Django - ManyToMany - 如何过滤父对象的 ManyToMany

时间:2020-12-24 01:24:02

标签: django django-models django-views

我在为查询集模型编写过滤器时遇到问题:

class Order(models.Model):
  items = models.ManyToManyField(OrderLine)
  store = models.ForeignKey(Store, blank=True, null=True, on_delete=models.SET_NULL)

class OrderLine(models.Model):
  orderItemId = models.IntegerField(blank=False, null=False, unique=True)
  quantity = models.IntegerField(blank=True, null=True)

class Store(models.Model):
  storeName = models.CharField(max_length=200, blank=True, null=True)
  access_from_account = models.ManyToManyField(EDUser, blank=True)

我有 EDUser“帐户”的查询集 现在我想选择属于来自商店的订单的订单行,该订单在 access_from _account 中的帐户可见。

例如:

store_name_1access_from_account user_1, user_2

store_name_2access_from_account user_1

属于store_name_1订单。这些订单有许多OrderLines。 我想选择 user_1 应该可以访问的 order_lines。

我可以这样做: acounts 是 ['user_1'] 的查询集

lines = OrderLine.objects.filter(order__store__access_from_account__in=accounts)? 我试过了,但我得到了一些奇怪的值...

关于如何正确执行的任何建议?我想避免制作列表并对其进行迭代。

提前致谢:)

1 个答案:

答案 0 :(得分:2)

查询

lines = OrderLine.objects.filter(
    order__store__access_from_account__in=accounts
)

将正常工作。唯一的问题是,如果 accounts 包含两个用户,例如 user1user2,并且两个帐户都有权访问商店,则会复制行。因此,您将为 OrderLineuser1 检索 user2。这是由于中间的联结表上的 LEFT OUTER JOIN。您可以通过使用 .distinct() [Django-doc]:

来解决这个问题
lines = OrderLine.objects.filter(
    order__store__access_from_account__in=accounts
).distinct()

如果您使用单个 EDUser,则不需要 __in 查找:

# for a single user

lines = OrderLine.objects.filter(
    order__store__access_from_account=myuser
)