Django admin list_display与父级相反

时间:2015-11-28 05:48:26

标签: django

我有2个型号:

1:KW(个别关键字)

2:项目(许多关键字可以属于许多不同的项目)

class KW(models.Model):
    ...
    project = models.ManyToManyField('KWproject', blank=True)

class KWproject(models.Model):
    ProjectKW = models.CharField('Main Keyword', max_length=1000)
    author = models.ForeignKey(User, editable=False)

现在,当用户在 KWproject 的管理员中时,他们应该能够在list_display中看到属于所选项目的所有关键字。我实现了这一点,但感觉不是正确的方式。

class ProjectAdmin(admin.ModelAdmin):
    form = ProjectForm
    list_display = ('Keywordd', 'author')

    def Keywordd(self, obj):
        return '<a href="url.co/admin/keywords/kw/?project__id__exact=%s&o=2&q=">%s</a>' % (obj.id, obj.ProjectKW)
    Keywordd.allow_tags = True
    Keywordd.admin_order_field = 'ProjectKW'
    Keywordd.short_description = 'ProjectKW'

是否有更好的方法来链接,然后 list_display 所有与模型有反向关系的项目? (通过我的例子中的“项目”字段)

1 个答案:

答案 0 :(得分:0)

根据Django Admin docs

  

不支持ManyToManyField字段,因为这将需要   为表中的每一行执行单独的SQL语句。如果你   尽管如此,还是要为您的模型提供自定义方法,然后添加   该方法的名称为list_display。 (有关定制的更多信息,请参阅下文   list_display中的方法。)

因此,您可以选择实现类似的自定义模型方法:

# models.py
class KW(models.Model):
    ...
    project = models.ManyToManyField('KWproject', blank=True)

class KWproject(models.Model):
    ProjectKW = models.CharField('Main Keyword', max_length=1000)
    author = models.ForeignKey(User, editable=False)

    def all_keywords(self):
        # Retrieve your keywords
        # KW_set here is the default related name. You can set that in your model definitions.
        keywords = self.KW_set.values_list('desired_fieldname', flat=True)
        # Do some transformation here
        desired_output = ','.join(keywords)
        # Return value (in example, csv of keywords)
        return desired_output

然后,将该模型方法添加到ModelAdmin中的list_display元组。

# admin.py
class ProjectAdmin(admin.ModelAdmin):
    form = ProjectForm
    list_display = ('Keywordd', 'author', 'all_keywords')

    def Keywordd(self, obj):
        return '<a href="url.co/admin/keywords/kw/?project__id__exact=%s&o=2&q=">%s</a>' % (obj.id, obj.ProjectKW)
    Keywordd.allow_tags = True
    Keywordd.admin_order_field = 'ProjectKW'
    Keywordd.short_description = 'ProjectKW'

请注意:这可能是非常昂贵的操作。如果在列表中显示200行,则对页面的请求将执行200个额外的SQL查询。