我很难通过大量连接进行这类查询。我没有找到例子,但我想它们写起来并不复杂。它只有几个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)
模型的快速描述
这样一来:客户有一张牌,可以在必胜客获得3分,在麦当劳获得5分同一张卡)
我试图写的请求
从功能上讲,目的是拥有者(如PizzaHut)可以看到他所有的客户(拥有在必胜客有点卡的客户)
从技术上讲,我试图编写一个查询来获取所有客户(即一个CliProfile查询集),这些客户的卡(至少有一个)的所有者(其中至少有一个)的所有者(有至少一个)只有1)其用户(只有1)= request.user?
你知道怎么写这样的查询吗?非常感谢。
答案 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()
显示所有卡片