我有一个Django的ModelForm它通过持有一个模型公开对应于许多一对多关系的选择题场order
选择的(一个文件列表)作为额外的属性。 在前端,该字段被显示为两个多重选择字段中管理的相似,一个列出可用的选择,而另一个保持选定的元素。
该表格可以保存的元素的正确选用,但他们总是在选择原来的顺序,而不是选择的顺序。 浏览器将在正确的顺序选择,但为了form.cleaned_data['documents']
总是在选择原订单的订单。
我怎样才能让MultipleChoiceField尊元素的顺序选择?
谢谢。
有没有简单的方法。 你要么需要重写clean
的方法MultipleChoiceField
或者,当你在你的评论中提到,使用的GetList手动重新订购。 这可能取决于你的代码,你需要多久做。
该clean
的方法MultipleChoiceField
创建QuerySet
您收到,通过经由过滤对象列表IN
操作者这样的,所以为了由数据库给出:
qs = self.queryset.filter(**{'%s__in' % key: value})
您可以从继承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)))
其缺点是,返回值不再是一个QuerySet
,但一个普通的列表。
要重写清洁方法也可以做到这一点时,返回的有序查询集:
class OrderedModelMultipleChoiceField(ModelMultipleChoiceField):
def clean(self, value):
qs = super(OrderedModelMultipleChoiceField, self).clean(value)
clauses = ' '.join(['WHEN id=%s THEN %s' % (pk, i) for i, pk in enumerate(value)])
return qs.filter(pk__in=value).extra(
select={'ordering': 'CASE %s END' % clauses},
order_by=('ordering',)
)
我通过一个Widget做到了。 它的好处是,它会在不同的语言正确排序:
class SortedSelectMultiple(SelectMultiple):
def render_options(self, selected_choices):
self.choices = sorted(self.choices)
self.choices.sort(key=lambda x: x[1])
return super(SortedSelectMultiple, self).render_options(selected_choices)