2009-02-01 6 views
10

Tout d'abord, je ne suis pas dans la programmation web. Je suis tombé sur django et j'ai lu un peu sur les modèles. Je suis intrigué par le code suivant (de djangoproject.com):Comment fonctionnent les champs du modèle 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)) 

par ma compréhension de python, prenom et last_name sont des variables de classe, non? Comment cela est-il utilisé dans le code (parce que j'imagine que le réglage Person.first_name ou Person.last_name affectera toutes les instances de Person)? Pourquoi est-ce utilisé de cette façon?

Répondre

4

Oui, prenom et last_name sont variables de classe. Ils définissent les champs qui seront créés dans une table de base de données. Il y a une table Person qui a des colonnes first_name et last_name, il est donc logique qu'elles soient au niveau de la classe à ce stade.

Pour en savoir plus sur les modèles, voir: http://docs.djangoproject.com/en/dev/topics/db/models/

En ce qui concerne l'accès aux instances d'une personne dans le code, vous font généralement ce via ORM de Django, et à ce moment, ils se comportent essentiellement comme variables d'instance.

Pour en savoir plus sur les instances de modèle, voir http://docs.djangoproject.com/en/dev/ref/models/instances/?from=olddocs

+0

Danke schon Andy! – Geo

+0

Certains bons liens ici, mais "à ce stade, ils se comportent essentiellement comme des variables d'instance" est un peu de main-ondulation qui n'est pas vraiment précis (ou du moins n'explique rien). –

+1

Assez juste ... Je vais tenir mes mains à celui-là. +1 sur votre réponse :) –

19

L'essence de votre question est « comment se fait ces variables de classe (que j'assigner des objets de champ à) deviennent soudainement des variables d'instance (que j'affecter des données à) en Django's ORM "? La réponse à cela est la magie de Python metaclasses.

A métaclasse vous permet de brancher et de modifier dans le processus de création d'une classe de python (pas la création d'une instance de cette classe, la création de la classe elle-même).

L'objet Modèle de Django (et donc aussi vos modèles, qui sont des sous-classes) a un ModelBase metaclass. Il regarde à travers tous les attributs de classe de votre modèle, et tous ceux qui sont des instances d'une sous-classe Field, il se déplace dans une liste de champs. Cette liste est affectée en tant qu'attribut de l'objet _meta, qui est un attribut de classe du modèle. Ainsi, vous pouvez toujours accéder aux objets Champ réels via MyModel._meta.fields ou MyModel._meta.get_field('field_name').

La méthode Model.__init__ peut ensuite utiliser la liste _meta.fields pour déterminer quels attributs d'instance doivent être initialisés lors de la création d'une instance de modèle.

Ne pas avoir peur de plonger dans le code source Django; C'est une excellente source d'éducation!

+0

+1: C'est cool vaudou. Ce n'est pas quelque chose que vous devriez comprendre profondément. Mais vous avez besoin de voir qu'il plie les règles de variable d'instance évidente, en ajoutant une autre couche à la façon dont les objets sont créés. –

+0

Belle explication. – Harold

+0

Cool. Je me demande simplement: l'attribut '_meta' fait-il partie de l'API du modèle officiel? – pcv

0

Pas une vraie réponse, mais pour l'enrichissement:

Person.first_name 

ne fonctionnera pas

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

fonctionnera. donc une instance d'objet de personne a un prénom et un nom, mais un contexte statique Personne ne le fait.

A noter également: Django a Model Les gestionnaires qui sont permettent « personne » pour effectuer des opérations de QuerySet statiques. (https://docs.djangoproject.com/en/dev/topics/db/managers/#managers).

donc par exemple

peoples = Person.objects.all() 
Questions connexes