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

时间:2017-04-13 17:28:43

标签: python django django-queryset

我正在尝试将项目显示到尽可能少的数据库命中的页面(有很多项目)。假设我的模型看起来像这样:

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)

请注意,没有相关名称。项目有一个属性列表,我可以使用的一个好的相关名称是item_attributes。但对于这个问题,我不这样做。我想知道是否有办法查询项目及其属性列表,以便我可以确定该项目是使用还是新项目。

Item.ItemAttribute.ItemAttributeName.name = "USED"

会(应该)看起来像

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

类似的东西,你得到了要点。

是否可以查询prefetch_related()使用的属性名称?我的意思是我知道_related在名字中,所以这可能看起来像一个愚蠢的问题,但我想知道它是否可能。显而易见的答案是不再是假人并添加一个相关名称,但现在不要担心。

2 个答案:

答案 0 :(得分:0)

永远不需要定义related_name(除非存在冲突)。 Django定义了一个非常好的默认值。

但是,您的模型结构存在更深层次的问题。 ItemAttribute只是多对多关系中的直通表。你根本不需要它,因为Django自动定义它。只需声明您关心的实际关系,即物品和属性之间的关系:

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

现在您可以直接使用prefetch_related来获取所有内容:

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

答案 1 :(得分:0)

一种可能的解决方案是检索ItemAttributes的查询,使其

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

然后查看这些属性的名称......

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

但是这个解决方案并没有使用prefetch_related,因为它暗示了你已经查询过的项目列表中的给定项目......

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