Django filter queryset on “tuples” of values for multiple columns

后端 未结 3 1557
孤独总比滥情好
孤独总比滥情好 2021-02-04 01:40

Say I have a model:

Class Person(models.Model):
    firstname = models.CharField()
    lastname = models.CharField()
    birthday = models.DateField()
    # etc.         


        
相关标签:
3条回答
  • 2021-02-04 02:18

    I don't see much solutions except for a big OR clause:

    import operator
    from itertools import izip
    query = reduce(
        operator.or_, 
        (Q(firstname=fn, lastname=ln) for fn, ln in izip(first_list, last_list))
        )
    
    Person.objects.filter(query)
    
    0 讨论(0)
  • 2021-02-04 02:28

    bruno's answer works, but it feels dirty to me - both on the Python level and on the SQL level (a large concatenation of ORs). In MySQL at least, you can use the following SQL syntax:

    SELECT id FROM table WHERE (first_name, last_name) IN
           (('John','Doe'),('Jane','Smith'),('Bill','Clinton'))
    

    Django's ORM doesn't provide a direct way to do this, so I use raw SQL:

    User.objects.raw('SELECT * FROM table WHERE (first_name, last_name) IN %s',
          [ (('John','Doe'),('Jane','Smith'),('Bill','Clinton')) ])
    

    (This is a list with one element, matching the single %s in the query. The element is an iterable of tuples, so the %s will be converted to an SQL list of tuples).

    Notes:

    1. As I said, this works for MySQL. I'm not sure what other backends support this syntax.
    2. A bug in python-mysql, related to this behavior, was fixed in November 2013 / MySQLdb 1.2.4, so make sure your Python MySQLdb libraries aren't older than that.
    0 讨论(0)
  • 2021-02-04 02:29

    Using python 3.5 version :

    import operator
    import functools
    
    query = functools.reduce(
        operator.or_, 
        (Q(firstname=fn, lastname=ln) for fn, ln in zip(first_list, last_list))
        )
    
    Person.objects.filter(query)
    
    0 讨论(0)
提交回复
热议问题