I would like to perform a logical exclusive OR (XOR) on django.db.models.Q objects, using operator module to limit the choices of a model field to a subset of foreignkey. I am doing this in Django 1.4.3 along with Python 2.7.2. I had something like this:
import operator
from django.conf import settings
from django.db import models
from django.db.models import Q
from django.contrib.auth.models import User, Group
def query_group_lkup(group_name):
    return Q(user__user__groups__name__exact=group_name)
class Book(models.Model):
    author = models.ForeignKey(
                 User,
                 verbose_name=_("Author"),
                 null=False,
                 default='',
                 related_name="%(app_label)s_%(class)s_author",
                 # This would have provide an exclusive OR on the selected group name for User
                 limit_choices_to=reduce(
                     operator.xor,
                     map(query_group_lkup, getattr(settings, 'AUTHORIZED_AUTHORS', ''))
                 )
AUTHORIZED_AUTHORS is a list of existing group names.
But this did not work, because Q objects do not support ^ operator (only | and & operators from the docs). The message from the stacktrace was (partly) the following:
File "/home/moi/.virtualenvs/venv/lib/python2.7/site-packages/django/db/models/loading.py", line 64, in _populate
    self.load_app(app_name, True)
  File "/home/moi/.virtualenvs/venv/lib/python2.7/site-packages/django/db/models/loading.py", line 88, in load_app
    models = import_module('.models', app_name)
  File "/home/moi/.virtualenvs/venv/lib/python2.7/site-packages/django/utils/importlib.py", line 35, in import_module
    __import__(name)
  File "/opt/dvpt/toto/apps/book/models.py", line 42, in <module>
    class Book(models.Model):
  File "/opt/dvpt/toto/apps/book/models.py", line 100, in Book
    map(query_group_lkup, getattr(settings, 'AUTHORIZED_AUTHORS', ''))
TypeError: unsupported operand type(s) for ^: 'Q' and 'Q'
Therefore, inspired by this answer I attempted to implement an XOR for my specific lookup. It is not really flexible as the lookup is hardcoded (I would need to use kwargs in the arguments of query_xor for example...). I ended up doing something like this:
from django.conf import settings
from django.db import models
from django.db.models import Q
from django.db.models.query import EmptyQuerySet
from django.contrib.auth.models import User, Group
def query_xor_group(names_group):
    """Get a XOR of the queries that match the group names in names_group."""
    if not len(names_group):
        return EmptyQuerySet()
    elif len(names_group) == 1:
        return Q(user__user__groups__name__exact=names_group[0])
    q_chain_or = Q(user__user__groups__name__exact=names_group[0])
    q_chain_and = Q(user__user__groups__name__exact=names_group[0])
    for name in names_group[1:]:
        query = Q(user__user__groups__name__exact=name)
        q_chain_or |= query
        q_chain_and &= query
    return q_chain_or & ~q_chain_and
class Book(models.Model):
    author = models.ForeignKey(
                 User,
                 verbose_name=_("author"),
                 null=False,
                 default='',
                 related_name="%(app_label)s_%(class)s_author",
                 # This provides an exclusive OR on the SELECT group name for User
                 limit_choices_to=query_xor_group(getattr(settings, 'AUTHORIZED_AUTHORS', ''))
                 )
It works as I want but I seems to me rather not pythonic (especially the query_xor_group method).
Would there be a better (more direct way) of doing this?
Basically, my question can be stripped of the limit_choices_to part and be summarized as:
How can I make a bitwise exclusive OR on a set of django.db.models.Q objects in a Djangonic way?
 
     
     
    