Question

Let's suposse I have the following model:

class Example(models.Model):
    name = models.CharField(max_length=40)

I want its form to have an initial value for the field 'name', so it could be:

class ExampleForm(forms.ModelForm):
   name = forms.CharField(initial="initial_name")

That's good enought for this simple example but in case I have more complex ModelFields (i.e. with overwritten widgets) I'm missing all when re-assigning the field 'name' with the basic forms.CharField.

My question: Is there a way to set the initials in the Meta class, in the same way the widgets can be? something like...

 class ExampleForm(forms.ModelForm):
     class Meta:
         initials = {
             'name': 'initial_name',
         }
Was it helpful?

Solution

These are the options that I would checkout:

Option 1: Provide initial form data when instantiating the form.

This is the most basic way to do it. In your views.py, simply provide the data with the initial keyword argument.

views.py

from forms import ExampleForm

INITIAL_DATA = {'name': 'initial_name'}

def my_view(request):
    ...
    form = ExampleForm(initial=INITIAL_DATA)
    ...

Not too tricky. The only downside would be if you use and abuse that form and get tired of passing in the initial data.

Option 2 (ideal for your case): Provide the initial data in the __init__ method of the class.

Forms in Django are designed to accept initial data at instantiation, so you can mess with those values in the __init__ method. Without testing it, this what I imagine it would look like:

forms.py

class ExampleForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        """If no initial data, provide some defaults."""
        initial = kwargs.get('initial', {})
        initial['name'] = 'initial_name'
        kwargs['initial'] = initial
        super(ExampleForm, self).__init__(*args, **kwargs)

This would be optimal because you can ignore the initial={...} in the view code.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top