使用Django的ModelChoiceField显示数据子集和绑定数据

0 投票
1 回答
1102 浏览
提问于 2025-04-16 18:15

在使用Django表单中的ModelChoiceField时,我只想显示一部分数据(在我的例子中是最后100条记录),因为数据集非常大。同时,我希望用户仍然能够从数据库中的任何对象中进行选择,而不仅仅是默认显示的那些(我使用AJAX来查询未默认显示的选项)。

我通过继承ModelChoiceField和ModelChoiceIterator成功实现了这一点。

class SubsetModelChoiceIterator(ModelChoiceIterator):
    def __init__(self, field):
        self.field = field
        self.queryset = field.subset_queryset

class SubsetModelChoiceField(forms.ModelChoiceField):
    """
    This is just like a ModelChoiceField, but only a subset of the full
    queryset will be displayed as choices.
    """

    def __init__(self, subset_queryset, *args, **kwargs):
        self.subset_queryset = subset_queryset
        super(SubsetModelChoiceField, self).__init__(*args, **kwargs)

    def _get_choices(self):
        if hasattr(self, '_choices'):
            return self._choices

        return SubsetModelChoiceIterator(self)
    choices = property(_get_choices, forms.ChoiceField._set_choices)

    def _get_subset_queryset(self):
        return self._subset_queryset

    def _set_subset_queryset(self, queryset):
        self._subset_queryset = queryset
        self.widget.choices = self.choices

在定义表单字段时,我现在可以提供两个查询集,一个用于验证提交的数据,另一个用于显示。

class MyForm(Form):
    some_option = SubsetModelChoiceField(queryset=MyModel.objects.all(),
                                         subset_queryset=MyModel.objects.all()[:100],)

这个方法运行得很好,但出现了一个可用性问题。当用户选择了一个默认未显示的选项,但另一个表单字段导致绑定的表单验证失败时,页面重新加载后,用户选择的选项将不会被预选,因为它不在“subset_queryset”中。

有没有人知道我该如何解决这个问题?

谢谢。

1 个回答

0

这其实不是一个关于Django的问题。最好的办法是把列表状态的信息存储在一个隐藏字段里(不一定是列表里的项目,而是你需要知道如何再次获取这些项目的信息)。然后,把这些信息传回模板,利用你的AJAX功能再去获取这些项目。

撰写回答