select_related 问题

1 投票
2 回答
4143 浏览
提问于 2025-04-17 17:43

这是我的模型:

class Brand(models.Model):
    name         = models.CharField(max_length=30)
    order        = models.SmallIntegerField()

class FeatureGroup(models.Model):
    name         = models.CharField(max_length=30)

class Feature(models.Model):
    name         = models.CharField(max_length=30, blank=True)
    order        = models.SmallIntegerField()
    group        = models.ForeignKey(FeatureGroup)

class FeatureDetail(models.Model):
    description         = models.TextField()
    feature             = models.ForeignKey(Feature)

class Phone(models.Model):
    name         = models.CharField(max_length=30)
    brand        = models.ForeignKey(Brand)
    features     = models.ManyToManyField(FeatureDetail)

我想获取当前手机的特性和特性详情,并遍历数据对,但我做不到。

我试过这个方法,它只成功获取了品牌:

p = get_object_or_404(Phone.objects.select_related('brand', 'feature__featuredetail'), id=id)

然后当我这样做时:

print p.featuredetail_set.all()

我得到了这个错误:

Django Version: 1.4.3
Exception Type: AttributeError
Exception Value:    
'Phone' object has no attribute 'featuredetail_set'

这是怎么回事?

2 个回答

1

你的关系叫做 features,而不是 featuredetail_set

要注意,这和 select_related 没有关系,因为在这种情况下它没有任何作用(而且它只对正向外键有效)。

2

你不能直接用类名作为select_related的参数。这个参数必须是你模型字段的字符串。

在你的情况下,应该用'features__feature'

另一个问题是,select_related 不能处理多对多的关系。所以才有了prefetch_related这个东西。

因此,你的查询集应该是:

Phone.objects.select_related('brand').prefetch_related('features__feature')

需要注意的是,prefetch_related会创建一个额外的查询,并在Python中进行连接。

撰写回答