Führe ein logisches Exklusiv-ODER für ein Django Q-Objekt durch

Ich möchte ein logisches Exklusiv-ODER durchführen (XOR) auf django.db.models.Q-Objekten mitOperator Modul, um die Auswahl eines Modellfelds auf eine Untergruppe von Fremdschlüsseln zu beschränken. Ich mache das in Django 1.4.3 zusammen mit Python 2.7.2. Ich hatte so etwas:

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 ist eine Liste der vorhandenen Gruppennamen.

Dies funktionierte jedoch nicht, da Q-Objekte dies nicht unterstützen^ Operator (nur | und & Operatoren aus demdocs). Die Nachricht vom Stacktrace war (teilweise) die folgende:

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'

Daher von diesem inspiriertAntworten Ich habe versucht, ein XOR für meine spezifische Suche zu implementieren. Es ist nicht wirklich flexibel, da die Suche fest codiert ist (ich müsste beispielsweise kwargs in den Argumenten von query_xor verwenden ...). Am Ende habe ich so etwas gemacht:

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', ''))
                 )

Es funktioniert wie ich will, aber ich scheine eher nicht pythonisch zu sein (besonders die query_xor_group-Methode). Wäre es besser (direkter), dies zu tun?

Grundsätzlich kann meine Frage aus dem Teil limit_choices_to entfernt und wie folgt zusammengefasst werden:

Wie kann ich ein bitweises exklusives ODER für eine Gruppe von django.db.models.Q-Objekten auf Djangonic-Weise erstellen?

Antworten auf die Frage(1)

Ihre Antwort auf die Frage