How to change the default widget for all built-in form fields of a certain type in Django?

This Continuation How do I change the default widget for all Django date fields in ModelForm? .

Suppose you have a very large number of models (for example, A-ZZZ) that grow with other developers that are beyond your control, and you want to change the way you enter all the date fields (for example, using jQueryUI). What is the best way to ensure that all date fields are populated with this new widget?

One of the suggested questions:

def make_custom_datefield(f): if isinstance(f, models.DateField): # return form field with your custom widget here... else: return f.formfield() class SomeForm(forms.ModelForm): formfield_callback = make_custom_datefield class Meta: # normal modelform stuff here... 

However, is this possible when you do not have an explicit ModelForm, but url patterns are taken from models directly? those. your url configuration makes sense:

 url(r'^A/?$', 'list_detail.object_list', SomeModelA) 

where SomeModelA is a model (not a form) that turned into a ModelForm by Django in the background.

There are currently no Forms for each model in my system. The only time you create forms would obviously be to add formfield_callback, as proposed in the previous solution, but this is contrary to DRY principles and will be error-prone and time-consuming.

I considered (as suggested in the last thread) the creation of my own field, which has a special widget and uses it instead of the built-in one. This is not so time consuming, but it can be error prone (nothing could fix a good grep).

Suggestions and thoughts are welcome.

+4
source share
1 answer

It looks like you want to do this throughout the project (i.e. you are not trying to do this in some cases, but in ALL cases in your running application).

One possibility is to replace the widget attribute of the DateField class itself. You will need to do this in some central place ... something that is guaranteed to be loaded by every running instance of the django application. Middleware can help with this. Otherwise, just put it in the __init__ file of your application.

What you want to do is override the widget property for the forms.DateField class itself. When a new DateField is created, Django checks to see if the code points to a specific widget in the field property definition. If not, the default value for DateField is used. I assume that if the user in your script really defined a specific widget, you would like to make sure that despite changing your global API,

Try this as an example of forced default for another widget ... in this case HiddenInput:

 from django import forms forms.DateField.widget = forms.HiddenInput class Foo(forms.Form): a = forms.DateField() f = Foo() print f.fields['a'].widget # results in <django.forms.widgets.HiddenInput object at 0x16bd910> 
+7
source

All Articles