题
我们有一个Django应用程序,它包含一系列的报纸上的文章。每篇文章都有一个m2m的关系一"发言人",以及"公司"(公司所提到的文章)。
目前,添加文网页创建新的条款是相当接近我们想要什么-这只是股Django管理,我们正在使用filter_horizontal用于设置两个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_horizontal控制,以增加公司/Spokeperson关系的文章--它们完全消失。你可以不见他们。我不知道这是为什么。
我希望有以某种方式继续使用酷filter_horizontal部件设置的关系,并在某种程度上只是嵌入的另一个领域下面,用于设置的评价。然而,我不知道该如何做到这一点,同时仍然充分利用Django管理。
我看到一个书面记录在这里,大约复盖的单个部件在Django管理:
http://www.fictitiousnonsense.com/archives/22
然而,我不知道,如果这一方法仍然有效,我不确定关于申请到这里,与一个FK到中介模式(它基本上是一个内联然后?).
肯定有一个简单的方式做这一切?
干杯, 维克多
解决方案
问题是,该管理员的方法 formfield_for_manytomany
在 django.contrib.admin.options
不返回的形式领域manytomany领域的中介模型! 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))