2011-04-02 27 views
3

这是我在SO上的第二篇文章,也是我在Django的第二篇文章 - 请温和。如何创建不允许编辑某些字段的自定义UserChangeForm?

我正在研究一个简单的用户模型。用户应该能够注册该网站,注册后他们应该能够在登录后更改他们的帐户设置。但是,如果我这样做时,用户会看到一个巨大的形式与各类信息的,我不希望他们编辑:

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)) 

如果这还不够糟糕,此表单不允许进行任何更改,并以“此用户名已存在的用户”作为错误。这使我困惑 - 我试图保存一个UserChangeForm,所以它不会存在给定?

我一直在寻找,现在网上有一阵子,企图使我自己的自定义表单,基于other questions我已经看到了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 

不幸这还没有解决。我有点不知所措,所以任何帮助将不胜感激。下面是我的urls.py和模板:

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 &rarr;"></p> 
    </form> 
{% endblock %} 

在此先感谢您的帮助!

回答

6

首先:要限制哪些字段在表单中,请按照documentation。基本上有两个选项来过滤字段:fieldsexclude

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

您的视图代码应为:

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

# otherwise 
form = UserChangeForm(instance=request.user) 

,并从form.py删除赋值。

+0

感谢您的帮助!我应该更仔细地检查文件,对此表示遗憾。根据您的建议,我更改了表单以获取用户的实例。 但是,它似乎像继承UserChangeForm时,我不能'排除'User.username。无论我是在Meta中设置字段还是专门排除字段,用户名字段都会显示在表单中。我想知道它是否可能与[这张票](http://code.djangoproject.com/ticket/8620)有关。你的想法? – modocache 2011-04-02 18:58:17

+0

我前段时间有同样的问题......它看起来像第一个班级链中的Meta类定义没有被覆盖 – Jerzyk 2011-04-02 19:17:17

+0

这似乎并不正确。我发现你显然不能通过'exclude'和'fields'来排除'username'和'password'。 任何想法如何实现? – codingjoe 2013-05-02 11:45:44

1

看起来你没有仔细阅读文档。

让我来帮你,看看using-a-subset-of-fields-on-the-form

基本上你只需要添加exclude = ('fieldname',)到你的模型元。

+0

我真的很尴尬,我错过了专门解决我的问题的文档 - 感谢您的帮助! – modocache 2011-04-02 19:05:59

4

这需要更新:您不能在UserChangeForm排除字段()

太糟糕了。

0

它为我工作的方法是添加一个窗体类(在forms.py)重写UserChangeForm:

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

这个版本
相关问题