django admin编辑模型select / prefetch_related?

时间:2017-10-15 14:23:31

标签: django django-admin

我有一个Django网站,模型Event,让我们说:

class Event(models.Model):
    home = models.ForeignKey('Team', related_name='%(class)s_home')
    away = models.ForeignKey('Team', related_name='%(class)s_away')
    ...

class Team(models.Model):
    name = models.CharField("team's name", max_length=100)

使用ForeignKeys是一个坏主意,但无论如何,如何在Django Admin页面中使用它?
在管理编辑事件页面中,为此获取了大量外键:
http://127.0.0.1:8000/admin/event/event/116255/

它产生了大量的选择,如:
SELECT "event_team"."id", "event_team"."name" FROM "event_team" WHERE "event_team"."id" = 346;

并且页面已经死亡。我正在玩这些:

class EventAdmin(admin.ModelAdmin):
    list_display = ('id', 'home', 'away', 'date_game', 'sport', 'result')
    search_fields = ['home__name', 'away__name']
    list_select_related = (
        'home', 'away', 'league', 'sport', ...
    )

    def get_queryset(self, request):
        return super(EventAdmin, self).get_queryset(request).select_related(*self.list_select_related)
admin.site.register(Event, EventAdmin)

但没有运气。

3 个答案:

答案 0 :(得分:1)

最简单,最快捷的方式

在您的ModelAdmin(Django ModelAdmin.raw_id_fields documentation)上添加raw_id_fields

class EventAdmin(admin.ModelAdmin):
    raw_id_fields = ("home", "away")

这将导致带有FK字段ID的inputText,例如: Django ModelAdmin.raw_id_fields text Input example
加载速度很快,因为它不会填充所有团队的选择列表 由于浏览图标,您将拥有Team ModelAdmin的Django管理员change_view来选择团队。

更好的方式?

在UX方面更优雅,它要求您了解团队名称的一部分:使用ajax自动完成小部件来表示您的字段。

您可以使用例如Django Autocomplete Light (DAL) quick tutorial为您的管理员设置自定义表单,为autocompleteModelSelect2home字段设置away(在ajax中有2个不同的QS)视图)。
它将产生一个类似于:

的字段

DAL autocomplete ModelSelect2 widget example
这个链接的教程有你需要的一切!

或者您可以选择其他第三方插件或构建自己的字段/小部件以产生类似的结果。

答案 1 :(得分:0)

我发现了问题,这是我的错误,我甚至没有提到它:(

所以这是我的模型,但是我没有提到重要部分:

class Event(models.Model):
    home = models.ForeignKey('Team', related_name='%(class)s_home')
    away = models.ForeignKey('Team', related_name='%(class)s_away')
    merged = models.ForeignKey('Event', null='True', blank='True')
    def __unicode__(self):
        return str(self.id) + ": " + self.home.name + " - " + self.away.name

问题不在于homeaway,而在merged字段中,为每个事件提取了self.home.nameself.away.name

替换为

def __unicode__(self):
    return 'Event id: {}'.format(self.id)

并将merged添加到list_select_related 解决了我的问题。感谢您的帮助,对不完整的问题感到抱歉。

答案 2 :(得分:0)

我认为@ppython 的 answer 是最简单的,而且效果很好,但我最终使用了 autocomplete_fields 而不是 raw_id_fields。实现更友好的方法,从 Django 2.0 开始就可以使用了。

按照答案,它会是这样的:

class EventAdmin(admin.ModelAdmin):
    autocomplete_fields = ['home', 'away']