Opened 18 years ago
Closed 18 years ago
#6162 closed (fixed)
ModelForm.__init__() should match argument signature of "standard" forms
| Reported by: | James Bennett | Owned by: | nobody |
|---|---|---|---|
| Component: | Forms | Version: | dev |
| Severity: | Keywords: | modelform | |
| Cc: | Triage Stage: | Design decision needed | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
Currently, ModelForm.__init__() differs from the __init__() of a "standard" newforms form in two ways:
- It requires an instance of the model to be passed in, and cannot fall back to a default.
- It requires this to be the first positional argument, while on "standard" forms the first positional argument is
data.
A number of use cases -- particularly generic form-handling code -- would be made much simpler if instead instance was optional (with ModelForm falling back to creating an instance based on _meta.model if it's not supplied), and if it was moved further back in the list of arguments so as to allow code to work with the standard argument signature of BaseForm.__init__() as much as possible.
Attachments (2)
Change History (5)
by , 18 years ago
| Attachment: | modelform-init.diff added |
|---|
follow-up: 2 comment:1 by , 18 years ago
| Triage Stage: | Unreviewed → Design decision needed |
|---|
New patch ensures that a ModelForm without a model or instance throws an error, and tests and documents the now-possible case of a ModelForm working with any of multiple models at runtime.
Discussion for anyone who's only watching here is taking place on django-dev.
comment:2 by , 18 years ago
I think the below code block which is for form.save method in meta class should be changed.
# Don't allow more than one Meta model defenition in bases. The fields
# would be generated correctly, but the save method won't deal with
# more than one object.
base_models = []
for base in bases:
base_opts = getattr(base, '_meta', None)
base_model = getattr(base_opts, 'model', None)
if base_model is not None:
base_models.append(base_model)
if len(base_models) > 1:
raise ImproperlyConfigured("%s's base classes define more than one model." % name)
# If a model is defined, extract form fields from it and add them to base_fields
if attrs['_meta'].model is not None:
# Don't allow a subclass to define a Meta model if a parent class has.
# Technically the right fields would be generated, but the save
# method will not deal with more than one model.
for base in bases:
base_opts = getattr(base, '_meta', None)
base_model = getattr(base_opts, 'model', None)
if base_model is not None:
raise ImproperlyConfigured('%s defines more than one model.' % name)
model_fields = fields_for_model(opts.model, opts.fields, opts.exclude)
# fields declared in base classes override fields from the model
model_fields.update(declared_fields)
attrs['base_fields'] = model_fields
else:
attrs['base_fields'] = declared_fields
return type.__new__(cls, name, bases, attrs)
(Maybe I should send a patch here, but I am not familiar to patch tool. I will learn it soon...)
Remove those checks, will make mulitiple inherit from ModelForm possible.
Thanks.
comment:3 by , 18 years ago
| Resolution: | → fixed |
|---|---|
| Status: | new → closed |
Patch which "fixes"
ModelForm.__init__()