【问题标题】:Django form to save m2m additional fields (using custom through/intermediary model)Django 表单保存 m2m 附加字段(使用自定义直通/中介模型)
【发布时间】:2020-07-11 20:11:55
【问题描述】:

我有一个“Parent”模型,其中包含多个“Child”模型,并且 Parent 和 Child 之间的关系持有孩子的顺序。因此,我需要一个自定义的中介模型。

models.py:

class Parent(models.Model):
    name = models.CharField
    children = models.ManyToManyField(Child, through=ParentChild)
    ...

class Child(models.Model):
    name = models.CharField()
    ...

class ParentChild(model.Model):
    parent = models.ForeignKey(Parent, on_delete=models.CASCADE)
    child = models.ForeignKey(Child, on_delete=models.CASCADE)
    order_of_child = IntegerField(null=True, blank=True, unique=True, default=None) 

父对象是基于表单创建的,并且要成为父对象一部分的子对象由复选框选择。 现在我的问题是:如何将 order_of_child 包含在表单中并与复选框一起呈现,以及如何将关系正确保存在视图中?

forms.py:

class ParentForm(ModelForm):

    class Meta:
        model = Parent
        fields = ['name', 'children']

    def __init__(self, *args, **kwargs):
        super(ParentForm, self).__init__(*args, **kwargs)
        self.fields['name'] = forms.CharField(label='Name', widget=forms.TextInput()
        self.fields['children'] = ModelMultipleChoiceField(
                                      widget=forms.CheckboxSelectMultiple(queryset=Child.objects.all())

【问题讨论】:

    标签: django forms save many-to-many m2m


    【解决方案1】:

    要保存关系,您只需先创建并保存Parent,然后循环通过form.cleaned_data['children'] 创建每个ParentChild 实例,将循环的索引分配为顺序。

    现在对于订单,这更加棘手,您需要一个允许您重新排序选择的小部件,因此默认的 CheckboxSelectMultiple 将不起作用,因为它不会这样做。为此,您需要一些 javascript:将选定的选项复制到一个新的 div 中,用户可以在其中拖放以更改顺序,例如使用诸如jquery.ui.sortablesortableJS/sortable 之类的库。使用 javascript,您可以以正确的顺序使用所选值填充隐藏字段,这就是您最终提交的内容。

    还有一个特殊的 django sortable multiselectfield 包我没有尝试过(使用 jqueryUI 进行排序)。

    【讨论】:

      最近更新 更多