2010-06-24 50 views
3

我们有一个包含报纸文章列表的Django应用程序。每篇文章与“发言人”以及“公司”(文章中提到的公司)都有M2M关系。Django Admin - 显示M2M模型的中介字段

目前,用于创建新文章的添加文章页面与我们想要的非常接近 - 它只是股票的Django Admin,我们使用filter_horizo​​ntal来设置两个m2m关系。

下一步是在每个m2m关系上添加一个“评级”字段作为中介字段。

所以,我们models.py的例子

class Article(models.Model): 
    title = models.CharField(max_length=100) 
    publication_date = models.DateField() 
    entry_date = models.DateField(auto_now_add=True) 
    abstract = models.TextField() # Can we restrict this to 450 characters? 
    category = models.ForeignKey(Category) 
    subject = models.ForeignKey(Subject) 
    weekly_summary = models.BooleanField(help_text = 'Should this article be included in the weekly summary?') 
    source_publication = models.ForeignKey(Publication) 
    page_number = models.CharField(max_length=30) 
    article_softcopy = models.FileField(upload_to='article_scans', null=True, blank=True, help_text='Optionally upload a soft-copy (scan) of the article.') 
    url = models.URLField(null=True, blank=True, help_text = 'Enter a URL for the article. Include the protocl (e.g. http)') 
    firm = models.ManyToManyField(Firm, null=True, blank=True, through='FirmRating') 
    spokesperson = models.ManyToManyField(Spokeperson, null=True, blank=True, through='SpokespersonRating') 

    def __unicode__(self): 
     return self.title 

class Firm(models.Model): 
    name = models.CharField(max_length=50, unique=True) 
    homepage = models.URLField(verify_exists=False, help_text='Enter the homepage of the firm. Include the protocol (e.g. http)') 

    def __unicode__(self): 
     return self.name 

    class Meta: 
     ordering = ['name'] 

class Spokeperson(models.Model): 
    title = models.CharField(max_length=100) 
    first_name = models.CharField(max_length=50) 
    last_name = models.CharField(max_length=50) 

    def __unicode__(self): 
     return self.first_name + ' ' + self.last_name 

    class Meta: 
     ordering = ['last_name', 'first_name'] 

class FirmRating(models.Model): 
    firm = models.ForeignKey(Firm) 
    article = models.ForeignKey(Article) 
    rating = models.IntegerField() 

class SpokespersonRating(models.Model): 
    firm = models.ForeignKey(Spokesperson) 
    article = models.ForeignKey(Article) 
    rating = models.IntegerField() 

这里的问题是,一旦我们改变我们的企业和发言人字段为“通过”,并使用中介机构,我们添加文章页面不再有filter_horizo​​ntal控制添加公司/ Spokeperson关系到文章 - 他们完全消失。你根本看不到他们。我不知道这是为什么。

我希望有一些方法可以继续使用cool filter_horizo​​ntal小部件来设置关系,并以某种方式嵌入另一个字段下面的设置评分。不过,我不确定如何做到这一点,同时仍然利用Django管理员。

我看到了一个书面记录这里关于Django管理覆盖一个Widget:

http://www.fictitiousnonsense.com/archives/22

不过,我不知道这方法仍然是有效的,而且我不知道它应用到这里,用一个FK到一个中间模型(它基本上是一个内联呢?)。

当然,这样做有一个简单的方法吗?

干杯, 维克多

回答

7

的问题是管理的方法formfield_for_manytomanydjango.contrib.admin.options不与中介模型多对多字段返回一个表单字段! http://code.djangoproject.com/browser/django/trunk/django/contrib/admin/options.py#L157

你将不得不重写你的ModelAdmin这个方法:

def formfield_for_manytomany(self, db_field, request=None, **kwargs): 
    """ 
    Get a form Field for a ManyToManyField. 
    """ 
    # If it uses an intermediary model that isn't auto created, don't show 
    # a field in admin. 
    if not db_field.rel.through._meta.auto_created: 
     return None # return something suitable for your needs here! 
    db = kwargs.get('using') 

    if db_field.name in self.raw_id_fields: 
     kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel, using=db) 
     kwargs['help_text'] = '' 
    elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)): 
     kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical)) 
+0

嗯,所以我需要以某种方式重写此方法,在不破坏任何一个通用的方法?呃,我的Django知识在这里有点欠缺。人们通常如何使用Django管理员编辑中介模型? – victorhooi 2010-06-24 22:54:27

+0

你只需要为你的字段覆盖它,你可以在那里放入'if db_field.name =='my_field'! – 2010-06-25 01:34:11

相关问题