Django在表单中使用多对多和Through

Django在表单中使用多对多和Through,django,django-models,django-forms,django-related-manager,Django,Django Models,Django Forms,Django Related Manager,我有一个数据模型,其中我使用一个手动中间表来处理m2m关系。 基于django文档中的经典示例: from django.db import models INSTRUMENT_CHOICES = ( ('guitar', 'Guitar'), ('bass', 'Bass Guitar'), ('drum', 'Drum'), ('keyboard', 'Keyboard'), ) class Person(models.Model): name =

我有一个数据模型,其中我使用一个手动中间表来处理m2m关系。 基于django文档中的经典示例:

from django.db import models

INSTRUMENT_CHOICES = (
    ('guitar', 'Guitar'),
    ('bass', 'Bass Guitar'),
    ('drum', 'Drum'),
    ('keyboard', 'Keyboard'),
)

class Person(models.Model):
    name = models.CharField(max_length=128)

    def __str__(self):
        return self.name

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, through='Leadership')

    def __str__(self):
        return self.name

    def get_leadership():
        return self.leadership_set.first()


class Leadership(models.Model):
    person = models.ForeignKey(Person, on_delete=models.CASCADE)
    group = models.ForeignKey(Group, on_delete=models.CASCADE)
    instrument = models.CharField('Playing Instrument', choices=INSTRUMENT_CHOICES, 
                                   max_length=15, 
                                   null=True, 
                                   blank=False)
    class Meta:
        unique_together = ('person', 'group')
当我创建一个新的团队时,我还想指定谁将成为领导者,对于这种关系,我还要指定他将在该团队中演奏哪种乐器

考虑到缺乏关于这个主题的文档,真正让我困惑的是如何在表单中处理这种关系

这是我随附的表格:

class InstrumentField(forms.ChoiceField):
    def __init__(self, *args, **kwargs):
        super().__init__(INSTRUMENT_CHOICES, *args, **kwargs)


class GroupForm(forms.ModelForm):
    instrument = InstrumentField(required=False)

    class Meta:
        model = Group
        fields = ['name', 
                  'members'
                  'instrument']  # This works but it's not correctly initalized in case of edit form
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if self.instance.pk is not None:  # editing 
            # PROBLEM: this doesn't work
            self.fields["instrument"].initial = self.instance.get_leadership().instrument

    def save(self, commit=True):
        group = super().save(commit=False)
        if commit:
            group.save()
            if 'instrument' in self.changed_data:
                leader = self.cleaned_data.get('members').first()  
                instrument = self.cleaned_data['instrument']

                Leadership.objects.update_or_create(person=leader, group=group, defaults={'instrument': instrument})

        return group
正如django文档中所建议的,我正在手动实例化
Leadership
对象(请参见表单
save
方法)

我无法解决的是在表单编辑时如何填充
instrument
字段。我尝试在
\uuu init\uuuu
中这样做:首先我检查我们是否处于“编辑”模式(实例有一个pk),然后我得到相关的
Leadership
对象(请参见
组。get\u Leadership
),然后从中提取
工具
,并将其分配给
字段[“instrument”]。initial

这不管用

我可以检查是否设置了
初始值
,但是当我呈现表单时,会显示默认的选择值(仪器选项的第一个值)

我错过了什么? 关于如何通过表单中的模型处理m2m,是否有更好的方法或更好的文档