如何创建不允许编辑某些字段的自定义UserChangeForm?

mod*_*che 5 django django-models django-forms django-admin

这是我关于SO的第二篇文章,以及我关于Django的第二篇文章 - 请保持温和.

我正在研究一个简单的用户模型.用户应该能够注册该网站,注册后他们应该能够在登录时更改其帐户设置.但是,如果我执行以下操作,用户会看到一个包含我不希望他们编辑的各种信息的巨大表单:

views.py

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) )
Run Code Online (Sandbox Code Playgroud)

好像这还不够糟糕,这个表单不允许进行任何更改,引用"具有此用户名的用户已存在"作为错误.这让我感到困惑 - 我试图保存一个UserChangeForm,所以它不会已经存在了吗?

我一直在网上寻找一段时间,根据我在SO上看到的其他问题尝试制作我自己的自定义表单,如下所示:

forms.py

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
Run Code Online (Sandbox Code Playgroud)

不幸的是,这还没有成功.我有点不知道该做什么,所以任何帮助都会非常感激.以下是我的urls.py和模板:

urls.py

urlpatterns = patterns('appname.accounts.views',

    url(r'^settings/$', 'settings', { 
            'template_name': 'accounts/settings.html' 
        }, 'settings'
    ),
)
Run Code Online (Sandbox Code Playgroud)

模板

{% 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 &rarr;"></p>
    </form>
{% endblock %}
Run Code Online (Sandbox Code Playgroud)

在此先感谢您的帮助!

Jer*_*zyk 8

第一:要限制表单中的哪些字段,请按照文档说明.筛选字段基本上有两种选择:fieldsexclude.

第二:你总是在创造一个新用户.使用User实例初始化表单,不仅可以保存表单,还可以使用初始数据集.

您的视图代码应为:

# in the POST:
form = UserChangeForm(request.POST, instance=request.user)

# otherwise
form = UserChangeForm(instance=request.user)
Run Code Online (Sandbox Code Playgroud)

并从中删除值赋值form.py.


Roh*_*hit 5

我想我在这方面已经很晚了,但为了未来的读者,我仍然会发布我的观点。

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'})
        }
Run Code Online (Sandbox Code Playgroud)

这将创建一个自定义表单,usernameemail字段为只读,因为您不希望用户在创建用户帐户后更改这些唯一字段。它还会阻止显示该字段,因为在个人资料页面上password显示 hased 没有意义。password