Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django - One view, multiple URLs?

I am fairly new to both Python and Django and would like to follow best practices where possible. I would like to tidy up the following code to make it easier to work with.

I am trying to set up a view which can be accessed through multiple URLs which provide different parameters for which a queryset will be returned and displayed.

I have set up the following URLs:

    url(r'^myrecords/$', login_required(RecordListView.as_view()), {'filter': 'all'}, name='myrecords'),
    url(r'^myrecords/page(?P<page>[0-9]+)/$', login_required(RecordListView.as_view()), {'filter': 'all'}, name='myrecords'),
    url(r'^myrecords/(?P<year>\d{4})/$', login_required(RecordListView.as_view()), {'filter': 'year'}, name='myrecords'),
    url(r'^myrecords/last(?P<months>[0-9]{1,2})months/$', login_required(RecordListView.as_view()), {'filter': 'month'}, name='myrecords'),

Then in my view I have something like this (There are actually several other parameters but these should remain the same regardless of the URL entered.):

def get_queryset(self): 
    if (self.kwargs['filter'] == 'month'):
        x_months_ago = (datetime.date.today() - 
        datetime.timedelta(int(self.kwargs['months']) * 365 / 12))
        queryset = Record.objects.filter(user=self.request.user, 
        date__gte = x_months_ago.isoformat())
    elif (self.kwargs['filter'] == 'year'):
        queryset = Record.objects.filter(user=self.request.user, date__year=self.kwargs['year'])
    else
        queryset = Record.objects.filter(user=self.request.user)

This seems very messy to me. Is there anyway I can make it cleaner? Is it possible to put the filter parameters in some sort of data structure and then just pass them to the Record.objects.filter line, rather than writing the whole thing out multiple times?

Any advice would be greatly appreciated.

Thanks.

like image 689
Dan Avatar asked Sep 14 '11 17:09

Dan


1 Answers

Sure. You can use a dictionary:

my_queryset_filters = {
    'user': self.request.user,
    'date__year': self.kwargs['year'],
}

Record.objects.filter(**my_queryset_filters)

The ** expands the dictionary into keyword arguments. (There's also * which expands a list into positional arguments.)

like image 130
Chris Pratt Avatar answered Sep 21 '22 09:09

Chris Pratt