Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to put common queries in Django?

I have a queryset that is reasonably complicated, which I currently use in a single view for getting a list of objects.

I want to use the same queryset in a couple of other views but would prefer not to just copy the code multiple times. I could use a Manager, to keep the queryset in one place, and use that in each view except the query relies on a date which is different on each page.

As I understand it, Managers don't let you pass in variables... so I'm wondering where I should put this query so as not to keep repeating it in several views. Any thoughts?

FWIW, this is my queryset, and published_date is the variable that changes on each page:

day_publications = Publication.objects.filter(
        Q(reading__end_date__gte=published_date) | Q(reading__end_date__isnull=True),
        reading__start_date__lte=published_date,
).select_related('series',)
like image 275
Phil Gyford Avatar asked Dec 27 '10 20:12

Phil Gyford


People also ask

What is __ GTE in Django?

The __lte lookup [Django-doc] means that you constrain the field that is should be less than or equal to the given value, whereas the __gte lookup [Django-doc] means that the field is greater than or equal to the given value.

What is difference between Icontains and contains in Django?

Definition and Usage The contains lookup is used to get records that contains a specified value. The contains lookup is case sensitive. For a case insensitive search, use the icontains lookup.


1 Answers

I think you should actually use a Manager. I habitually use methods like this in my managers:

class CustomManager(models.Manager):

    def get_records(self, city_slug, dt):
        filter_kwargs = { 
            'city__slug': city_slug,
            'date_from__lt': dt,
            'date_to__gt': dt,
        }   
        return super(CustomManager, self).get_query_set().filter(**filter_kwargs)

Then I run the query on my model:

MyModel.objects.get_records(city.slug, datetime.now())

Of course, you can follow up with another call of filter and chain these or do whatever you want. There's nothing wrong with this kind of approach, that's what managers are here for :-).

like image 83
VoY Avatar answered Sep 20 '22 03:09

VoY