simple way for QuerySet union and subtraction in django?

后端 未结 5 801
醉话见心
醉话见心 2021-02-07 02:15

Consider two QuerySet objects of the same class. Is there a simple way to unify them into a single QuerySet by calculating the union? Also, is there a simple way to subtract the

相关标签:
5条回答
  • 2021-02-07 02:21

    You can use the Q object.

    The syntax could be something like this:

    added_query_set = YourModel.objects.\
             filter(Q(id__in=old_query_set_1)|Q(id__in=old_query_set_2))
    

    You probably can optimize based on your actual needs and get the amount of db hits down (right now it's 3), but this should get you started.

    0 讨论(0)
  • 2021-02-07 02:32

    Subtract a QuerySet from another QuerySet using the same model.

    This works - but is probably slowly

    queryset_with_hello = Blog.objects.filter(name__icontains='hello')
    queryset_without_hello = Blog.objects.exclude(pk__in=queryset_with_hello)
    

    Read the performance considerations in django documentation:

    https://docs.djangoproject.com/en/dev/ref/models/querysets/#in

    0 讨论(0)
  • 2021-02-07 02:36

    I think for operations as this you need to evalute them. So you can call list() on them and work on them with the common python list operations!

    0 讨论(0)
  • 2021-02-07 02:39

    Going back to django's documentation, you can:

    new_query_set = query_set_1 | query_set_2
    

    This works as a logical OR which is actually addition without duplicates. This answers the addition aspect and AFAIK does not hit the db at all!

    new_query_set = query_set_1 & query_set_2
    

    This works as a logical AND.

    Still missing how to subtract QuerySets. It's hard for me to believe this has not been dealt with elegantly by the community...

    0 讨论(0)
  • 2021-02-07 02:42

    Since Django 1.11, QuerySets have union(), intersection() and difference() methods.

    It's also possible to use & and | operators with QuerySets (I could not find a reference to this in the docs, so I guess union() and intersection() is the preferred way to combine two querysets.

    qs3 = qs1.union(qs2)         # or qs3 = qs1 | qs2
    qs3 = qs1.intersection(qs2)  # or qs3 = qs1 & qs2
    qs3 = qs1.difference(qs2)    # the ^ operator is not implemented.
    

    You can also use Q() objects which like QuerySets implement | and &, and additionally the inversion operator ~

    0 讨论(0)
提交回复
热议问题