How do I pass in arguments to the __init__ function of Django's PasswordChangeForm

By : Maaack
Source: Stackoverflow.com
Question!

I'm getting a TypeError when trying to access my PasswordChangeView in Django. The error is:

Django Version: 1.7.3
Exception Type: TypeError
Exception Value:    
__init__() missing 1 required positional argument: 'user'
Exception Location: /usr/local/lib/python3.4/dist-packages/django/views/generic/edit.py in get_form, line 45
Python Executable:  /usr/bin/python3.4

I haven't been able to find an example of the FormView loading the provided PasswordChangeForm from https://docs.djangoproject.com/en/1.7/_modules/django/contrib/auth/forms/#PasswordChangeForm

This is how I tried to do it, but am still running into the error even after some tweaking.

urls.py

url(r'^password/change/$', login_required(views.PasswordChangeView.as_view()), name='change_password'),

views.py

class PasswordChangeView(FormView):
    template_name = 'change_password.html'
    form_class = PasswordChangeForm

    def dispatch(self, request, *args, **kwargs):
        try:
            self.initial['user'] = self.request.user
        except AttributeError:
            raise Http404

        return super(PasswordChangeView, self).dispatch(request, *args, **kwargs)

I'm not certain why I'm still getting this error. If I look into the FormMixin that I extend with FormView I see the following:

def get_form(self, form_class):
    """
    Returns an instance of the form to be used in this view.
    """
    return form_class(**self.get_form_kwargs())

def get_form_kwargs(self):
    """
    Returns the keyword arguments for instantiating the form.
    """
    kwargs = {
        'initial': self.get_initial(),
        'prefix': self.get_prefix(),
    }

    if self.request.method in ('POST', 'PUT'):
        kwargs.update({
            'data': self.request.POST,
            'files': self.request.FILES,
        })
    return kwargs

and ...

def get_initial(self):
    """
    Returns the initial data to use for forms on this view.
    """
    return self.initial.copy()

Source: https://github.com/django/django/blob/master/django/views/generic/edit.py

I confirmed that self.initial contains user by calling self.get_form_kwargs():

{'initial': {'user': <SimpleLazyObject: <User: maaack>>}, 'prefix': None}

How else am I supposed to pass the user into the form?

By : Maaack


Answers

You should pass the user to the form constructor as the first argument. Look at the SetPasswordForm.__init__():

def get_form(self, form_class):
    return form_class(self.request.user, **self.get_form_kwargs())

There is no user field in the PasswordChangeForm so the user key in the initial is useless.

By : catavaran


This video can help you solving your question :)
By: admin