Multiple models in a single get_queryset() to populate data in a template

Viewed 73

I'm trying to push multiple data sets into a template, home.html, using class based views. I don't know if this is the right way or if there is a better way to do this.

views.py

class HomePage(ListView):
   template_name = 'home.html'
   context_object_name = 'result'

   def get_queryset(self):
      query1 = {}
      query2 = {}
      query3 = {}
      query1['url'] = table1.objects.filter(username=self.kwargs['username'])
      query2['text'] = table2.objects.filter(username=self.kwargs['username'])
      query3['link'] = table3.objects.filter(username=self.kwargs['username'])
      return (query1, query2, query3)

home.html

{% for query1_data in result %}
   {% if query1_data.url %}
       <img src="{{query1_data.url}}">
   {% endif %}
{% endfor %}

{% for query2_data in result %}
   {% if query2_data.text %}
       ...
   {% endif %}
{% endfor %}

It works but it seems like there should be a better way to do this.

Thanks!

2 Answers

I would use a TemplateView instead:

from django.views.generic import TemplateView

class HomePage(TemplateView):
    template_name = 'home.html'
   
    def get_context_data(self, **kwargs):
        result = {
            'table1': Table1.objects.filter(username=self.kwargs['username']),
            'table2': Table2.objects.filter(username=self.kwargs['username']),
            'table3': Table3.objects.filter(username=self.kwargs['username']),
        }
       return result

Then you can iterate over them in your template like so:

{% for object in table1 %}
    <img src="{{ object.url }}">
{% endfor %}

{% for object in table2 %}
    ...
{% endfor %}

Also, please use Pascal Casing (capitalized) for class names :)

Try to use this approach. Simple and clear.

from django.views.generic import TemplateView

class HomePage(TemplateView):
   template_name = 'home.html'

   def get_context_data(self, **kwargs):
      ctx = super().get_context_data(**kwargs)
      ctx.update({
         'urls' : table1.objects.filter(username=self.kwargs['username']),
         'texts': table2.objects.filter(username=self.kwargs['username']),
         'links': table3.objects.filter(username=self.kwargs['username'])
      })
      return ctx

In your template

{% for url in urls %}
    <img src="{{url.url}}">
{% endfor %}

{% for text in texts %}
    ...
{% endfor %}
Related