简体   繁体   English

UserCreationForm Django

[英]UserCreationForm Django

I'm trying to create a sign-up form, but I notice that when I render {{ form.as_p }} with a UserCreationForm, all possible fields appear for the user.我正在尝试创建一个注册表单,但我注意到当我使用{{ form.as_p }}呈现{{ form.as_p }}时,会为用户显示所有可能的字段。 Now some of the fields, I want only accessible to admins.现在有些字段,我只想让管理员访问。

So, I know that you can specify the fields in the Meta Class through fields=(f1,f2...)所以,我知道你可以通过fields=(f1,f2...)

But wouldn't a malicious user still be able to manually submit a POST request with the 'secret' fields even though they aren't technically displayed in the form?但是恶意用户是否仍然能够手动提交带有“秘密”字段的 POST 请求,即使它们在技术上没有显示在表单中?

The only way I know how to combat this is to manually validate each field and to construct the model objects myself to ensure that the user does not touch these 'secret' fields.我知道如何解决这个问题的唯一方法是手动验证每个字段并自己构建模型对象以确保用户不会接触这些“秘密”字段。 How, this seems to defeat the purpose of using a UserCreationForm.如何,这似乎违背了使用 UserCreationForm 的目的。 Is there a better way about this?有没有更好的方法呢?

For reference, when I mean defeating the purpose for a UserCreationField, I wouldn't be able to use user = super(UserCreationForm,self).save(commit=True) safely?作为参考,当我的意思是破坏 UserCreationField 的目的时,我将无法安全地使用user = super(UserCreationForm,self).save(commit=True)

If the form doesn't know the field exists (ie, it is not in the fields list of its meta class), then it won't look for a value for it in the submitted data.如果表单不知道该字段存在(即它不在其元类的fields列表中),则它不会在提交的数据中为其查找值。 Hence you are perfectly safe saving the data from the form.因此,您可以完全安全地保存表单中的数据。

As an example, suppose we have the following model:例如,假设我们有以下模型:

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)

We can then write a LimitedCreateForm which only gets the name and hobbies and doesn't set the age.然后我们可以编写一个LimitedCreateForm ,它只获取姓名和爱好,不设置年龄。 For test purposes, we can then use this form in a view which dumps the submitted data and the corresponding created person back to the browser for debugging purposes:出于测试目的,我们可以在视图中使用此表单,该视图将提交的数据和相应的创建人转储回浏览器以进行调试:

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)

The final step in the test is to create a template which displays the debugging data (the POST data from the form and the corresponding person created), and creates a 'malicious' form with a field for the age in it:测试的最后一步是创建一个显示调试数据的模板(来自表单的 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>

If we then run it, and submit some values, we get the following debugging output:如果我们然后运行它并提交一些值,我们会得到以下调试输出:

Submitted data:提交的数据:

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

Created user创建用户

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

This shows the form ignored the submitted age of 27, and only saved the fields it was told about.这表明表单忽略了提交的年龄 27,只保存了它被告知的字段。

It is worth noting that this is also the case if you specify a list of fields to exclude (ie, exclude = ('age',) rather than fields = ('name', 'hobbies') in the forms meta class).值得注意的是,如果您指定要排除的字段列表(即,在表单元类中使用exclude = ('age',)而不是fields = ('name', 'hobbies') ,情况也是如此。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM