Opened 9 years ago
Last modified 3 years ago
#26369 new New feature
Allow override of hardcoded defaults in model Field.formfield()
Reported by: | James Pic | Owned by: | |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.9 |
Severity: | Normal | Keywords: | |
Cc: | James Pic, hv@…, Kevin Brown | Triage Stage: | Someday/Maybe |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | yes |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Currently, the model field builds the default form field that's used
by the modelform metaclass in Field.formfield(). It uses hardcoded defaults which it would be nice to be able to override with attributes.
Example patch: https://github.com/jpic/django/commit/d102f362f3c1ceaf2d5224d71f788c0821a481ae
This patch allows to use Radio widget by default for a OneToOne field:
class TestModel(models.Model): name = models.CharField(max_length=200) test = models.OneToOneField( 'self', null=True, blank=True, related_name='related_test_models', # This seems like it would always be useful formfield_defaults={ 'widget': forms.RadioSelect } )
Change History (11)
comment:1 by , 9 years ago
Description: | modified (diff) |
---|
comment:2 by , 9 years ago
Cc: | added |
---|
comment:3 by , 9 years ago
Component: | Forms → Database layer (models, ORM) |
---|---|
Type: | Cleanup/optimization → New feature |
comment:4 by , 9 years ago
Triage Stage: | Unreviewed → Someday/Maybe |
---|
comment:5 by , 9 years ago
Cc: | added |
---|
comment:6 by , 9 years ago
I guess I understood what you want.
I see this problem: A django projects is a container for N apps.
Since there are N apps, and not just one: Who is allowed to provide defaults?
Yes, we already do change the default widgets. We use monkey patching: We modify the django classes. That is not a nice way, but works.
Yes, I would like to have an official solution, too.
comment:7 by , 9 years ago
Cc: | added |
---|
comment:8 by , 8 years ago
Has patch: | set |
---|---|
Owner: | changed from | to
Patch needs improvement: | set |
Status: | new → assigned |
comment:9 by , 8 years ago
I'm unsure if I wouldn't prefer to just be able to define a project-level default formfield callback, because that's going to depend on what the INSTALLED_APPS provide. Then for example, to make all relations to Foo a particular widget instead of Select, and to make all CharFields have a text field:
# settings.py: DEFAULT_FORMFIELD='project.forms.project_formfield' # project/forms.py def project_formfield(db_field, form_class, defaults): if db_field.rel.to == Foo: defaults['widget'] = forms.RadioSelect if db_field.model == Foo and isinstance(db_field, models.CharField): defaults['widget'] = forms.Textarea return form_class(**defaults)
This seems even more powerful, anybody would like to take a look at such an implementation ?
comment:10 by , 3 years ago
This has been implemented in a third party, while not relying on supported APIs, remains sufficiently short (35 SLOCs) to be maintenable.
comment:11 by , 3 years ago
Owner: | removed |
---|---|
Status: | assigned → new |
I'm not sure whether or not to accept this, so I raised it on the django-developers mailing list.