guettli
guettli

Reputation: 27816

Change default widgets of Django to custom ones

My usecase: I want to use a different DateInput. But I want to reduce code duplication. I want all forms, which don't explicitly want a different DateInput widget, to use my custom widget.

Any change to solve this without monkey patching?

Example

models.py:

class MyModel(models.Model):
    date=models.DateField()

forms.py:

class MyForm(forms.ModelForm):
    class Meta:
        model=MyModel

The above code should use my custom widget. I don't want to change the above models.py and forms.py, since there are many.

Upvotes: 5

Views: 2015

Answers (2)

awwester
awwester

Reputation: 10162

Unfortunately, I don't think you can get this working with your exact code listed above.

Without hacking django, essentially there are 2 parts to this. The first is creating a custom form field, and the second is defaulting your custom model field to your newly created form field.

To create your custom Form Field, you could override the existing django forms.DateField and update the widget.

# form_fields.py
from django.forms import DateField
from myapp.widgets import MyWidget

class MyDateFormField(DateField):
    widget = MyWidget

And then after you have your form field created, you're going to have to override the django model field to default to your new form field

# fields.py
from django.db.models import DateField
from myapp.form_fields import MyDateFormField

class MyDateField(DateField):
    def formfield(self, **kwargs):
        defaults = {'form_class': MyDateFormField}
        defaults.update(kwargs)
        return super(DateField, self).formfield(**defaults)

You would then have your custom model field, which you would need to slightly change your code to use.

from myapp.fields import MyDateField

class MyModel(models.Model):
    date=MyDateField()

It's not exactly what you were asking for (have to change the model field), but hopefully this gets you in the right direction.

Upvotes: 3

GwynBleidD
GwynBleidD

Reputation: 20539

  1. Create your field
  2. Create form that will use this field by default
  3. import this form instead of default form, when you use it

If you're using it in admin:

  1. create your own ModelAdmin that will use your form by default
  2. use that instead of default ModelAdmin.

Upvotes: -1

Related Questions