Unexpected value is set when I use "super().get_initial()".

I got unexpected default value when I used django.views.generic.FormView with get_initial().

Sample code:

from django.views.generic import FormView


class NewsView(FormView):
    def get_initial(self):
        self.initial['name'] =  self.request.user
        return super().get_initial()


class ContactView(FormView):
    def get_initial(self):
        if self.request.user.is_authenticated:
            return {'name': self.request.user}
        else:
            return super().get_initial()

First, I saw NewsView page with logged in.
Second, I saw ContactView page with other browser; not logged in, then name field has initial value. It must be blank!!!

I know it occurred by my mistake. Class variable which is mutable is shared variables by all class instances.

According to Python document,

9. Classes — Python 3.11.0 documentation
As discussed in A Word About Names and Objects, shared data can have possibly surprising effects with involving mutable objects such as lists and dictionaries. For example, the tricks list in the following code should not be used as a class variable because just a single list would be shared by all Dog instances:

I think django.views.generic.FormView(FormMixin) do not use initial as class value because any beginner possibly write such a code above. It makes unexpected initial value set between different forms and it may cause application hidden bug.

Do you know why does django.views.generic.FormView(FormMixin) have initial as class value?

Because initial on the class is intended to be the defaults of all instances for that FormView.

If you want to change (override) a specific field (or fields), you call super in get_initial, and then modify what super has returned to you.
e.g.

def get_initial(self):
  initial = super().get_initial()
  initial['name'] = self.request.user.username
  return initial
1 Like

Thank you for your reply.