Редактирование обеих сторон M2M на странице администратора - PullRequest
7 голосов
/ 09 ноября 2009

Сначала я расскажу, чего я пытаюсь достичь, если есть другой способ сделать это!

Я хочу иметь возможность редактировать обе стороны отношения M2M (предпочтительно на странице администратора, хотя при необходимости это может быть на обычной странице), используя любой из интерфейсов множественного выбора.

Проблема, очевидно, связана с обратной стороной, так как главная сторона (где определены отношения) работает очень хорошо в автоматическом режиме.

Я попробовал некоторые из советов здесь, чтобы появился inline, и это работает, но это не очень хороший интерфейс.

Совет, который я получил в списке рассылки django, заключался в использовании пользовательской ModelForm. Я дошел до появления окна множественного выбора, но оно, похоже, не «связано» с чем-либо, так как не запускается с выбранным элементом и не сохраняет внесенные изменения.

Вот соответствующие фрагменты кода:

#models.py
class Tag(models.Model):
    name = models.CharField(max_length=200)

class Project(models.Model):
    name = models.CharField(max_length=200)
    description = models.TextField()
    tags = models.ManyToManyField(Tag, related_name='projects')

#admin.py
class TagForm(ModelForm):
    fields = ('name', 'projects')
    projects = ModelMultipleChoiceField(Project.objects.all(), widget=SelectMultiple())
    class Meta:
        model = Tag

class TagAdmin(admin.ModelAdmin):
    fields = ('name', 'projects')
    form = TagForm

Любая помощь будет принята с благодарностью: либо приведенный выше код для работы, либо предоставив лучший способ сделать это!

DavidM

1 Ответ

2 голосов
/ 09 ноября 2009

Причина, по которой ничего не происходит автоматически, заключается в том, что поле "projects" не является частью модели Tag. Что означает, что вы должны сделать всю работу самостоятельно. Что-то вроде (в TagForm):

def __init__(self, *args, **kwargs):
    super(TagForm, self).__init__(*args, **kwargs)
    if 'instance' in kwargs:
        self.fields['projects'].initial = self.instance.project_set.all()

def save(self, *args, **kwargs):
    super(TagForm, self).save(*args, **kwargs)
    self.instance.project_set.clear()
    for project in self.cleaned_data['projects']:
        self.instance.project_set.add(project)

Обратите внимание, что код не проверен, поэтому вам может понадобиться настроить его, чтобы он заработал.

...