这是我关于SO的第二篇文章,以及我关于Django的第二篇文章 - 请保持温和。
我正在研究一个简单的用户模型。用户应该能够注册该网站,注册后他们应该能够在登录时更改其帐户设置。但是,如果我执行以下操作,用户会看到一个包含我不希望他们编辑的各种信息的巨大表单:
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) )
好像这还不够糟糕,此表单不允许进行任何更改,引用“具有此用户名的用户已存在”作为错误。这让我感到困惑 - 我试图保存一个UserChangeForm,所以它不会已经存在了吗?
我一直在网上寻找一段时间,尝试制作我自己的自定义表单,基于我在SO上看到的other questions,就像这样:
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
不幸的是,这还没有成功。我有点不知道该做什么,所以任何帮助都会非常感激。以下是我的urls.py和模板:
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 %}
提前感谢您的帮助!
答案 0 :(得分:8)
首先:要限制表单中的字段,请按照documentation进行操作。筛选字段基本上有两个选项:fields
和exclude
。
第二:你总是在创造一个新用户。使用User实例初始化表单,不仅可以保存表单,还可以使用初始数据集。
您的观看代码应为:
# in the POST:
form = UserChangeForm(request.POST, instance=request.user)
# otherwise
form = UserChangeForm(instance=request.user)
并从form.py
中删除值分配。
答案 1 :(得分:4)
这需要更新:您不能排除UserChangeForm()中的字段
太糟糕了。
答案 2 :(得分:2)
三件事。首先,您应该将self.fields ['username']设置为表单字段,例如forms.CharField(initial = self.instance.username)。其次,您在视图中使用UserChangeForm而不是CustomUserChangeForm。第三,http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#using-a-subset-of-fields-on-the-form(现在是一个适当的链接,而不是某人的硬盘......
答案 3 :(得分:1)
看起来您没有仔细阅读文档。
让我帮助你,查看using-a-subset-of-fields-on-the-form。
基本上您只需要将exclude = ('fieldname',)
添加到您的模型元数据
答案 4 :(得分:1)
它对我有用的方法是添加一个覆盖UserChangeForm的表单类(在forms.py中):
from django.contrib.auth.forms import UserChangeForm
class UserChangeForm(UserChangeForm):
"""Overriding visible fields."""
class Meta:
model = User
fields = ('username', 'password', 'email', 'first_name', 'last_name',)
最后在views.py而不是contrib.auth.forms
上导入此版本答案 5 :(得分:0)
我认为我在这本书上还很晚,但为了将来的读者,我还是会发表自己的观点。
class UserUpdateForm(UserChangeForm):
password = None
class Meta:
model = CustomUser
fields = ['username', 'email', 'first_name', 'last_name', 'description', ]
widgets = {
'description': forms.Textarea(attrs={'rows': 3}),
'username': forms.TextInput(attrs={'readonly': 'readonly'}),
'email': forms.TextInput(attrs={'readonly': 'readonly'})
}
这将创建一个自定义表单,其中username
和email
字段为只读,因为您不希望用户在创建用户帐户后更改这些唯一字段。由于在个人资料页面上显示匆忙的password
也没有意义,因此也会显示password
字段。
答案 6 :(得分:0)
我也遇到了排除密码字段的问题,这就是我登陆这里的方式。
在检查了一些好的项目的代码后,我找到了一种排除密码字段的方法(不使用排除)
只需像下面的代码一样输入 password = None
。
from django.contrib.auth.forms import UserChangeForm
class CustomUserChangeForm(UserChangeForm):
# make the password as None for removing the password field from the form
password = None
class Meta:
model = User
# select the fields that you want to display
fields = ('email', 'first_name', 'last_name',)