J. Donič
J. Donič

Reputation: 163

Query two models in Django into one queryset

I have two models in my django app:

class Person(models.Model):
    name = models.CharField(max_length=100)

class Book(models.Model):
    title = models.CharField(max_length=100)
    persons = models.ManyToManyField(Person, related_name="books")

Now I need to create a view that will make one query for regex to both of the models, find the ones that are matching and display them in template. If I do:

class SearchListView(ListView):
    queryset = Person.objects.filter(name__icontains="a")
    book_queryset = Book.objects.filter(title__icontains="a")

I get an error that ListView accepts only one queryset. What is the typical solution to such problem?

Upvotes: 1

Views: 114

Answers (1)

allexiusw
allexiusw

Reputation: 1744

You need to do something a little bit different here:

class SearchListView(ListView):
    queryset = Person.objects.filter(name__icontains="a")

    def get_context_data(self, **kwargs):
        context = super(SearchListView, self).get_context_data(**kwargs)
        context['book_queryset'] = Book.objects.filter(title__icontains="a")
        return context

Then in your view you can do somenting like the following:

{% for object in object_list %}
    <p>{{object}}</p>
{% endfor %}
{% for object in book_queryset %}
    <p>{{object}}</p>
{% endfor %}

The reason why the way you are using is not working is because ListView inherit from MultipleObjectMixin the queryset property and that property is passed to object_list context variable in the template, that happens under the hood and if you want to pass more context variables to the template you need to follow the approach I shared.

Upvotes: 1

Related Questions