Biorąc pod uwagę model Django, próbuję wymienić wszystkie jego pola. Widziałem kilka przykładów robienia tego przy użyciu atrybutu modelu _meta, ale czy podkreślenie przed meta nie wskazuje, że atrybut _meta jest atrybutem prywatnym i nie powinien być dostępny bezpośrednio? ... Bo na przykład układ _meta mógłby się zmienić w przyszłości i nie być stabilnym API?
Czy _meta jest wyjątkiem od tej reguły? Czy jest stabilny i gotowy do użycia, czy też dostęp do niego jest uważany za złą praktykę? A może istnieje funkcja lub inny sposób introspekcji pól modelu bez użycia atrybutu _meta? Poniżej znajduje się lista niektórych linków pokazujących, jak to zrobić za pomocą atrybutu _meta
Wszelkie porady są mile widziane.
Odpowiedzi:
_meta
jest prywatny, ale jest stosunkowo stabilny. Podejmowane są próby jego sformalizowania, udokumentowania i usunięcia podkreślenia, co może mieć miejsce przed 1.3 lub 1.4. Wyobrażam sobie, że zostanie podjęty wysiłek, aby zapewnić zgodność wsteczną, ponieważ i tak wiele osób go używało.Jeśli szczególnie martwisz się o kompatybilność, napisz funkcję, która pobiera model i zwraca pola. Oznacza to, że jeśli coś się zmieni w przyszłości, wystarczy zmienić tylko jedną funkcję.
Wierzę, że to zwróci listę
Field
obiektów. Aby uzyskać wartość każdego pola z instancji, użyjgetattr(instance, field.name)
.Aktualizacja: autorzy Django pracują nad interfejsem API, który ma zastąpić obiekt _Meta w ramach Google Summer of Code. Zobacz:
- https://groups.google.com/forum/#!topic/django-developers/hD4roZq0wyk
- https://code.djangoproject.com/wiki/new_meta_api
źródło
model._meta.many_to_many
!django/core/management/commands/loaddata.py
używa _meta do poruszania się po drzewie aplikacji, modeli i pól. Niezły wzór do naśladowania ... i można się założyć, że to „oficjalny sposób”._meta.virtual_fields
_meta
jest teraz formalnym, obsługiwanym interfejsem API (nowość w Django 1.8)Wiem, że ten post jest dość stary, ale chciałem tylko powiedzieć każdemu, kto szuka tego samego, że istnieje publiczny i oficjalny interfejs API, który to robi:
get_fields()
iget_field()
Stosowanie:
https://docs.djangoproject.com/en/1.8/ref/models/meta/
źródło
get_fields()
docs.djangoproject.com/en/1.10/ref/models/meta/…_meta
?Teraz jest specjalna metoda - get_fields ()
Akceptuje dwa parametry, których można użyć do kontrolowania zwracanych pól:
include_parents
Domyślnie prawda. Rekurencyjnie obejmuje pola zdefiniowane w klasach nadrzędnych. Jeśli ustawiona na False, get_fields () będzie szukać tylko pól zadeklarowanych bezpośrednio w bieżącym modelu. Pola z modeli, które bezpośrednio dziedziczą z modeli abstrakcyjnych lub klas proxy, są uważane za lokalne, a nie nadrzędne.
include_hidden
Domyślnie fałszywe. Jeśli ustawiona na True, get_fields () będzie zawierać pola używane do przywrócenia funkcjonalności innych pól. Obejmuje to również wszystkie pola, które mają powiązaną nazwę (np. ManyToManyField lub ForeignKey), które zaczynają się od „+”
źródło
get_fields()
zwraca a,tuple
a każdy element jestModel field
typem, którego nie można użyć bezpośrednio jako łańcucha. Więcfield.name
zwróci nazwę polamy_model_fields = [field.name for field in MyModel._meta.get_fields()]
Powyższy kod zwróci listę zawierającą nazwy wszystkich pól
Przykład
źródło
To jest coś, co robi sam Django podczas budowania formularza z modelu. Używa atrybutu _meta, ale jak zauważył Bernhard, używa zarówno _meta.fields, jak i _meta.many_to_many. Patrząc na django.forms.models.fields_for_model, możesz to zrobić w następujący sposób:
źródło
Pola modelu zawarte w _meta są wymienione w wielu lokalizacjach jako listy odpowiednich obiektów pól. Może być łatwiej pracować z nimi jako słownikiem, w którym kluczami są nazwy pól.
Moim zdaniem jest to najbardziej zbędny i wyrazisty sposób zbierania i porządkowania obiektów pola modelu:
(Zobacz ten przykład użycia w django.forms.models.fields_for_model.)
źródło
A co z tym?
źródło
many_to_many
ivirtual_fields
.Zgodnie z dokumentacją django 2.2 możesz użyć:
Aby uzyskać wszystkie pola:
Model._meta.get_fields()
Aby uzyskać indywidualne pole:
Model._meta.get_field('field name')
dawny.
Session._meta.get_field('expire_date')
źródło
Jeśli potrzebujesz tego dla swojej witryny administracyjnej , istnieje również
ModelAdmin.get_fields
metoda ( dokumentacja ), która zwracalist
nazwę polastrings
.Na przykład:
źródło
Innym sposobem jest dodanie funkcji do modelu, a gdy chcesz nadpisać datę, możesz wywołać funkcję.
źródło