我正在显示一个modelformset,我希望表单通过其字段之一的内容进行排序。因此,我想对SomeModel.objects.filter(whatever).order_by('somefield')模板中的(模型)formset 使用等效项。
我怎样才能做到这一点?
请注意,can_order它并不能满足我的要求(它必须是自动的,不是用户指定的)。我也尝试过其他事情,例如dictsort过滤器,但是会产生不可预测的输出(即未按指定字段排序)。
我什至尝试过{% regroup formset by somefield as sorted_formset %},但是结果sorted_formset不能用作(重复)正常的形式集。
完成答案。有两种方法可以控制表单集中表单的顺序:表单集尊重给定查询集的顺序(这在其他回复中显示)。另一种方法(如果您想完全控制表单的顺序)是定义自定义表单集类和覆盖__iter__和__getitem__方法:
from django.forms import BaseModelFormSet
class MyModelBaseFormset(BaseModelFormSet):
def __iter__(self):
"""Yields the forms in the order they should be rendered"""
return ...
def __getitem__(self, index):
"""Returns the form at the given index, based on the rendering order"""
return ...
MyModelFormset = modelformset_factory(model=MyModel, formset=MyModelBaseFormset, queryset=...)
Run Code Online (Sandbox Code Playgroud)
这种方法在 Django 文档中有所描述:
迭代表单集将按照它们创建的顺序呈现表单。您可以通过为该
__iter__()方法提供替代实现来更改此顺序。表单集也可以被索引,它返回相应的表单。如果您覆盖
__iter__,您还需要覆盖__getitem__以具有匹配的行为。
https://docs.djangoproject.com/en/dev/topics/forms/formsets/#django.forms.formsets.BaseFormSet
实现这些方法的示例例如在此 SO 线程中:modelformset __iter__ 重载问题。
如果你没有定义 Formset,这是“内联代码”版本:
FS=inlineformset_factory(ParentClass,ChildClass)
formset=FS(instance=parentobject,
queryset=parentobject.childobject_set.order_by("-time_begin")
)
Run Code Online (Sandbox Code Playgroud)
感谢@john-peters 上面的回答,为我指明了正确的方向。但这里有一个更好的方法:
MyFormset(inlineformset_factory(...)):
def get_queryset(self):
return super(MyFormset, self).get_queryset().order_by('myfieldname')
Run Code Online (Sandbox Code Playgroud)
这样你就不必复制或弄乱 django 的代码,也不必在路上造成故障..只需采用 django 给你的查询集并覆盖排序。我在自己的代码中使用了它,它有效。
编辑。在对此进行了一些研究后,我意识到虽然它看起来工作正常,但它以某种方式混淆了 BaseInlineFormset.get_queryset() 中的逻辑,导致重复的数据库查询。但是,希望有人对此发表评论并纠正它,我将其保留在这里。同时,我有另一个解决方案,它确实有效并且不会导致冗余查询..如下:
MyFormset(inlineformset_factory(...)):
def __init__(self, *args, **kwargs):
super(MyFormset, self).__init__(*args, **kwargs)
self.queryset = self.queryset.order_by('myfieldname')
Run Code Online (Sandbox Code Playgroud)
这会在安全时间修改查询集,然后再对其进行任何处理。在我的代码中,我也在此处执行 .select_related() ,这大大加快了我的大型模型集!
| 归档时间: |
|
| 查看次数: |
4137 次 |
| 最近记录: |