Zdefiniowałem User
klasę, która (ostatecznie) dziedziczy models.Model
. Chcę uzyskać listę wszystkich pól zdefiniowanych dla tego modelu. Na przykład phone_number = CharField(max_length=20)
. Zasadniczo chcę odzyskać wszystko, co dziedziczy po Field
klasie.
Myślałem, że będę w stanie je odzyskać, korzystając z inspect.getmembers(model)
, ale lista, którą zwraca, nie zawiera żadnego z tych pól. Wygląda na to, że Django już opanował klasę i dodał wszystkie jej magiczne atrybuty i usunął to, co faktycznie zdefiniowano. Więc ... jak mogę zdobyć te pola? Prawdopodobnie mają funkcję wyszukiwania ich do własnych celów wewnętrznych?
django
django-models
mpen
źródło
źródło
Odpowiedzi:
Ponieważ większość odpowiedzi jest nieaktualna, spróbuję zaktualizować Cię w postach Django 2.2 Here - Twoja aplikacja (posty, blog, sklep itp.)
1) Z linku do modelu : https://docs.djangoproject.com/en/2.2/ref/models/meta/
Uwaga:
Uzyska także pewne relacje, które np. nie można wyświetlić w widoku.
Jak w moim przypadku:
i
2) Z instancji
3) Z modelu nadrzędnego
Załóżmy, że mamy Post jako model nadrzędny i chcesz zobaczyć wszystkie pola na liście, a pola nadrzędne mają być tylko do odczytu w trybie edycji.
źródło
clean_field_names = [str(h).split('.')[2].replace("_", " ").title() for h in all_fields]
all_fields = bp._meta.fields
Django w wersji 1.8 i nowszych:
Powinieneś użyć
get_fields()
:get_all_field_names()
Sposób jest nieaktualne począwszy od Django 1,8 i zostaną usunięte w 1,10 .Strona dokumentacji, do której prowadzi powyższy link, zapewnia w pełni kompatybilną wstecz implementację
get_all_field_names()
, ale w większości przypadków poprzedni przykład powinien działać dobrze.Wersje Django przed 1.8:
To powinno wystarczyć.
To wymaga rzeczywistej instancji modelu. Jeśli masz tylko podklasę
django.db.models.Model
, powinieneś zadzwonićmyproject.myapp.models.MyModel._meta.get_all_field_names()
źródło
model._meta.fields
, a ich nazwy można odzyskaćfield.name
. Mam tylko nadzieję, że jest to najbardziej stabilny sposób na odzyskanie tych informacji :)django.db.models.Model
._meta
atrybutu jest jedynym sposobem ... Dodatkowo sprawdź_meta.many_to_many
pola ManyToMany!get_all_related_fields()
Metodzie opisanej w niniejszym dokumencie została zaniechana na 1,8 . Od teraz to jestget_fields()
.źródło
Uważam, że dodanie tego do modeli django jest bardzo pomocne:
Pozwala to na:
źródło
django.db.models.fields.related.RelatedObjectDoesNotExist: CustomModel has no custom_attribute.
ForeignKey
działa dobrze dla mnie. Chociaż ciche wychwytywanie wszystkich wyjątków jest anty-wzorem. Znacznie lepiej złapaćAttributeError
, a przynajmniej odnotować, że jakiś wyjątek został po cichu połknięty.self._meta.get_all_field_names()
został amortyzowany i usunięty. Możesz użyć czegoś takiego,for field in self._meta.get_fields()
a potemyield (field.name, field.value_from_object(self))
To załatwia sprawę. Testuję to tylko w Django 1.7.
Model._meta.local_fields
nie zawiera pól wiele do wielu. Powinieneś je zdobyćModel._meta.local_many_to_many
.źródło
Nie jest jasne, czy masz instancję klasy, czy samą klasę i próbujesz pobrać pola, ale tak czy inaczej, rozważ następujący kod
Korzystanie z instancji
Korzystanie z klasy
źródło
To zadziałało dla mnie w
django==1.11.8
źródło
MyModel._meta.get_all_field_names()
zostało wycofane kilka wersji z powrotem i usunięte w Django 1.10.Oto sugestia zgodna wstecz z dokumentów :
źródło
Żeby dodać, używam obiektu własnego, to zadziałało dla mnie:
źródło
Przynajmniej w przypadku Django 1.9.9 - wersji, której obecnie używam - zauważ, że
.get_fields()
tak naprawdę „traktuje” każdy obcy model jako pole, co może być problematyczne. Powiedz, że masz:Wynika, że
natomiast, jak pokazuje @Rockallite
źródło
Więc zanim znalazłem ten post, udało mi się go znaleźć.
Działa tak samo jak
Nie jestem pewien, jaka jest różnica w wynikach, jeśli taka istnieje. Uruchomiłem tę pętlę i dostałem to samo wyjście.
źródło
Dlaczego nie skorzystać z tego:
Przykładowe dane wyjściowe:
źródło