简体   繁体   English

Django 1.7:我可以使用prefetch_related()来获取不带有related_name的ForeignKey吗?

[英]Django 1.7: Can I use prefetch_related() to fetch an ForeignKey without a related_name?

I am trying to display Items to a page with the least amount of database hits as possible (there are a lot of Items). 我正在尝试将项目显示到数据库命中次数最少的页面上(有很多项目)。 Suppose my models look like this: 假设我的模型如下所示:

Class Item(models.Model):
    name = models.CharField(max_length=50, unique=True)

Class ItemAttribute(models.Model):
    item = models.ForeignKey(Item)
    name = models.ForeignKey(ItemAttributeName)

Class ItemAttributeName(models.Model):
    name = models.CharField(max_length=50, unique=True)

Notice there is no related name. 注意没有相关名称。 Items have a list of attributes, a good related_name I could use would be item_attributes. 项目具有属性列表,我可以使用的一个很好的related_name是item_attributes。 But for this question I am not doing that. 但是对于这个问题,我没有这样做。 I was wondering if there is a way to query a list of Items and their attributes so I can determine if the item is used or new. 我想知道是否有一种方法来查询项目及其属性的列表,以便可以确定该项目是已使用还是新的。

Item.ItemAttribute.ItemAttributeName.name = "USED"

would (should) look like (应该)看起来像

Item.item_attributes[0].name.name = "USED"

Something like that, you get the gist. 像这样的东西,你就明白了。

Is it possible to query the attributes name used prefetch_related()? 是否可以查询使用prefetch_related()的属性名称? I mean I know _related is in the name so this may seem like a dumb question but I was wondering if it's possible. 我的意思是我知道_related是名字,所以这似乎是一个愚蠢的问题,但我想知道是否有可能。 The obvious answer is to stop being an dummy and add a related_name but don't worry about that right now. 显而易见的答案是停止成为虚拟角色并添加related_name,但现在不必担心。

There's never any need to define a related_name (except if there is a conflict). 永远不需要定义related_name(除非有冲突)。 Django defines a perfectly good default. Django定义了一个完美的默认值。

However, your model structure has deeper problems than that. 但是,您的模型结构比这更深层的问题。 ItemAttribute is just the through table in a many-to-many relationship. ItemAttribute只是多对多关系中的穿透表。 You don't need it at all, because Django defines it automatically. 您根本不需要它,因为Django是自动定义的。 Just declare the actual relationship you care about, which is between Item and Attribute: 只需声明您关心的实际关系,该关系在Item和Attribute之间:

class Item(models.Model):
    name = models.CharField(max_length=50, unique=True)
    attributes = models.ManyToManyField('ItemAttributeName')

Now you can use prefetch_related directly to fetch everything: 现在,您可以直接使用prefetch_related来获取所有内容:

items = Item.objects.all().prefetch_related('attributes')

One possible solution is to retrieve a query of ItemAttributes such that 一种可能的解决方案是检索ItemAttributes的查询,以便

attributes = ItemAttribute.objects.filter(item=<given_item>)

Then look at names of those attributes... 然后查看这些属性的名称...

for attribute in attributes:
    if attribute.name.name == "USED":
        # do something
    else:
        # do something else

But this solution doesn't use prefetch_related because it implies a given item from a list of item's you've already queried... 但是此解决方案不使用prefetch_related,因为它暗示了您已经查询过的项目列表中的给定项目...

items = Item.objects.filter(<some_filter>)
for item in items:
    check_if_used(item)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM