Opened 14 years ago
Closed 14 years ago
#17740 closed Bug (needsinfo)
BaseModelFormSet should use its queryset when initializing the ModelForm's pk_field's ModelChoiceField.
| Reported by: | larsent | Owned by: | larsent |
|---|---|---|---|
| Component: | Forms | Version: | 1.3 |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
BaseModelFormSet uses the queryset of the default model manager when creating the ModelChoiceField for the model's pk_field.
Line 656:
if isinstance(pk, OneToOneField) or isinstance(pk, ForeignKey):
qs = pk.rel.to._default_manager.get_query_set()
else:
qs = self.model._default_manager.get_query_set()
qs = qs.using(form.instance._state.db)
form.fields[self._pk_field.name] = ModelChoiceField(qs, initial=pk_value, required=False, widget=HiddenInput)
The ModelFormSet will not validate if it is initialized with a queryset containing objects that are not in the model's default manager's queryset.
Change History (2)
comment:1 by , 14 years ago
comment:2 by , 14 years ago
| Resolution: | → needsinfo |
|---|---|
| Status: | new → closed |
Let me elaborate a bit on the bug report; it's terse and it took me a while to figure out what's going on.
BaseModelFormSet.add_fields(self, form, index) adds a field that contains the primary key to form. This field is invisible to the end user -- it uses a HiddenInput widget -- but it's necessary for Django to know which instance of the model form deals with, when it received the contents of form in the next request. Django uses a ModelChoiceField for this extra field: this makes sense for designating which instance the form applies to, among all existing instances of the model.
"All existing instances of the model" is qs = self.model._default_manager.get_query_set(). By definition -- and unless I missed something -- this queryset always contains all instances of the model. Could you explain how it's possible for your custom_manager to contain an object that isn't in _default_manager?
Code to reproduce this: