Django MultipleChoiceField不保留所选值的顺序

oma*_*mat 4 django django-forms cleaned-data

我有一个Django ModelForm,它通过一个模型来公开对应于多对多关系的多选字段,该模型将order选择(文档列表)作为额外属性.在前端,该字段显示为两个与admin中类似的多个选择字段,一个列出可用选项,另一个列出所选元素.

可以使用正确的元素选择保存表单,但它们始终按原始选择顺序排列,而不是选择顺序.浏览器以正确的顺序发送选择,但顺序输入form.cleaned_data['documents']始终是原始顺序的顺序.

如何使MultipleChoiceField尊重所选元素的顺序?

谢谢.

tic*_*cky 5

没有简单的方法.您需要覆盖或的clean方法MultipleChoiceField,如您在评论中提到的,使用getlist手动重新排序.这可能取决于您需要在代码中执行的频率.

通过像这样通过运算符过滤对象列表来创建您正在接收的clean方法,因此顺序由数据库给出:MultipleChoiceFieldQuerySetIN

qs = self.queryset.filter(**{'%s__in' % key: value})
Run Code Online (Sandbox Code Playgroud)

您可以继承自ModelMultipleChoiceField:

class OrderedModelMultipleChoiceField(ModelMultipleChoiceField):
    def clean(self, value):
        qs = super(OrderedModelMultipleChoiceField, self).clean(value)
        return sorted(qs, lambda a,b: sorted(qs, key=lambda x:value.index(x.pk)))
Run Code Online (Sandbox Code Playgroud)

缺点是返回的值不再是QuerySet普通列表.

  • +1加上`sorted(qs, key=lambda x:value.index(x.pk))`更短 (2认同)