Is there a way to iterate through all the fields in a Django database object and display them through a template HTML?

Viewed 1006

I have this HTML code for my template HTML file:

name : {{object.name}}
age : {{object.age}}
gender : {{object.gender}}

name, age, gender etc are stored in a MySQL database. Instead of listing every field, which is a lot, I want to generalize the code like this:

{% for field in object %}
 {{field.field_name}} : {{field.field_value}}
{% endfor %}

My problem is that I have multiple tables and each table has lots of fields. I cannot generalize the table. How do I generalize my template the way I've shown in the latter code snippet?

2 Answers

You can use get_fields method of Model _meta API for introspecting model fields :

Add a method to your model which will return the field name and corresponding value. you can just loop over these values in your template.

For example: I am using a Blog model you can change model name as per your code

models.py:

class Blog(models.Model):
    title = models.CharField(max_length=200)
    image = models.ImageField(null=True, blank=True)
    created = models.DateField(auto_now_add=True, null=True)

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

Views.py:

def bloglist(request):
    bloglist = Blog.objects.all()
    return render(request, 'bloglist.html',{'bloglist':bloglist })

In template bloglist.html you can write:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  </head>
  <body>
        <div class="container">
          <h1>
            Each attribute and value are:
          </h1>
          <br>

          {% for entry in bloglist %}
            <br>
            {% for name, value in entry.get_fields %}
                {% if value %}
                    {{name}} : {{value}}
                    <br>
                {% endif %}
            {% endfor %}
          {% endfor %}                  
        </div> 
  </body>
</html>

please refer official doc for Model _meta API:

https://docs.djangoproject.com/en/3.2/ref/models/meta/

Lets say you have this :

Models:

class Post(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    title = models.CharField(max_length=150, null=False, blank=False)
    body = models.CharField(max_length=150, null=False, blank=False)

Views:

def index(request):
    posts = Post.objects.all().values() 
    print(posts)
    return render(request,'index.html',{'posts':posts})

Note: if you don't add "values()" at the end of your queryset you'll get a blank page in the html file.

Template:

{%for p in post%}
-----------------
    <br>
  {%for k, v in p.items %}
    The key: {{ k }} ==> has a value: {{ v }} 
    <br>
  {%endfor%}
-----------------
{%endfor%}

You iterate on each post then you iterate over all items of that post and extract key and value, and so on..

of course you'll need to adjust this example to your actual data

Related