Próbuję utworzyć podstawowy szablon do wyświetlania wartości pól wybranej instancji wraz z ich nazwami. Pomyśl o tym jak o standardowym wyjściu wartości tego wystąpienia w formacie tabeli, z nazwą pola (pełna nazwa, jeśli jest określona w polu) w pierwszej kolumnie i wartością tego pola w drugiej kolumnie.
Załóżmy na przykład, że mamy następującą definicję modelu:
class Client(Model):
name = CharField(max_length=150)
email = EmailField(max_length=100, verbose_name="E-mail")
Chciałbym, aby był wyprowadzany w szablonie w taki sposób (załóżmy instancję o podanych wartościach):
Field Name Field Value
---------- -----------
Name Wayne Koorts
E-mail waynes@email.com
Staram się przekazać instancję modelu do szablonu i dynamicznie iterować go w szablonie, mniej więcej tak:
<table>
{% for field in fields %}
<tr>
<td>{{ field.name }}</td>
<td>{{ field.value }}</td>
</tr>
{% endfor %}
</table>
Czy istnieje ciekawy sposób na „zatwierdzenie przez Django”? Wydaje się, że jest to bardzo częste zadanie i będę musiał to robić często w przypadku tego konkretnego projektu.
źródło
Możesz użyć serializatora zestawu zapytań Django do zapytania.
Wystarczy umieścić następujący kod w swoim widoku:
A następnie w szablonie:
Jego wielką zaletą jest to, że obsługuje pola relacji.
Dla podzbioru pól spróbuj:
źródło
verbose_name
przekazanie pola?Wreszcie znalazłem dobre rozwiązanie tego problemu na liście dyskusyjnej deweloperów :
W widoku dodaj:
w szablonie dodaj:
źródło
FooForm
jest toModelForm
, czy nie łatwiej byłoby po prostu zrobićFooForm(instance=Foo.objects.get(pk=object_id)))
:?W świetle wydania Django 1.8 (i sformalizowania API Model _meta , pomyślałem, że zaktualizuję to, dodając nowszą odpowiedź.
Zakładając ten sam model:
Django <= 1,7
Django 1.8+ (sformalizowany model _meta API)
W poniższym przykładzie wykorzystamy sformalizowaną metodę pobierania wszystkich instancji pola modelu za pomocą
Client._meta.get_fields()
:W rzeczywistości zwrócono mi uwagę, że powyższe jest nieco przesadzone, jeśli chodzi o to, co było potrzebne (zgadzam się!). Prosty jest lepszy niż złożony. Zostawiam powyższe w celach informacyjnych. Jednak do wyświetlenia w szablonie najlepszą metodą byłoby użycie ModelForm i przekazanie w instancji. Możesz iterować po formularzu (odpowiednik iteracji po każdym z pól formularza) i użyć atrybutu label, aby pobrać pełną nazwę modelu pola, i użyć metody value, aby pobrać wartość:
Teraz renderujemy pola w szablonie:
źródło
Oto inne podejście przy użyciu metody modelowej. Ta wersja rozwiązuje pola listy wyboru / wyboru, pomija puste pola i pozwala wykluczyć określone pola.
Następnie w swoim szablonie:
źródło
except User.DoesNotExist:
?_meta.get_fields()
aż będę mógł to przetestować.Ok, wiem, że to trochę za późno, ale ponieważ natknąłem się na to, zanim znalazłem poprawną odpowiedź, może ktoś inny.
Z dokumentacji django :
źródło
ordering = ['-id']
wclass Meta:
swoim obiekciemodels.py
. 2. następnie użyjBlog.objects.filter(name__startswith='Beatles').values()[0]
model
obiekt, trafiłbyś ponownie do bazy danych tylko po to, aby uzyskać pola. Jakiś sposób na to?Możesz użyć
values()
metody aqueryset
, która zwraca słownik. Ponadto ta metoda akceptuje listę pól do podzbioru. Tavalues()
metoda nie będzie działaćget()
, dlatego należy jej użyćfilter()
(patrz interfejs API QuerySet ).W
view
...W
detail.html
...W przypadku zbioru instancji zwróconych przez filtr:
In detail.html ...
źródło
table
, więc potrzebuję każdego z nichkey
wth
. Jak to zrobić bez pętli? Po prostu weź dowolną instancję obiektu i powtórz ją przezkey
s? Obecnie osobno przechodzęmodel_to_dict(Model())
doth
, ale myślę, że jest to niepotrzebna instancja obiektu.get_object
widok szczegółów (zniekształcony ze względu na ograniczenia kodu w komentarzach i nie wydaje mi się, że to wystarczy do własnej odpowiedzi, biorąc pod uwagę nasycenie tego wątku):def get_object(self, **kwargs): obj = super().get_object(**kwargs) obj = obj.__class__.objects.filter(pk=obj.pk).values()[0] return obj
obj.get_absolute_url
do tej listy bez powielania wierszy?Użyłem https://stackoverflow.com/a/3431104/2022534, ale zastąpiłem model_to_dict () Django tym, aby móc obsługiwać ForeignKey:
Pamiętaj, że nieco uprościłem to, usuwając części oryginału, których nie potrzebowałem. Możesz je odłożyć.
źródło
Możesz mieć formularz, który wykona pracę za Ciebie.
Następnie w szablonie:
źródło
DetailView
) działa dla mnie dobrze. Możesz jednak użyćfield.label
zamiastfield.name
.Naprawdę powinien istnieć wbudowany sposób, aby to zrobić. Napisałem to narzędzie,
build_pretty_data_view
które pobiera obiekt modelu i instancję formularza (formularz oparty na modelu) i zwraca aSortedDict
.Korzyści z tego rozwiązania obejmują:
SortedDict
.exclude()
listę nazw pól, aby wykluczyć niektóre pola.Meta: exclude()
, ale nadal chcesz zwrócić wartości, dodaj te pola do opcjonalnejappend()
listy.Aby skorzystać z tego rozwiązania, najpierw dodaj gdzieś ten plik / funkcję, a następnie zaimportuj go do swojego
views.py
.utils.py
Więc teraz
views.py
możesz zrobić coś takiegoTeraz w
my-template.html
szablonie możesz iterować dane w ten sposób ...Powodzenia. Mam nadzieję, że to komuś pomoże!
źródło
Poniżej jest moja, zainspirowana shackerem
get_all_fields
. Otrzymuje dykt jednej instancji modelu, jeśli napotka pole relacji, to rekursywnie przypisz wartość pola dyktowi.Ta funkcja jest używana głównie do zrzutu instancji modelu do danych JSON:
źródło
Zamiast edytować każdy model polecam napisanie jednego znacznika szablonu, który zwróci wszystkie podane pola dowolnego modelu .
Każdy obiekt ma listę pól
._meta.fields
.Każdy obiekt pola ma atrybut
name
, który zwróci jego nazwę, a metodavalue_to_string()
dostarczona z modelemobject
zwróci jego wartość.Reszta jest tak prosta, jak napisano w dokumentacji Django .
Oto mój przykład, jak może wyglądać ten szablon:
źródło
Tak, to nie jest ładne, musisz zrobić własne opakowanie. Spójrz na wbudowane databrowse aplikacji, która ma wszystkie funkcje potrzebne naprawdę.
źródło
Można to uznać za włamanie, ale zrobiłem to, zanim użyłem modelform_factory do przekształcenia instancji modelu w formę.
Klasa Form zawiera o wiele więcej informacji, które są bardzo łatwe do powtórzenia i będzie służyć temu samemu celowi kosztem nieco większego obciążenia. Jeśli twoje ustawione rozmiary są stosunkowo małe, myślę, że wpływ na wydajność byłby znikomy.
Jedną z zalet oprócz wygody jest oczywiście to, że możesz łatwo zmienić tabelę w edytowalny datagrid w późniejszym terminie.
źródło
Wymyśliłem następującą metodę, która działa dla mnie, ponieważ w każdym przypadku model będzie miał związany z nim ModelForm.
Oto wyciąg z szablonu, którego używam do tego konkretnego widoku:
Zaletą tej metody jest to, że mogę wybrać na podstawie szablonu po kolejności, w jakiej chciałbym wyświetlić etykiety pól, używając krotki przekazanej do GetModelData i określając nazwy pól. Pozwala mi to również wykluczyć niektóre pola (np. Klucz obcy użytkownika), ponieważ tylko nazwy pól przekazywane przez krotkę są wbudowane w ostateczny słownik.
Nie przyjmuję tego jako odpowiedzi, ponieważ jestem pewien, że ktoś może wymyślić coś więcej „Djangonic” :-)
Aktualizacja: wybieram to jako ostateczną odpowiedź, ponieważ jest to najprostszy z tych, który robi to, czego potrzebuję. Dziękujemy wszystkim, którzy udzielili odpowiedzi.
źródło
Rozwiązanie Django 1.7 dla mnie:
Istnieją zmienne, które dokładnie odpowiadają pytaniu, ale zdecydowanie powinieneś być w stanie przeanalizować ten przykład
Kluczem jest tutaj użycie
.__dict__
modeluviews.py :
szablon :
w szablonie użyłem filtra, aby uzyskać dostęp do pola w
pliku dict filter.py :
źródło
Używam tego, https://github.com/miracle2k/django-tables .
źródło
To podejście pokazuje, jak używać klasy, takiej jak ModelForm django i znacznik szablonu, taki jak {{form.as_table}}, ale wszystkie tabele wyglądają jak dane wyjściowe, a nie formularz.
Pierwszym krokiem było podklasowanie widgetu TextInput django:
Następnie podklasowałem ModelForm django, aby zamienić domyślne widżety dla wersji tylko do odczytu:
To były jedyne widżety, których potrzebowałem. Jednak rozszerzenie tego pomysłu na inne widżety nie powinno być trudne.
źródło
Po prostu edycja @wonder
Pozwól Django obsłużyć wszystkie inne pola oprócz powiązanych pól. Czuję, że to jest bardziej stabilne
źródło
Spójrz na aplikację django-etc . Ma
model_field_verbose_name
tag szablonu, aby uzyskać pełną nazwę pola z szablonów: http://django-etc.rtfd.org/en/latest/models.html#model-field-template-tagsźródło
Właśnie przetestowałem coś takiego w powłoce i wydaje się, że wykonuje swoją pracę:
Zauważ, że jeśli chcesz reprezentacji str () dla obcych obiektów, powinieneś zdefiniować ją w ich metodzie str . Z tego masz dyktę wartości obiektu. Następnie możesz renderować szablon lub cokolwiek innego.
źródło
Django> = 2.0
Dodaj
get_fields()
domodels.py
:Następnie nazwij to tak jak
object.get_fields
na swoimtemplate.html
:źródło
źródło