2013-01-05 53 views
2

我試圖創建一個註冊表單,但我注意到當我使用UserCreationForm呈現{{ form.as_p }}時,所有可能的字段都顯示給用戶。現在一些字段,我只想讓管理員訪問。UserCreationForm Django

所以,我知道,你可以通過fields=(f1,f2...)

指定在Meta類中的字段,但不會惡意用戶仍然能夠手動提交POST請求與即使他們AREN的「祕密」領域技術上顯示在表單中?

我知道如何解決這個問題的唯一方法是手動驗證每個字段並自己構建模型對象,以確保用戶不會觸摸這些「祕密」字段。如何,這似乎打敗了使用UserCreationForm的目的。有沒有更好的方法呢?

作爲參考,當我的目的是擊敗UserCreationField的目的,我將無法安全地使用user = super(UserCreationForm,self).save(commit=True)

回答

3

如果表單不知道該字段是否存在(即,它不在其元類的fields列表中),那麼它將不會在提交的數據中查找它的值。因此,您完全可以安全地保存表單中的數據。

舉個例子,假設我們有以下模型:

from django.db import models 

class Person(models.Model): 
    name = models.CharField(max_length=100) 
    age = models.PositiveIntegerField(blank=True, null=True) 
    hobbies = models.CharField(max_length=200, blank=True, null=True) 

然後,我們可以寫一個LimitedCreateForm只獲取名稱和愛好,並且不設置年齡。出於測試目的,我們就可以使用此表中轉儲提交數據的視圖和相應的創建人回瀏覽器調試目的:

from django.shortcuts import render 
from django import forms 

from testapp.models import Person 

class LimitedCreateForm(forms.ModelForm): 
    class Meta: 
     model = Person 
     fields = ('name', 'hobbies') 

def create_limited(request): 
    submitted = "" 
    new_user = None 

    if request.method == 'POST': 
     submitted = str(request.POST) 
     form = LimitedCreateForm(request.POST) 
     if form.is_valid(): 
      new_user = form.save() 

    else: 
     form = LimitedCreateForm() 

    data = { 
     'form': form, 
     'submitted': submitted, 
     'new_user': new_user, 
    } 

    return render(request, 'create_limited.html', data) 

在測試的最後一步是創建一個模板,該模板顯示調試數據(從形式和建立相應的人POST數據),並與現場的年齡在它創建了一個「惡意」的形式:

<html> 

<body> 

<h1> 
Submitted data: 
</h1> 

<p> 
{{ submitted|default:"Nothing submitted" }} 
</p> 

<h1> 
Created user 
</h1> 

<p> 
Name: {{ new_user.name|default:"Nothing" }} 
<br /> 
Age: {{ new_user.age|default:"Nothing" }} 
<br /> 
Hobbies: {{ new_user.hobbies|default:"Nothing" }} 
</p> 

<h1> 
Form 
</h1> 

<form method="post"> 
    {% csrf_token %} 
    Name: <input type="text" name="name" id="id_name"> 
    <br /> 
    Age: <input type="text" name="age" id="id_age"> 
    <br /> 
    Hobbies: <input type="text" name="hobbies" id="id_hobbies"> 
    <br /> 
    <input type="submit" value="Create" /> 
</form> 

</body> 

</html> 

如果我們再運行它,並提交了一些值,我們得到以下調試輸出:

提交的數據:

<QueryDict: 
{u'age': [u'27'], 
u'csrfmiddlewaretoken': [u'ed576dd024e98b4c1f99d29c64052c15'], 
u'name': [u'Bruce'], 
u'hobbies': [u'Dancing through fields of flowers']}>` 

創建用戶

Name: Bruce 
Age: Nothing 
Hobbies: Dancing through fields of flowers 

由此可見形式忽視的27歲提交,只保存它講述了場。

值得注意的是,如果您指定要排除的字段列表(即exclude = ('age',)而不是表單元類中的fields = ('name', 'hobbies')),則也是如此。

+0

很好的解釋,謝謝:) – user1431282

相關問題