Django UserChangeForm errors

I am creating a custom form that a user can log in to change some details. I got two errors that I can't figure out what the problem is.

The first problem is that the form doesn't fill in the user's details. And it looks like because it is self

empty when the form is initialized, why?

And the second problem is that when I submit this form, it will complain about some KeyError, which I don't get either. I pasted code and stacktrace.

Trackback

Environment:


Request Method: POST
Request URL: http://localhost:8000/settings/

Django Version: 1.4
Python Version: 2.7.2
Installed Applications:
('django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.admin',
 'social_auth')
Installed Middleware:
('django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware')


Traceback:
File "c:\tools\python27\lib\site-packages\django-1.4-py2.7.egg\django\core\handlers\base.py" in get_response
  111.                         response = callback(request, *callback_args, **callback_kwargs)
File "c:\tools\python27\lib\site-packages\django-1.4-py2.7.egg\django\contrib\auth\decorators.py" in _wrapped_view
  20.                 return view_func(request, *args, **kwargs)
File "C:\xampp\htdocs\tddd27_project\contact\views.py" in settings
  47.       if form.is_valid():
File "c:\tools\python27\lib\site-packages\django-1.4-py2.7.egg\django\forms\forms.py" in is_valid
  124.         return self.is_bound and not bool(self.errors)
File "c:\tools\python27\lib\site-packages\django-1.4-py2.7.egg\django\forms\forms.py" in _get_errors
  115.             self.full_clean()
File "c:\tools\python27\lib\site-packages\django-1.4-py2.7.egg\django\forms\forms.py" in full_clean
  270.         self._clean_fields()
File "c:\tools\python27\lib\site-packages\django-1.4-py2.7.egg\django\forms\forms.py" in _clean_fields
  290.                     value = getattr(self, 'clean_%s' % name)()
File "c:\tools\python27\lib\site-packages\django-1.4-py2.7.egg\django\contrib\auth\forms.py" in clean_password
  122.         return self.initial["password"]

Exception Type: KeyError at /settings/
Exception Value: 'password'

      

views.py

def settings(request):

    if request.method == 'POST':
        form = UserProfileForm(request.POST)
        if form.is_valid():
            form.save()
            return HttpResponse("Change success")
    else:
        form = UserProfileForm(instance=request.user)
    return render_to_response('settings.html',{'form': form}, context_instance=RequestContext(request))

      

forms.py

class UserProfileForm(UserChangeForm):

    class Meta:
        model = User
        fields = ('username', 'first_name', 'last_name')
        exclude = ('password',)

    def __init__(self, *args, **kwargs):
        super(UserProfileForm, self).__init__(*args, **kwargs)
        if self.instance  and self.instance.pk:
            self.fields['username'] = self.instance.username
            self.fields['first_name'] = self.instance.first_name
            self.fields['last_name'] = self.instance.last_name

      

template

{% extends "base.html" %}

{% block title %}
    Settings
{% endblock title %}

{% block content %}
 {{ user.username }}
    <form action="" method="POST">
        {% csrf_token %}
        {{ form.as_p }}
        <input type="submit" value="submit">
    </form>
{% endblock content %}

      

+3


source to share


2 answers


Regarding your second problem, I also ran into the same question today while upgrading from Django 1.3 to Django 1.4. I had a regular form like you:

class UserProfileForm(UserChangeForm):
    class Meta:
        model = User
        fields = ('username', 'first_name', 'last_name', )

      



I solved the problem by adding a method clean_password

like this:

class UserProfileForm(UserChangeForm):
    class Meta:
        model = User
        fields = ('username', 'first_name', 'last_name', )

    def clean_password(self):
        return "" # This is a temporary fix for a django 1.4 bug

      

+5


source


The first problem is that the form doesn't fill in the user's details. And it seems to be because self is empty when the form is initialized, why?

This will initiate a new empty template: UserProfileForm()

orUserProfileForm(request.POST)

This will initiate a model form bound to a user instance: UserProfileForm(instance=request.user)

or UserProfileForm(request.POST, instance=request.user)

.

If you don't fully understand this, read the documentation about using ModelForm .

In your opinion, you are creating new empty forms, not forms associated with the request.user instance. for example it UserProfileForm(request.POST)

should beUserProfileForm(request.POST, instance=request.user)

Then it is absolutely unnecessary:

   if self.instance  and self.instance.pk:
        self.fields['username'] = self.instance.username
        self.fields['first_name'] = self.instance.first_name
        self.fields['last_name'] = self.instance.last_name

      



This doesn't fix the KeyError, but you must change:

exclude = ('password')

      

To:

exclude = ('password',)

      

Note that in the second case, exclude is a tuple. See this example in python shell:

In [1]: ('foo')
Out[1]: 'foo'

In [2]: ('foo',)
Out[2]: ('foo',)

      

As for your KeyError, I'm really not sure. I can see the problem , but I haven't hacked how it is supposed to work. Anyway, if the password is excluded, this function shouldn't run anyway.

+2


source







All Articles