Django和编写带有大量连接的查询

时间:2014-05-02 15:48:07

标签: django django-models

我很难通过大量连接进行这类查询。我没有找到例子,但我想它们写起来并不复杂。它只有几个FK。

这是models.py(不复杂)

class User(AbstractBaseUser, PermissionsMixin): # Django custom user model
    # Some stuff

class CliProfile(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL)

class BizProfile(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL)

class Card(models.Model):
    linked_client = models.ForeignKey(CliProfile, blank=True, null=True)

class Points(models.Model):
    benef_card = models.ForeignKey(Card)
    at_owner = models.ForeignKey(BizProfile)
    creation_date = models.DateTimeField(auto_now_add=True)

模型的快速描述

  • 用户可以是客户端(使用CliProfile)或业务(使用BizProfile)
  • 每张卡都链接到客户
  • 每张卡片包含[points - business]协会

这样一来:客户有一张牌,可以在必胜客获得3分,在麦当劳获得5分同一张卡)

我试图写的请求

从功能上讲,目的是拥有者(如PizzaHut)可以看到他所有的客户(拥有在必胜客有点卡的客户)

从技术上讲,我试图编写一个查询来获取所有客户(即一个CliProfile查询集),这些客户的卡(至少有一个)的所有者(其中至少有一个)的所有者(有至少一个)只有1)其用户(只有1)= request.user?

你知道怎么写这样的查询吗?非常感谢。

1 个答案:

答案 0 :(得分:2)

要匹配filter()中模型中的字段,您需要使用两个下划线。以下为我工作

CliProfile.objects.filter(card__points__at_owner=request.user)

但@ Alex的建议最有意义,除非这只是你要做的事情的一个例子。

如果您想要与多张卡片中的一张相关联的配置文件,您可以使用__in field lookup

CliProfile.objects.filter(card__in=IterableOfCards)

另外,您不要在filter()中使用==。这将返回True或False,然后在filter()调用中传递该值,从而有效地使调用过滤器(True或False)无效。你必须使用=因为你正在将一个命名参数传递给过滤函数。

为什么选择card而不是card_set()? cart_set仅存在于CliProfile的实例中。您不在CliProfile的实例中,而是试图获取它们的列表。

你可以在终端试试,它会告诉你有效的选择。

#Note that it doesn't matter what you put after=, since it fails before that is checked.
>>> CliProfile.objects.filter(card_set=True)
FieldError: Cannot resolve keyword 'card_set' into field. Choices are: card, id, user

一张CliProfile可以被多张牌引用,这就是为什么card_set存在于其中,但你试图匹配一张牌。其card points字段为at_owner的{​​{1}}。

您可以使用request.user获取其卡片的子集,或使用a_cliprofile_instance.card_set.filter()显示所有卡片