При использовании ModelChoiceField в формах Django я хочу отображать только подмножество данных (в моем случае последние 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
При определении поля формы я теперь могу предоставить 2 набора запросов, один из которых будет проверяться отправленными данными, а другой будет отображаться.
class MyForm(Form):
some_option = SubsetModelChoiceField(queryset=MyModel.objects.all(),
subset_queryset=MyModel.objects.all()[:100],)
Это работает нормально, однако возникает проблема с удобством использования. Когда пользователь выбирает параметр, не отображаемый по умолчанию, но другое поле формы приводит к тому, что связанная форма не проходит проверку, то при перезагрузке страницы параметр, выбранный пользователем, не будет предварительно выбран, поскольку он не найден в «subset_queryset».
Кто-нибудь знает, как я могу это решить?
Спасибо.