Django Admin - отображение посредников для моделей M2M
Вопрос
У нас есть приложение Django, которое содержит список газетных статей. Каждая статья имеет отношения M2M с «представителями», а также «фирмой» (компания, упомянутая в статье).
На данный момент страница «Добавить статью» для создания новых статей довольно близко к тому, что мы хотим - это просто акция Django Admin, и мы используем Filter_horizontal для установки двух отношения M2M.
Следующим шагом было добавить поле «Рейтинг» в качестве посредника в каждом отношениях M2M.
Итак, пример наших моделей .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 для добавления отношений фирм / SpeCeperson для статьи - они полностью исчезают. Вы не можете видеть их вообще. Я понятия не имею, почему это.
Я надеялся, что должен быть какой-то способ сохранить прохладный виджет Filter_Horizontal, чтобы установить отношения, и как-то просто встроить другое поле ниже, что для настройки рейтинга. Тем не менее, я не уверен, как это сделать, пока все еще использует админ Джанго.
Здесь я видел переписку здесь о переопределении одного виджета в Django Admin:
http://www.fictitivenonsense.com/Чахивы/22.
Тем не менее, я не уверен, что этот метод все еще действителен, и я не уверен в том, чтобы применить его здесь, с FK к посреднической модели (в основном это встроенный тогда?).
Конечно, есть простой способ сделать все это?
Ура, Виктор
Решение
Проблема в том, что метод админа formfield_for_manytomany
в django.contrib.admin.options
Не возвращает поле формы для MultiTomany полей со посреднической моделью! 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))