Perform a logical exclusive OR on a Django Q object Perform a logical exclusive OR on a Django Q object django django

Perform a logical exclusive OR on a Django Q object


You could add an __xor__() method to Q that uses and/or/not to do the XOR logic.

from django.db.models import Qclass QQ:    def __xor__(self, other):            not_self = self.clone()        not_other = other.clone()        not_self.negate()        not_other.negate()        x = self & not_other        y = not_self & other        return x | yQ.__bases__ += (QQ, )

After doing this I was able to Q(...) ^ Q(...) in a filter() call.

Foobar.objects.filter(Q(blah=1) ^ Q(bar=2)) 

Which means the original attempt no longer throws an unsupported operand exception.

limit_choices_to=reduce(                     operator.xor,                     map(query_group_lkup, getattr(settings, 'AUTHORIZED_AUTHORS', ''))                 )

Tested in Django 1.6.1 on Python 2.7.5