1

I would like to display something like this in my template:

Name: John

Age: 18

City: New York

Using, for example, this code:

views.py

def person_details(request,pk):
   person = get_object_or_404(Person, id=pk)
   return render(request, 'template.html', {'person': person, 'person_fields': person._meta.get_fields()})

template.html

{% for field in person_fields %}        
     <div class="col-4 form-group">            
         <p><strong>{{ field.verbose_name }}:</strong> {{ person[ field.name ]  }}</p>             
     </div>
{% endfor %}

Is this possible in python? I ask because I have a model that have about 20 fields and hard coding the fields in template would be a little hard.

petezurich
  • 9,280
  • 9
  • 43
  • 57
WitnessTruth
  • 539
  • 2
  • 9
  • 27

2 Answers2

2

You can use Django's to-python queryset serializer.

Just put the following code in your view:

from django.core import serializers
data = serializers.serialize( "python", SomeModel.objects.all() )

And then in the template:

{% for instance in data %}
    {% for field, value in instance.fields.items %}
        {{ field }}: {{ value }}
    {% endfor %}
{% endfor %}

Its great advantage is the fact that it handles relation fields.

For the subset of fields try:

data = serializers.serialize('python', SomeModel.objects.all(), fields=('name','size'))
Exprator
  • 26,992
  • 6
  • 47
  • 59
  • Worked for me, thank you so much! I didn't know about this serializers. they will make a lot of other situations in my coding easier. T – WitnessTruth Nov 05 '18 at 12:55
  • One more question. It's there a way to show the verbose_name of the field? I tried putting {{ field.verbose_name }} but didn't work. – WitnessTruth Nov 05 '18 at 12:58
  • 1
    no you cannot do it like that to display it in template. post it as a question – Exprator Nov 05 '18 at 13:00
0

Django templates are deliberately restricted, such that writing business logic is hard (or close to impossible). One typically performs such logic in the model or view layer.

def person_details(request, pk):
    person = get_object_or_404(Person, id=pk)
    person_data = {
       f.verbose_name: getattr(person, f.name, None)
       for f in person._meta.get_fields()
    }
    return render(request, 'template.html', {'person': person, 'person_data': person_data })

and then render it with:

{% for ky, val in person_data.items %}
     <div class="col-4 form-group">            
         <p><strong>{{ ky }}:</strong> {{ val }}</p>             
     </div>
{% endfor %}

It is however advisable not to do this serialization yourself, but to use other serialization methods like these listed in this answer.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555