1

How can you merge querysets in Django? I use the Django Rest Framework.

I work with the following model:

class City(models.Model):
    ...

class House(models.Model):
    city = models.ForeignKey(City, ...)
    ...

class Resident(models.Model):
    house = models.Foreignkey(House, ...)
    ...

I now want to have a view that lists all the residents of a given city (slug is the slug of the city).

Here is how I wrote it:

class ResidentList(generics.ListAPIView):
    lookup_field = 'slug'
    serializer_class = ResidentSerializer
    permission_classes = (IsAuthenticated, IsMayor)

    def get_queryset(self):
        residents = Resident.objects.filter(house__city__slug=self.kwargs['slug'])
        return residents

As you can see I create the list of residents for a city by iterating through all the citizens and filter those who life in a home that lifes in the right city. I just feel like this is pretty bad and inefficient, since the database has to loop through ALL the citizens. It would be better to have something like

City.objects.get(slug=<cityslug>).houses.residents

Then I would only have to loop through the smaller amount of cities. The problem with this obviously is that the above query returns a queryset. Therefore I can't chain houses and residents like that.

PS: If you have other suggestions how I can improve my view let me know!

PPS: I found this question here on stackoverflow, but it only shows how to get a list, which wouldn't work with get_queryset and the django rest structure, would it?

Edit (More specification to get the question better): So the goal is to hit the api route:

localhost:8000/api/house/<city_slug>/residents/

And get a list of all the residents in the city.

Like this:

{
  [
    {
      resdidentid = "<some_resident_id>",
      residentname = "<some_resident_name>",
      ...
    },
    {
      resdidentid = "<some_resident_id>",
      residentname = "<some_resident_name>",
      ...
    },
    {
      resdidentid = "<some_resident_id>",
      residentname = "<some_resident_name>",
      ...
    },
    ...
  ]
}
halfer
  • 19,824
  • 17
  • 99
  • 186
J. Hesters
  • 13,117
  • 31
  • 133
  • 249
  • Are you trying to display the filtered items ? – JPG Feb 20 '18 at 16:42
  • @jerin-peter-george I don't know, if I understand your question clearly. I will edit the post to specify the needs :) – J. Hesters Feb 20 '18 at 17:07
  • If you have a `residence list` at `/api/v1/residence/` , then you can filter those result by like `/api/v1/residence/?city=city_name&house=house_name` – JPG Feb 20 '18 at 17:18
  • Thank you! Nice idea, I just think that it wouldn't increase the performance, because it would use the same filtering as I do. – J. Hesters Feb 20 '18 at 17:20
  • I'm not much sure about the performance, but it would be more stylish ;) – JPG Feb 20 '18 at 17:21
  • Have you looked at the resulting SQL from the Resident.objects filter() call, and analyzed it? It will certainly generate some joins, but that seems like a reasonable enough filter call for what you want. – Shane Feb 20 '18 at 20:01

0 Answers0