Essex
Essex

Reputation: 6128

Django Class Based View with get_queryset()

I would like to use get_queryset() with Class Based View but I don't overcome to display variables in my template.

The function is very simple :

class MyClassView(LoginRequiredMixin, ListView) :

    template_name = 'my_template.html'
    model = Foo

    def get_queryset(self) :

        foo = Foo.objects.order_by('-id')
        bar = foo.filter(Country=64)
        return foo, bar

And my template :

<table style="width:120%">
                <tbody>
                <tr>
                    <th>ID</th>
                </tr>
                {% for item in foo %}
                <tr>
                    <td>{{ foo.id }}</td>
                </tr>
                {% endfor %}
                </tbody>
            </table>
<br></br>
<table style="width:120%">
                <tbody>
                <tr>
                    <th>ID</th>
                </tr>
                {% for item in bar %}
                <tr>
                    <td>{{ bar.id }}</td>
                </tr>
                {% endfor %}
                </tbody>
            </table>

I have to use Context dictionary ?

Upvotes: 1

Views: 8280

Answers (2)

Benjamin Hicks
Benjamin Hicks

Reputation: 764

Two things:

1) get_queryset returns, well, a QuerySet. You're returning a tuple. 2) Listview by default passes the query set into a template variable called object_list

However, you can do this all in the template with zero overrides to methods.

{% for item in object_list %}
    {% if item.country == 64 %}
    <tr>
      <td>{{ item.id }}</td>
    </tr>
   {% endif %}
{% endfor %}

That would iterate over all items Foo and only print ones that have country == 64 (If that's a foreign key, you'd need to construct the query differently.)

If for some reason you must do this in the view, you'll need to tweak by get_queryset and get_context to have two different object lists.

Upvotes: 1

Alasdair
Alasdair

Reputation: 308899

The get_queryset method for a ListView should return a single queryset (or list of items). If you want to add another variable to the context, then override get_context_data as well:

class MyClassView(LoginRequiredMixin, ListView) :

    template_name = 'my_template.html'
    model = Foo

    def get_queryset(self) :
        queryset = Foo.objects.order_by('-id')
        return queryset

    def get_context_data(self, **kwargs):
        context = super(MyClassView, self).get_context_data(**kwargs)
        context['bar_list'] = context['foo_list'].filter(Country=64)
        return context

In the template for a ListView, you access the queryset with object_list or <model>_list (e.g. foo_list), unless you set context_object_name. I've used bar_list in get_context_data to be consistent with that. You need to change the template to loop through {% for item in foo_list %} and {% for item in bar_list %}

Upvotes: 15

Related Questions