3

我有几个模型:Review,其中包含专辑评论字段,Record,这是专辑名称等,以及Band,这是乐队名称。Record有一个外键反对Band并且Review有一个外键反对Record

Review我想为所有Records 显示一个下拉选择框的管理表单中。目前,用于的 unicode 方法Record只是:

def __unicode__(self):
    return self.record_name

这不是很有帮助,所以我将其更改为:

def __unicode__(self):
    return self.band.band_name + ' - ' + self.record_name  

这现在为每个(3000 左右)添加一个查询Record,显然不好。

阅读此答案后,我尝试将其添加到我的模型管理员中Record

def queryset(self, request):
    return super(RecordAdmin, self).queryset(request).select_related('band')

不过,这并没有什么不同。

是否可以在模型表示中使用外键字段__unicode__而不会产生 n 平方查询?

更新:这是模型(删除了不相关的字段):

class Review(models.Model):

    def __unicode__(self):
        # this is used in other places where we show review titles
        return self.record.band.band_name + ' - ' + self.record.record_name

    record = models.ForeignKey('Record')
    review_text = models.TextField()

class Record(models.Model):

    def __unicode__(self):
        # this generates a billion queries
        #return self.record_name
        return self.band.band_name + ' - ' + self.record_name  

    def band_and_title(self):
        return self.band.band_name + ' - ' + self.record_name

    band = models.ForeignKey('Band')
    label = models.ForeignKey('Label')
    record_name = models.CharField(max_length=175)

class Band(models.Model):

    def __unicode__(self):
        return self.band_name

    band_name = models.CharField(max_length=100)
4

2 回答 2

1

鉴于您的评论,您实际上可能需要选择相关的记录及其乐队。像这样:

class ReviewAdmin(admin.ModelAdmin):
    model = Review
    def queryset(self, request):
        return super(ReviewAdmin, self).queryset(request).select_related('record', 'record__band')

class RecordAdmin(admin.ModelAdmin):
    model = Record
    def queryset(self, request):
        return super(RecordAdmin, self).queryset(request).select_related('band')

使用Django 工具栏是发现正在运行的查询的好方法。

于 2013-01-26T21:26:35.950 回答
1

您需要select_related在管理站点创建更改表单时注入。您可以通过覆盖ModelAdmin.formfield_for_foreignkey您的 ModelAdmin 来做到这一点。像这样的东西:

class ReviewAdmin(admin.ModelAdmin):
    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "record":
            kwargs["queryset"] = Record.objects.all().select_related()

        return super(ReviewAdmin, self).formfield_for_foreignkey(
            db_field, request, **kwargs)
于 2015-07-02T20:02:40.390 回答