【发布时间】:2017-01-23 01:32:24
【问题描述】:
我有以下两个 Django 类 MyClassA 和 MyClassB。
MyClassB 有一个多对多字段MyClassAs
from django.db import models
class MyClassA(models.Model):
name = models.CharField(max_length=50, null=False)
def __str__(self):
return "<%s %s>" % (
self.__class__.__name__, "; ".join(["ID: %s" % self.pk, "name: %s" % self.name, ]))
class MyClassB(models.Model):
name = models.CharField(max_length=50, null=False)
my_class_as = models.ManyToManyField(MyClassA, related_name="MyClassB_my_class_as")
def __str__(self):
return "<%s %s>" % (
self.__class__.__name__, "; ".join(["ID: %s" % self.pk, "name: %s" % self.name, ]))
然后我使用以下数据为数据库播种:
>>> a = MyClassA.objects.create(name="A")
>>> b = MyClassA.objects.create(name="B")
>>> c = MyClassA.objects.create(name="C")
>>> d = MyClassA.objects.create(name="D")
>>> e = MyClassA.objects.create(name="E")
>>> u = MyClassB.objects.create(name="U")
>>> u.my_class_as.add(c)
>>> u.my_class_as.add(d)
>>> u.save()
我想查找与 MyClassA 的实例 c 或 d 有关系的 MyClassB 的(唯一)列表。我该怎么做??
我的解决方案是在MyClassB 上创建以下静态方法:
@staticmethod
def is_m2m_related_queryset(my_class_a_list):
q = Q()
for curr_a in my_class_a_list:
q |= Q(my_class_as=curr_a)
return q
...然后运行以下查询:
>>> MyClassB.objects.filter(MyClassB.is_m2m_related_queryset([c, d]))
[<MyClassB: <MyClassB ID: 11; name: U>>, <MyClassB: <MyClassB ID: 11; name: U>>]
但是等等!
这个查询集没有像我预期的那样返回一个包含u 对象的单例列表,而是返回[u, u]。那不是我想要的。
这不应该返回[u]吗?
为什么它会返回它所做的事情?
我应该如何得到我想要的?我应该简单地将.distinct() 附加到我的查询集吗?或者对我来说构建我的查询集是否有更好/更有效的方法?
编辑:
我尝试了下面建议的 Andrey 的解决方案(及其变体),但这也不起作用:
>>> MyClassB.objects.filter(my_class_as__pk__in=[c.pk, d.pk])
[<MyClassB: <MyClassB ID: 1; name: U>>, <MyClassB: <MyClassB ID: 1; name: U>>]
>>> MyClassB.objects.filter(my_class_as__in=[c, d])
[<MyClassB: <MyClassB ID: 1; name: U>>, <MyClassB: <MyClassB ID: 1; name: U>>]
【问题讨论】:
标签: python django orm many-to-many django-queryset