Django .filter on same option with multiple possibilities
I have a model of objects. I also have a list of options to filter results with. I'm not sure if t开发者_JAVA百科here is an easy way to filter the objects in the model such that any object that matches any of the items in the filter list is returned. For example:
# returns all users with name starting with 'P'
usersWithPName = User.objects.filter(name__startswith = 'P')
# 3 letters to filter User model with
filterList = ['P', 'T', 'R']
# ideally would return all users with name starting with either 'P', 'T', or 'R'
usersWithPTRName = User.objects.filter(name__startswith = filterList)
Is there any way to filter (in this case) the User model such that any object matching any one of the items in the filterList is returned?
This can be done with Q objects
from django.db.models import Q
usersWithPTRName = User.objects.filter(Q(name__startswith='P') |
Q(name__startswith='T') |
Q(name__startswith='R'))
Also you can build Q filters at runtime:
filterList = ['P', 'T', 'R']
query = Q()
for letter in filterList:
query = query | Q(name__startswith=letter)
usersWithPTRName = User.objects.filter(query)
You can use python reduce
and operator
builtins:
import operator
from functools import reduce
from django.db.models import Q
values = ["blue", "green", "brown"]
# or condition
conditions = reduce(operator.or_, [Q(**{"categories__slug": value}) for value in values])
# and condition
conditions = reduce(operator.and_, [Q(**{"categories__slug": value}) for value in values])
queryset = queryset.filter(conditions)
Two choices.
Include the first letter as a property in your model.
Use more advanced queries.
You can do this
class User( models.Model ):
... all the usual stuff ...
@property
def first_letter( self ):
return self.name[:1]
Now can you filter with filter( first_letter__in=('P','T','R') )
The second choice is to build Django Q
objects for your filter.
Start here: https://stackoverflow.com/search?q=django+Q+objects
精彩评论