2009-02-01 18 views
10

Prima di tutto, non sono interessato alla programmazione web. Mi sono imbattuto in django e ho letto un po 'di modelle. Sono stato incuriosito dal seguente codice (da djangoproject.com):Come funzionano i campi del modello Django?


class Person(models.Model): 
    first_name = models.CharField(max_length=50) 
    last_name = models.CharField(max_length=50) 

    def __str__(self): 
     # Note use of django.utils.encoding.smart_str() here because 
     # first_name and last_name will be unicode strings. 
     return smart_str('%s %s' % (self.first_name, self.last_name)) 

Con la mia comprensione di pitone, first_name e last_name sono variabili di classe, giusto? Com'è utilizzato nel codice (perché suppongo che l'impostazione di Person.first_name o Person.last_name riguarderà tutte le istanze di Person)? Perché è usato in questo modo?

risposta

4

Sì, first_name e last_name sono variabili di classe. Definiscono i campi che verranno creati in una tabella di database. C'è una tabella Person che ha colonne first_name e last_name, quindi ha senso che siano a livello di classe a questo punto.

Per ulteriori informazioni su modelli, vedere: http://docs.djangoproject.com/en/dev/topics/db/models/

quando si tratta di accedere istanze di una persona in codice è in genere facendo questo tramite ORM di Django, ed a questo punto che essenzialmente si comportano come variabili di istanza.

Per ulteriori informazioni su casi modello, vedi: http://docs.djangoproject.com/en/dev/ref/models/instances/?from=olddocs

+0

Danke schon Andy! – Geo

+0

Alcuni link validi qui, ma "a questo punto si comportano essenzialmente come variabili di istanza" è un po 'di mano che non è veramente accurato (o almeno non spiega nulla). –

+1

Abbastanza giusto ... terrò le mie mani su quello. +1 sulla tua risposta. :) –

19

L'essenza della tua domanda è "come mai queste variabili di classe (che assegno oggetti Field a) diventano improvvisamente variabili di istanza (che assegno dati a) in Django's ORM "? La risposta è la magia di Python metaclasses.

Una metaclasse consente di agganciare e modificare il processo di creazione di una classe Python (non la creazione di un'istanza di quella classe, la creazione della classe stessa).

Oggetto modello di Django (e quindi anche i tuoi modelli, che sono sottoclassi) ha un ModelBase metaclass. Analizza tutti gli attributi di classe del tuo modello e qualsiasi istanza di una sottoclasse Field che si sposta in un elenco di campi. Tale elenco viene assegnato come attributo dell'oggetto _meta, che è un attributo di classe del modello. In questo modo è sempre possibile raggiungere gli oggetti Field attuali tramite MyModel._meta.fields o MyModel._meta.get_field('field_name').

Il metodo Model.__init__ è quindi in grado di utilizzare l'elenco _meta.fields per determinare quali attributi di istanza devono essere inizializzati quando viene creata un'istanza di modello.

Non aver paura di immergerti nel codice sorgente di Django; è una grande fonte di educazione!

+0

+1: Questo è un bel voodoo. Non è qualcosa che dovresti capire profondamente. Ma hai bisogno di vedere che piega le ovvie regole delle variabili di istanza, aggiungendo un altro livello al modo in cui gli oggetti vengono creati. –

+0

Bella spiegazione. – Harold

+0

Fresco. Mi chiedo solo: l'attributo '_meta' è una parte dell'API del modello ufficiale? – pcv

0

Non una vera risposta, ma per l'arricchimento:

Person.first_name 

non funzionerà

p = Person.objects.get(pk=x) 
p.first_name 

funzionerà. quindi un'istanza di oggetto di una persona ha un nome e un cognome, ma il contesto statico Person non lo fa.

Nota: Django dispone di Manager modello che consentono a "Persona" di eseguire operazioni di queryset statiche. (Https://docs.djangoproject.com/en/dev/topics/db/managers/#managers).

così per esempio

peoples = Person.objects.all() 
Problemi correlati