Search code examples
pythondjangowidgetcustom-field-type

When is the formfield() method called in Django?


This is a question on making custom fields in Django. I'm making a field called EditAreaField, which inherits from TextField. Here's what my code looks like:

class EditAreaField(models.TextField):
    description = "A field for editing the HTML of a page"
    def formfield(self, **kwargs):
        defaults = {}
        defaults['widget'] = EditArea() # setting a new widget
        defaults.update(kwargs)
        return super(EditAreaField, self).formfield(**defaults)

On the 5th line, I'm assigning a custom widget to this field. On line 6, I update the parameters.

The problem is, Django sends a parameter widget that's set to django.contrib.admin.widgets.AdminTextareaWidget, which overrides my EditArea() widget.

How can I change the value that Django is setting? Obviously I could just override their setting by switching lines 5 and 6, so my code looks like:

        defaults.update(kwargs)
        defaults['widget'] = EditArea() # override django here

But is that really the best way to do it?

As a side note, I couldn't find documentation on the formfield() function anywhere on Django's site: is it deprecated?


Solution

  • It looks like the formfield method is called by the ModelForm helper. According to the docs, the formfield method should include only a form_class attribute to point to the formfield class for this custom model field. This is a custom (or default) form field class, which is where the default widget is defined

    from myapp.forms import MyCustomFormField
    
    #create a custom model field
    class EditAreaField(models.TextField):
      def formfield(self, **kwargs):
        defaults={'form_class': MyCustomFormField}#pass our custom field as form_class
        defaults.update(kwargs)
        return super(EditAreaField, self).formfield(**defaults)