对 Django Q 对象执行逻辑异或

2023-12-23

我想执行逻辑异或(XOR http://en.wikipedia.org/wiki/Exclusive_disjunction) on django.db.models.Q对象,使用operator http://docs.python.org/2/library/operator.html模块将模型字段的选择限制为外键的子集。我在 Django 1.4.3 和 Python 2.7.2 中执行此操作。我有这样的事情:

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是现有组名称的列表。

但这并没有奏效,因为Q对象不支持^运算符(仅| and &运营商从docs https://docs.djangoproject.com/en/1.4/topics/db/queries/#complex-lookups-with-q-objects)。来自堆栈跟踪的消息(部分)如下:

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'

因此,受此启发answer https://stackoverflow.com/questions/8903128/python-list-to-bitwise-operations我尝试为我的特定查找实现异或。它并不是很灵活,因为查找是硬编码的(我需要使用kwargs在论据中query_xor例如...)。我最终做了这样的事情:

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

它按照我想要的方式工作,但在我看来,我并不是Pythonic(尤其是query_xor_group方法)。 是否有更好(更直接的方式)来做到这一点?

基本上,我的问题可以被剥夺limit_choices_to部分并总结为:

如何对一组进行按位异或运算django.db.models.Q以姜戈式的方式对象?


你可以添加一个__xor__()Q 的方法使用和/或/不执行异或逻辑。

from django.db.models import Q

class 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 | y

Q.__bases__ += (QQ, )

这样做之后我能够Q(...) ^ Q(...) in a filter() call.

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

这意味着最初的尝试不再抛出不支持的操作数异常。

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

测试于Django 1.6.1 on Python 2.7.5

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

对 Django Q 对象执行逻辑异或 的相关文章

随机推荐

  • 找不到org.springframework.util.ClassUtils.getMethod并且无法初始化DefaultConversionService

    运行我的应用程序后 它会在控制台中显示以下错误 我研究了这个问题 但它answer https stackoverflow com questions 20851236 spring mvc http status 500 servlet
  • Django 模型管理器是否需要 using=self._db

    在使用 Django 用户模型时 我注意到模型管理器包括using self db作用于数据库时的参数 如果我只使用单个数据库 这有必要吗 什么是using self db除了指定数据库之外 还可以执行其他操作 如果添加另一个数据库 这是否
  • gdb 回溯

    我刚刚尝试过使用 gdb回溯Linux http www backtrack linux org 我必须说这太棒了 我想知道 backtrack 中的 gdb 是如何配置为这样的 当我设置断点时 会打印所有寄存器值 堆栈的一部分 数据部分的
  • 适用于 Android 的 Google 环聊 API

    您知道如何将 Google Hangout 集成到 Android 应用程序中吗 我没有看到任何当前可用的 API 使用 WebView 是一种选择吗 目前没有任何内容 我不相信 WebView 版本会起作用 因为环聊需要谷歌安装的相机插件
  • Python Fizzbuzz 循环问题

    我已经搜索了大约一个小时的答案 似乎大多数人都以与我不同的方式编码 fizzbuzz 然而 在尝试了一切方法来找出为什么这个简单的代码不起作用之后 我感到非常沮丧 谁能指出我确定遇到的简单问题 代码运行但只返回值 1 def fizzbuz
  • Android L Nexus 5 上的材料设计

    我的应用程序在 Android L 上崩溃 但在 Android Kitkat 上运行 布局上也没有 RippleDrawable 这是异常和布局 XML 布局
  • ocaml 命令行找不到“topfind”

    我已经安装了顶级 并且有 OCAML TOPLEVEL PATH 设置 export OCAML TOPLEVEL PATH Users smcho opam system lib toplevel 我检查该目录是否存在 并且有一个文件to
  • 在 strpos() 的字符串中使用正则表达式

    我想让脚本搜索 open email msg 不同的电子邮件将有不同的信息 但格式相同 如下所示 我并没有真正使用正则表达式太多 但我想做的是每当我用它来搜索字符串时 它都会搜索 标题 标题数据 类别 类别数据 我问因为我不认为类似的事情
  • 无法找到 Python PIL 库。Google App Engine

    完美安装了Google App Engine SDK Python 2 6 想要进入图像并在本地进行测试 已安装 PIL 安装了Python 然后运行了PIL安装 这次成功了 事情看起来不错 但尝试进行本地主机图像处理 给出 NotImpl
  • Node Puppeteer, page.on( "request" ) 抛出“请求已处理!”

    我在用着puppeteer extra https www npmjs com package puppeteer extra和 node js 来迭代多个 url 我试图拦截一些资源类型以在每次迭代时加载 并收到以下错误 PS C Use
  • ios 中的阴影

    iOS 中如何去掉物体的阴影 My object is UIImageView and i want to drop an elliptical shadow Please refer image for reference 最好使用另一张
  • 使一个流的输出成为另一个流的输入的最佳方法是什么

    我想知道除了使用字节缓冲区和循环之外 是否有更好 内置的方法从一个流读取并将其写入另一个流 在 NET 中 通常 这样做是为了将转换应用于流并将其继续移动 在本例中 我正在加载一个文件 将其放入 deflate 流并将其写入文件 为简单起见
  • AMD(特别是 RequireJs)如何处理跨多个模块的依赖关系

    我有一个调用 require 的主初始化脚本 其中一个依赖项是实用程序框架 但我通过 require 指定的其他一些模块本身也已将此框架定义为依赖项 例如 init js require module a module b module c
  • 删除了方法的 C++ 类可以轻松复制吗?

    我希望类 B 继承类 A 的除少数方法之外的所有方法 假设它是可简单复制的 并且仍然可简单复制 在 C 11 中我可以删除方法 举个例子 class A trivially copyable private stuff here publi
  • 用于奇异控制流的 ES6 Promise 模式

    ES6 Promise 很棒 到目前为止 调整我的想法很容易 回调习惯用法 我发现它自然地鼓励更多的模块化代码 并且 当然错误处理更加清晰 但有几次我遇到了看起来不像 的心流情况 可以很容易地从节点返回到承诺 也许就是这样 但也许我只是对答
  • 如何在 VS Code 设置中为 VS Code 进程指定环境变量?

    我发现这两种方法来添加环境变量 添加环境变量terminal integrated env osx对于终端 添加环境变量launch json用于调试 但 VSCode Process 没有类似的配置选项 一些插件经常需要访问特定的环境变量
  • C++ 中的 rand() 和 srand()

    C 中生成随机数的基础是什么 这背后有什么逻辑或者原理吗 生成的数字是完全随机的吗 假设我正在运行这个程序 include
  • 在javascript中获取元数据属性

    我在从元标记检索信息时遇到问题 我正在尝试从网站获取 img src 但不太明白 这是我正在尝试做的一个例子 var image document querySelector meta property og image getAttrib
  • 如何在引导模式主体上创建具有固定标题的可滚动表格?

    我尝试了这个 但这不起作用 字段值是动态变化的 所以宽度不固定 div class table responsive table class table table hover thead tr tr thead tbody style h
  • 对 Django Q 对象执行逻辑异或

    我想执行逻辑异或 XOR http en wikipedia org wiki Exclusive disjunction on django db models Q对象 使用operator http docs python org 2