Django - RelatedManager _set filter in a template?

We have a Django DetailView where we show an object ( Site ) along with all related objects ( Rooms ).

Now, in the template, we can simply iterate over the RelatedManager set:

 {% for room in site.room_set.all %} do stuff {% endfor %} 

However, the problem is that this will result in all related rooms being hosted on the site. However, we need to narrow this set down with a slightly different attribute (let it be called year ) - and this attribute is stored in a Django session variable.

Currently, we just use Room.objects.filter(site=some_site, year='2009') in the view code, which is great.

My question is more out of curiosity - is there a way to use _set in a template and still filter or narrow the set?

Could you write your own model manager for this, so that _set returns objects only for the current year? Or is there some other way?

Cheers, Victor

+4
source share
1 answer

My question is more out of curiosity - is there a way to use _set in a template and still filter or narrow the set?

Not by default, as there is no way to pass arguments to a filter call.

  • If this functionality that needs to be changed is often related to the template: create your own template tag or filter (which can take arguments).
  • If this is view-specific functionality, enter the code in the view.
  • If this is functionality, the same thing in several views, build the function in a dry place.

For # 3, there are so many factors that determine where this code should go, that there is no general solution. Can you import a function into your views? Use model manager? Model instance method? context processor? etc.

Could you write your own model manager for this, so that _set will only return objects for the current year? Or is there another way?

It looks like you can just use the model manager for your inverse model.

 class RoomManager(models.Manager): def current_year(self): return self.get_queryset().filter(year=datetime.date.today().year) for room in site.room_set.current_year(): ... 

Or only in the parent model:

 class Site(models.Model): ... def year_room_set(self): return self.room_set.filter(year=datetime.date.today().year) 
+2
source

Source: https://habr.com/ru/post/1379254/


All Articles