如何使用 Q 正确过滤 Many2Many / Generic 关系?
我有 3 个模型,TaggedObject 与 ObjectTagBridge 有 GenericRelation。 ObjectTagBridge 有一个标签模型的外键。
class TaggedObject(models.Model):
"""
class that represent a tagged object
"""
tags = generic.GenericRelation('ObjectTagBridge',
blank=True, null=True)
class ObjectTagBridge(models.Model):
"""
Help to connect a generic object to a Tag.
"""
# pylint: disable-msg=W0232,R0903
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
tag = models.ForeignKey('Tag')
class Tag(models.Model):
...
当我将标签附加到对象时,我正在创建一个新的 ObjectTagBridge 并将其外键标签设置为我要附加的标签。这工作正常,我可以非常轻松地获取附加到对象的所有标签。但是,当我想获取(过滤)具有 Tag1 和 Tag2 的所有对象时,我尝试这样做:
query = Q(tags__tag=Tag1) & Q(tags__tag=Tag2)
object_list = TaggedObjects.filter(query)
但现在我的 object_list 为空,因为它正在寻找具有一个带有 2 个标签对象的 ObjectTagBridge 的 TaggedObject,第一个带有 Tag1 和第二个带有 Tag2。
我的应用程序将比这个更复杂的 Q 查询,所以我认为我需要一个带有此 Q 对象的解决方案。事实上,任何二元连词的组合,例如: (...) and ( (...) or not(...))
我怎样才能正确过滤这个?欢迎每个答案,也许还有其他方法可以实现这一目标。
谢谢你的帮助!
I have 3 Models, the TaggedObject has a GenericRelation with the ObjectTagBridge. And the ObjectTagBridge has a ForeignKey to the Tag Model.
class TaggedObject(models.Model):
"""
class that represent a tagged object
"""
tags = generic.GenericRelation('ObjectTagBridge',
blank=True, null=True)
class ObjectTagBridge(models.Model):
"""
Help to connect a generic object to a Tag.
"""
# pylint: disable-msg=W0232,R0903
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
tag = models.ForeignKey('Tag')
class Tag(models.Model):
...
when I am attaching a Tag to an Object, I am creating a new ObjectTagBridge and set its ForeignKey tag to the Tag I want to attach. That is working fine, and I can get all Tags that I attached to my Object very easy. But when I want to get (filter) all Objects that have Tag1 and Tag2 I tried to something like this:
query = Q(tags__tag=Tag1) & Q(tags__tag=Tag2)
object_list = TaggedObjects.filter(query)
but now my object_list is empty, because it is looking for TaggedObjects that have one ObjectTagBridge with 2 tag objects, the first with Tag1 and the second with Tag2.
I my application will be more complex Q queries than this one, so I think I need a solution with this Q object. In fact any combination of binary conjunctions, like: (...) and ( (...) or not(...))
How can I filter this correctly? Every answer is welcome, maybe there is also a different way do achieve this.
thx for your help!!!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您要查找的结果是具有 Tag1 和 Tag2 的 TaggedObject,请考虑查询 TaggedObject 而不是查询 ObjectTagBridge。该查询可能如下所示:
本质上我们正在执行两个过滤器。只有同时具有 Tag1 和 Tag2 的对象才会通过过滤条件并成为结果集的一部分。
If the result you are looking for is a TaggedObject with Tag1 and Tag2, consider querying the TaggedObject instead of querying the ObjectTagBridge. This is what that query might look like:
Essentially we are conducting two filters. Only objects with both Tag1 and Tag2 will pass the filtering criteria and be a part of the result set.
看起来您正在尝试手动实现多对多表,然后将其与通用关系结合起来。更好的方法可能是让 Django 为您处理 M2M,并将其表示为通用关系,如下所示:
这应该让您可以做您想做的事情......
It looks like you are trying to manually implement a Many-to-Many table and then combine that with a generic relation. A better approach might be to let Django handle the M2M for you, and just have it represented on the generic relationship like so:
This should let you do what you were trying to do...