Когато използвам 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“.
Някой има ли идея как мога да разреша това?
Благодаря.