This is my second post on SO, as well as my second post on Django--please be gentle.
I am working on a simple User model. Users should be able to sign up for the site, and after signing up they should be able to change their account settings upon login. However, if I do the following, Users see a huge form with all kinds of info I don't want them to edit:
from django.shortcuts import render_to_response, get_object_or_404
from django.core import urlresolvers
from django.http import HttpResponseRedirect
from django.template import RequestContext
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import UserChangeForm
@login_required
def settings( request, template_name = 'accounts/settings.html' ):
"""
Processes requests for the settings page, where users
can edit their profiles.
"""
page_title = 'Account Settings'
if request.method == 'POST':
postdata = request.POST.copy()
form = UserChangeForm( postdata )
if form.is_valid():
form.save()
else:
form = UserChangeForm()
title = 'Settings'
return render_to_response( template_name, locals(), context_instance = RequestContext( request) )
As if that wasn't bad enough, this form doesn't allow any changes to be made, citing "User with this Username already exists" as an error. This confuses me--I am attempting to save a UserChangeForm, so wouldn't it already existing be a given?
I've been looking online for a while now, attempting making my own custom forms, based on other questions I've seen on SO, like so:
class CustomUserChangeForm( UserChangeForm ):
def __init__( self, *args, **kwargs ):
super( CustomUserChangeForm, self ).__init__( *args, **kwargs )
if self.instance and self.instance.pk:
# Since the pk is set this is not a new instance
self.fields['username'] = self.instance.username
self.fields['username'].widgets.attrs['readonly'] = True
Unfortunately this hasn't worked out. I'm kind of at a loss as to what to do, so any help would be greatly appreciated. Below are my urls.py and template:
urlpatterns = patterns('appname.accounts.views',
url(r'^settings/$', 'settings', {
'template_name': 'accounts/settings.html'
}, 'settings'
),
)
{% extends "accounts/base.html" %}
{% block main %}
<h1>Welcome, {{ request.user.pk }}{{ request.user.username }} to accounts.templates.accounts.settings.html.</h1>
<h2>Here you can update your user settings. You can change your password <a href="{% url change_password %}">here</a>.</h2>
<form action="." method="post" accept-charset="utf-8">
{% csrf_token %}
{{ form.as_p }}
<p><input type="submit" value="Update →"></p>
</form>
{% endblock %}
Thanks in advance for any help!
First: to limit which fields are in the form, follow the documentation. There are basically two options to filter fields: fields
and exclude
.
Second: you are always creating a new user. Initialize form with the User instance, not only you will be able to save a form, but you will have an initial data set.
Your view code should read:
# in the POST:
form = UserChangeForm(request.POST, instance=request.user)
# otherwise
form = UserChangeForm(instance=request.user)
and remove value assignment from the form.py
.
This needs to be updated: You cannot exclude fields in UserChangeForm()
Too bad.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With