2009-02-01 39 views
10

Przede wszystkim nie jestem programistą internetowym. Wpadłem na django i przeczytałem trochę o modelach. Byłem zaintrygowany przez następujący kod (od djangoproject.com):Jak działają pola modelu 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)) 

Według mojego rozumienia Python, first_name i last_name są zmienne klasy, prawda? Jak to jest używane w kodzie (ponieważ domyślam się, że ustawienie Person.first_name lub Person.last_name wpłynie na wszystkie instancje Person)? Dlaczego jest używany w ten sposób?

Odpowiedz

4

Tak, pierwsza nazwa i ostatnia nazwa są zmiennymi klasy. Określają pola, które zostaną utworzone w tabeli bazy danych. Istnieje tabela Person z kolumnami first_name i last_name, więc ma to sens, aby byli na poziomie klasy w tym momencie.

Więcej informacji na temat modeli, patrz: http://docs.djangoproject.com/en/dev/topics/db/models/

Jeśli chodzi o dostęp do wystąpień osoby w kodzie, zazwyczaj robi to za pośrednictwem ORM Django, iw tym momencie one zasadniczo zachowywać jako zmienne instancji.

Więcej informacji na temat modelu przypadkach, patrz: http://docs.djangoproject.com/en/dev/ref/models/instances/?from=olddocs

+0

Danke schon Andy! – Geo

+0

Niektóre dobre linki tutaj, ale "w tym momencie zachowują się zasadniczo jak zmienne instancji" to trochę machania ręką, która nie jest naprawdę dokładna (albo przynajmniej nie wyjaśnia niczego). –

+1

Wystarczająco uczciwe ... Podniosę ręce do tego. +1 na twoją odpowiedź. :) –

19

Istotą swoje pytanie brzmi „dlaczego te zmienne klasy (który przypisać obiekty polu Do) nagle stają się zmienne instancji (co przypisać dane TO) w ORM Django "? Odpowiedzią na to jest magia Pythona metaclasses.

Metaclass pozwala na hakowanie i modyfikowanie procesu tworzenia klasy Pythona (nie tworzenie instancji tej klasy, tworzenie samej klasy).

Obiekt modelu Django (a zatem również modele, które są podklasami) ma numer ModelBase metaclass. Przegląda wszystkie atrybuty klas modelu i wszystkie instancje podklasy Field, która przenosi do listy pól. Ta lista jest przypisana jako atrybut obiektu _meta, który jest atrybutem klasy modelu. Dzięki temu zawsze można uzyskać dostęp do rzeczywistych obiektów Field poprzez MyModel._meta.fields lub MyModel._meta.get_field('field_name').

Metoda jest następnie w stanie użyć listy _meta.fields, aby określić, które atrybuty instancji powinny zostać zainicjowane po utworzeniu instancji modelu.

Nie bój się zagłębiać w kod źródłowy Django; to wspaniałe źródło edukacji!

+0

+1: To jest fajne voodoo. To nie jest coś, co powinno się głęboko zrozumieć. Ale musisz zobaczyć, że wygina oczywiste reguły zmiennych instancji, dodając kolejną warstwę do sposobu, w jaki tworzone są obiekty. –

+0

Niezłe wyjaśnienie. – Harold

+0

Cool. Zastanawiam się tylko: czy atrybut '_meta' jest częścią oficjalnego API modelu? – pcv

0

Nie prawdziwą odpowiedź, ale dla wzbogacenia:

Person.first_name 

nie zadziała

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

zadziała. więc instancja obiektu osoby ma imię i nazwisko, ale kontekst statyczny Osoba nie.

Uwaga: Django ma menedżerów modeli, którzy umożliwiają "Person" wykonywanie operacji ze statycznym zapytaniem. (https://docs.djangoproject.com/en/dev/topics/db/managers/#managers).

tak na przykład

peoples = Person.objects.all() 
Powiązane problemy