Ich versuche, eine grundlegende Vorlage zu erstellen, um die Feldwerte der ausgewählten Instanz zusammen mit ihren Namen anzuzeigen. Stellen Sie sich das nur als Standardausgabe der Werte dieser Instanz im Tabellenformat vor, mit dem Feldnamen (Verbose_name speziell, falls im Feld angegeben) in der ersten Spalte und dem Wert dieses Felds in der zweiten Spalte.
Angenommen, wir haben die folgende Modelldefinition:
class Client(Model):
name = CharField(max_length=150)
email = EmailField(max_length=100, verbose_name="E-mail")
Ich möchte, dass es wie folgt in der Vorlage ausgegeben wird (nehmen Sie eine Instanz mit den angegebenen Werten an):
Field Name Field Value
---------- -----------
Name Wayne Koorts
E-mail waynes@email.com
Ich versuche zu erreichen, dass eine Instanz des Modells an eine Vorlage übergeben und in der Vorlage dynamisch durchlaufen werden kann.
<table>
{% for field in fields %}
<tr>
<td>{{ field.name }}</td>
<td>{{ field.value }}</td>
</tr>
{% endfor %}
</table>
Gibt es eine nette, von Django genehmigte Möglichkeit, dies zu tun? Es scheint eine sehr häufige Aufgabe zu sein, und ich werde es für dieses spezielle Projekt oft tun müssen.
quelle
Sie können den To -Python- Queryset-Serializer von Django verwenden .
Fügen Sie einfach den folgenden Code in Ihre Ansicht ein:
Und dann in der Vorlage:
Sein großer Vorteil ist die Tatsache, dass es Beziehungsfelder behandelt.
Versuchen Sie für die Teilmenge der Felder:
quelle
verbose_name
des Feldes?Endlich eine gute Lösung dafür auf der Entwickler-Mailingliste gefunden :
In der Ansicht hinzufügen:
in der Vorlage hinzufügen:
quelle
FooForm
ist einModelForm
, wäre es nicht einfacher, einfach zu tun :FooForm(instance=Foo.objects.get(pk=object_id)))
?Angesichts der Veröffentlichung von Django 1.8 (und der Formalisierung der Model _meta-API) dachte ich, ich würde dies mit einer neueren Antwort aktualisieren.
Unter der Annahme des gleichen Modells:
Django <= 1,7
Django 1.8+ (formalisierte Model _meta API)
Im folgenden Beispiel verwenden wir die formalisierte Methode zum Abrufen aller Feldinstanzen eines Modells über
Client._meta.get_fields()
:Eigentlich wurde ich darauf aufmerksam gemacht, dass das oben Genannte für das, was benötigt wurde, etwas über Bord geht (da stimme ich zu!). Einfach ist besser als komplex. Ich lasse das oben genannte als Referenz. Für die Anzeige in der Vorlage ist es jedoch am besten, eine ModelForm zu verwenden und eine Instanz zu übergeben. Sie können über das Formular iterieren (entspricht dem Iterieren über jedes Feld des Formulars) und das Attribut label verwenden, um den ausführlichen Namen des Modellfelds abzurufen, und die Wertmethode verwenden, um den Wert abzurufen:
Jetzt rendern wir die Felder in der Vorlage:
quelle
Hier ist ein anderer Ansatz unter Verwendung einer Modellmethode. Diese Version löst Auswahllisten- / Auswahlfelder auf, überspringt leere Felder und ermöglicht das Ausschließen bestimmter Felder.
Dann in Ihrer Vorlage:
quelle
except User.DoesNotExist:
?_meta.get_fields()
bis ich es testen kann.Ok, ich weiß, dass dies etwas spät ist, aber da ich darauf gestoßen bin, bevor ich die richtige Antwort gefunden habe, könnte es auch jemand anderes tun.
Aus den Django-Dokumenten :
quelle
ordering = ['-id']
inclass Meta:
Ihrer Aufgabe inmodels.py
. 2. dann benutzeBlog.objects.filter(name__startswith='Beatles').values()[0]
model
Objekt haben, rufen Sie die Datenbank erneut auf, um die Felder abzurufen. Wie kann man das umgehen?Sie können die
values()
Methode a verwendenqueryset
, die ein Wörterbuch zurückgibt. Ferner akzeptiert diese Methode eine Liste von Feldern, für die eine Teilmenge erstellt werden soll. Dievalues()
Methode funktioniert nicht mitget()
, daher müssen Sie verwendenfilter()
(siehe QuerySet-API ).In
view
...In
detail.html
...Für eine Sammlung von Instanzen, die vom Filter zurückgegeben werden:
In detail.html ...
quelle
table
, also brauche ich jedeskey
s in ath
. Wie mache ich das ohne Schleifen? Nehmen Sie einfach eine Objektinstanz und durchlaufen Sie sie fürkey
s? Zur Zeit bin ich vorbei separatmodel_to_dict(Model())
für dasth
, aber ich denke , es ist eine unnötige Objektinstanziierung.get_object
die Detailansicht (aufgrund der Einschränkung des Inline-Codes für Kommentare verstümmelt und nicht der Meinung, dass dies für die eigene Antwort ausreicht, wenn man bedenkt, wie gesättigt dieser Thread ist):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
dieser Liste hinzufügen , ohne die Zeilen zu duplizieren?Ich habe https://stackoverflow.com/a/3431104/2022534 verwendet, aber Djangos model_to_dict () durch dieses ersetzt, um ForeignKey verarbeiten zu können:
Bitte beachten Sie, dass ich es ein wenig vereinfacht habe, indem ich die Teile des Originals entfernt habe, die ich nicht brauchte. Vielleicht möchten Sie diese zurücklegen.
quelle
Sie können ein Formular die Arbeit für Sie erledigen lassen.
Dann in der Vorlage:
quelle
DetailView
) funktioniert gut für mich. Möglicherweise möchten Sie jedochfield.label
anstelle von verwendenfield.name
.Es sollte wirklich einen eingebauten Weg geben, dies zu tun. Ich habe dieses Dienstprogramm geschrieben
build_pretty_data_view
, das ein Modellobjekt und eine Formularinstanz (ein auf Ihrem Modell basierendes Formular) verwendet und a zurückgibtSortedDict
.Zu den Vorteilen dieser Lösung gehören:
SortedDict
.exclude()
Liste von Feldnamen verwendet, um bestimmte Felder auszuschließen.Meta: exclude()
, Sie aber dennoch die Werte zurückgeben möchten, fügen Sie diese Felder der optionalenappend()
Liste hinzu.Um diese Lösung zu verwenden, fügen Sie diese Datei / Funktion zuerst irgendwo hinzu und importieren Sie sie dann in Ihre
views.py
.utils.py
Also
views.py
könnten Sie jetzt in Ihrem so etwas tunJetzt können Sie in Ihrer
my-template.html
Vorlage die Daten wie folgt durchlaufen ...Viel Glück. Hoffe das hilft jemandem!
quelle
Unten ist meine, inspiriert von Shackers
get_all_fields
. Es wird ein Diktat einer Modellinstanz abgerufen. Wenn ein Begegnungsbeziehungsfeld vorhanden ist, wird dem Feldwert ein Diktat rekursiv zugewiesen.Diese Funktion wird hauptsächlich verwendet, um eine Modellinstanz in JSON-Daten zu sichern:
quelle
Anstatt jedes Modell zu bearbeiten, würde ich empfehlen, ein Vorlagen-Tag zu schreiben, das alle Felder eines bestimmten Modells zurückgibt.
Jedes Objekt hat eine Liste von Feldern
._meta.fields
.Jedes Feldobjekt verfügt über ein Attribut
name
, das seinen Namen zurückgibtvalue_to_string()
, und die mit Ihrem Modell gelieferte Methodeobject
gibt seinen Wert zurück.Der Rest ist so einfach wie in der Django-Dokumentation angegeben .
Hier ist mein Beispiel, wie dieses Templatetag aussehen könnte:
quelle
Ja, es ist nicht schön, du musst deinen eigenen Wrapper machen. Schauen Sie sich die integrierte Datenbank- App an, die alle Funktionen bietet , die Sie wirklich benötigen.
quelle
Dies kann als Hack angesehen werden, aber ich habe dies getan, bevor ich modelform_factory verwendet habe, um eine Modellinstanz in ein Formular umzuwandeln.
Die Form-Klasse enthält viel mehr Informationen, die sehr einfach zu durchlaufen sind, und sie erfüllt denselben Zweck auf Kosten eines etwas höheren Overheads. Wenn Ihre eingestellten Größen relativ klein sind, sind die Auswirkungen auf die Leistung meiner Meinung nach vernachlässigbar.
Der einzige Vorteil neben der Bequemlichkeit besteht natürlich darin, dass Sie die Tabelle zu einem späteren Zeitpunkt problemlos in ein bearbeitbares Datagrid verwandeln können.
quelle
Ich habe die folgende Methode entwickelt, die für mich funktioniert, da dem Modell in jedem Fall eine ModelForm zugeordnet ist.
Hier ist ein Auszug aus der Vorlage, die ich für diese bestimmte Ansicht verwende:
Das Schöne an dieser Methode ist, dass ich vorlagenweise die Reihenfolge auswählen kann, in der die Feldbezeichnungen angezeigt werden sollen, wobei das an GetModelData übergebene Tupel verwendet und die Feldnamen angegeben werden. Dadurch kann ich auch bestimmte Felder (z. B. einen Benutzer-Fremdschlüssel) ausschließen, da nur die über das Tupel übergebenen Feldnamen in das endgültige Wörterbuch integriert sind.
Ich werde das nicht als Antwort akzeptieren, weil ich sicher bin, dass sich jemand etwas mehr "Djangonic" einfallen lassen kann :-)
Update: Ich wähle dies als endgültige Antwort, weil es die einfachste unter den gegebenen ist, die das tut, was ich brauche. Vielen Dank an alle, die Antworten beigesteuert haben.
quelle
Django 1.7 Lösung für mich:
Dort sind die Variablen genau auf die Frage abgestimmt, aber Sie sollten dieses Beispiel auf jeden Fall analysieren können
Der Schlüssel hier ist,
.__dict__
die Modellansichten soziemlich zu verwenden .
Vorlage :
In der Vorlage habe ich einen Filter verwendet, um auf das Feld in der
Datei dict filter.py zuzugreifen :
quelle
Ich benutze dies, https://github.com/miracle2k/django-tables .
quelle
Dieser Ansatz zeigt, wie eine Klasse wie ModelForm von django und ein Vorlagen-Tag wie {{form.as_table}} verwendet werden, wobei jedoch die gesamte Tabelle wie eine Datenausgabe und nicht wie ein Formular aussieht.
Der erste Schritt bestand darin, das TextInput-Widget von django in Unterklassen zu unterteilen:
Dann habe ich die ModelForm von django untergeordnet, um die Standard-Widgets gegen schreibgeschützte Versionen auszutauschen:
Das waren die einzigen Widgets, die ich brauchte. Es sollte jedoch nicht schwierig sein, diese Idee auf andere Widgets auszudehnen.
quelle
Nur eine Bearbeitung von @wonder
Lassen Sie Django alle anderen Felder außer den zugehörigen Feldern behandeln. Ich finde das stabiler
quelle
Schauen Sie sich die Anwendung django-etc an . Es verfügt über ein
model_field_verbose_name
Vorlagen-Tag, mit dem der ausführliche Feldname aus den Vorlagen abgerufen werden kann : http://django-etc.rtfd.org/en/latest/models.html#model-field-template-tagsquelle
Ich habe so etwas gerade in der Shell getestet und scheint seinen Job zu machen:
Wenn Sie eine str () - Darstellung für Fremdobjekte wünschen, sollten Sie diese in ihrer str- Methode definieren. Daraus haben Sie ein Diktat von Werten für das Objekt. Dann können Sie eine Art Vorlage oder was auch immer rendern.
quelle
Django> = 2,0
Fügen Sie
get_fields()
Ihrem hinzumodels.py
:Dann nenne es wie
object.get_fields
auf deinemtemplate.html
:quelle
quelle