2011-04-02 58 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

這個版本
相關問題