Quantcast
Channel: Planet Python
Viewing all articles
Browse latest Browse all 22462

Experienced Django: Why kwargs?

$
0
0

I’ve noticed that several of the Django functions, especially filter, take a kwargs-style set of arguments.  I casually wondered about this but didn’t give it much thought until now.  I ran into a very practical use for it, that should have been obvious, but wasn’t to me.

The Setup

In my recent redesign of the KidTasks project, I opted to take the easy route for tasks which repeat on particular weekdays and simply put a BooleanField for each day of the week into the model.  This makes forms a bit easier but does cause some complications when trying to use a filter function to get a list of weekday-task pairs.  I started with the naive (and un-good) method of filtering each weekday independently:

# note: syntax on the filter here is from memory - might be incorrect!
qs = RepeatingTask.objects.filter(kid=self).filter('monday'=True)
tasks.append((day, [task for task in qs]))
qs = RepeatingTask.objects.filter(kid=self).filter('tuesday'=True)
tasks.append((day, [task for task in qs]))
    [etc]

While that will work, I’m sure you’ll agree that it’s ugly.

Kwargs to the rescue!

It turns out that the solution to this problem lies with those mysterious kwargs function signatures.  It turns out that filter takes one. This allows you to create a dict which you can create on the fly.  Which, in turn, allows you to use a variable to define the field on which you’re filtering!

days = [
    'monday',
    'tuesday',
    'wednesday',
    'thursday',
    'friday',
    'saturday',
    'sunday'
]

...

for day in self.days:
    qs = RepeatingTask.objects.filter(kid=self).filter(**{ day : True })
    tasks.append((day, [task for task in qs]))

Much nicer.  While this is likely obvious to most seasoned Django users, I thought it tied things together nicely.


Viewing all articles
Browse latest Browse all 22462

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>