29 Stimmen

Django Vorlagen: Schleife durch und drucken Sie alle verfügbaren Eigenschaften eines Objekts?

Ich habe ein Datenbankobjekt namens manor_stats mit etwa 30 Feldern. Bei den meisten Zeilen werden die meisten dieser Felder Null sein.

In meiner Vorlage möchte ich eine Schleife durch alle Felder in der Zeile, und drucken Sie Informationen für nur die Felder, die nicht null sind.

Es gibt zum Beispiel ein Feld namens "Name": Ich möchte Folgendes ausdrucken <li>Name: {{ manor_stats.name }}</li> in der Vorlage NUR für diejenigen Objekte, bei denen das Feld nicht Null ist. Idealerweise würde ich gerne "Name: " von irgendwoher automatisch zu, anstatt es anzugeben.

Ich weiß, ich könnte {% if manor_stats.name %} um zu prüfen, ob jedes Feld null ist, aber ich möchte das nicht 30 Mal für alle Felder tun.

Hier ist, was ich in views.py habe:

manor_stats = Manors.objects.get(idx=id)
return render_to_response('place.html', { 'place' : place, 'manor_stats' : manor_stats }, context_instance = RequestContext(request))

Und dann möchte ich in place.html etwas haben, das ungefähr so funktioniert (Pseudocode, mit ??? für die Teile, von denen ich nicht weiß, wie sie funktionieren):

{% if manor_stats %} 
<ul>
 {% for manor_stats.property??? in manor_stats %} 
  {% if manor_stats.property %} 
   <li>{{ manor_stats.property.field_name??? }} {{ manor_stats.property.value??? }}</li>
  {% endif %}
 {% endfor %
{% endif %}

Ich hoffe, das macht Sinn...

64voto

buckley Punkte 1970

Sie könnten eine Methode zu Ihrem Manors-Modell hinzufügen, die alle Feldwerte zurückgibt. Von dort aus können Sie einfach eine Schleife über diese Werte in Ihrer Vorlage laufen lassen, um zu sehen, ob der Wert nicht null ist.

-- models.py

class Manors(models.Model)
  #field declarations

  def get_fields(self):
    return [(field.name, field.value_to_string(self)) for field in Manors._meta.fields]

-- manor_detail.html

{% for name, value in manor_stats.get_fields %}
  {% if value %}
    {{ name }} => {{ value }}
  {% endif %}
{% endfor %}

8voto

Rob Simpson Punkte 326

Der folgende Ansatz erfordert nur die Definition eines einzigen benutzerdefinierten Vorlagenfilters ( siehe die Dokumente ) - das ist DRY'er als in jedes Modell, für das Sie diese Funktionalität benötigen, eine Methode zu schreiben oder zu kopieren.

-- my_app/templatetags/my_tags.py

from django import template

register = template.Library()

@register.filter
def get_fields(obj):
    return [(field.name, field.value_to_string(obj)) for field in obj._meta.fields]

Sie müssen Ihren Server neu starten, damit die neuen Tags registriert und in Ihren Vorlagen verfügbar werden.

-- meine_anwendung/vorlagen/meine_anwendung/meine_vorlage.html

{% load my_tags %}
<ul>
{% for key, val in object|get_fields %}
  <li>{{ key }}: {{ val }}</li>
{% endfor %}
</ul>

Getestet in Django 1.11.

NB: Da es sich bei ._meta um ein privates Attribut handelt, kann sich seine Funktionalität in Zukunft durchaus ändern.

Vielen Dank an die anderen Antworten in diesem Beitrag, die mir den größten Teil des Weges abgenommen haben, insbesondere an W. Perrin.

0voto

W.Perrin Punkte 3042

Verwenden Sie Model._meta.get_fields() im Python-Code.

>>> from django.contrib.auth.models import User
>>> User._meta.get_fields()
(<ManyToOneRel: admin.logentry>,
 <django.db.models.fields.AutoField: id>,
 <django.db.models.fields.CharField: password>,
 <django.db.models.fields.DateTimeField: last_login>,
 <django.db.models.fields.BooleanField: is_superuser>,
....

In der Vorlage können wir einen Filter definieren, um alle Felder abzurufen.

my_app

  templatetags
      my_filters.py

from django import template
register = template.Library()

@register.filter
def get_fields(obj):
    return obj._meta.get_fields()

{% for k,v in obj|get_fields %}
    <td> {{k}} </td>
{% endfor %}

Siehe diesen Link: https://docs.djangoproject.com/en/2.0/ref/models/meta/#retrieving-all-field-instances-of-a-model

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X