Elegant Disjunctive Normal Form in Django
Posted
by Mike
on Stack Overflow
See other posts from Stack Overflow
or by Mike
Published on 2010-05-28T00:40:54Z
Indexed on
2010/05/28
0:41 UTC
Read the original article
Hit count: 232
Let's say I've defined this model:
class Identifier(models.Model):
user = models.ForeignKey(User)
key = models.CharField(max_length=64)
value = models.CharField(max_length=255)
Each user will have multiple identifiers, each with a key and a value. I am 100% sure I want to keep the design like this, there are external reasons why I'm doing it that I won't go through here, so I'm not interested in changing this.
I'd like to develop a function of this sort:
def get_users_by_identifiers(**kwargs):
# something goes here
return users
The function will return all users that have one of the key=value pairs specified in **kwargs. Here's an example usage:
get_users_by_identifiers(a=1, b=2)
This should return all users for whom a=1 or b=2. I've noticed that the way I've set this up, this amounts to a disjunctive normal form...the SQL query would be something like:
SELECT DISTINCT(user_id) FROM app_identifier
WHERE (key = "a" AND value = "1") OR (key = "b" AND value = "2") ...
I feel like there's got to be some elegant way to take the **kwargs input and do a Django filter on it, in just 1-2 lines, to produce this result. I'm new to Django though, so I'm just not sure how to do it. Here's my function now, and I'm completely sure it's not the best way to do it :)
def get_users_by_identifiers(**identifiers):
users = []
for key, value in identifiers.items():
for identifier in Identifier.objects.filter(key=key, value=value):
if not identifier.user in users:
users.append(identifier.user)
return users
Any ideas? :)
Thanks!
© Stack Overflow or respective owner