2015-11-28 194 views
0

我有2种型号:Django管理list_display反向于母公司

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) 

现在当用户在Admin的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有对模型的反向关系的所有项目? (通过我的例子“项目”字段)

回答

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 

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

# 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查询。