【问题标题】:Client-Side Verification Django客户端验证 Django
【发布时间】:2021-01-24 05:31:36
【问题描述】:

我是 Django 新手,我制作了一个扩展 UserCreationForm 的表单,我想验证客户端的输入。我怎样才能做到这一点?当我验证 password1 时,它工作得很好,但由于某种原因,我无法检查这些字段是否丢失。提前致谢。

class UserRegisterForm(UserCreationForm):
    email = forms.EmailField()

    class Meta:
        model = User 
        fields = ['username', 'email', 'password1', 'password2']


    def validate(self,password):

        return self.short_enough(password) and self.has_lowercase(password) and self.has_uppercase(password) and self.has_numeric(password) and self.has_special(password)


    def short_enough(self,pw):
         return len(pw) == 8

    def has_lowercase(self,pw):
        'Password must contain a lowercase letter'
        return len(set(string.ascii_lowercase).intersection(pw)) > 0

    def has_uppercase(self,pw):
        'Password must contain an uppercase letter'
        return len(set(string.ascii_uppercase).intersection(pw)) > 0

    def has_numeric(self,pw):
        'Password must contain a digit'
        return len(set(string.digits).intersection(pw)) > 0

    def has_special(self,pw):
        'Password must contain a special character'
        return len(set(string.punctuation).intersection(pw)) > 0


    def clean(self):
        
        cleaned_data = super(UserRegisterForm, self).clean()

        username = cleaned_data.get('username')
        email = cleaned_data.get('email')
        password1 = cleaned_data.get('password1')
        password2 = cleaned_data.get("password2")

        if username == None or email == None or password1 == None or password2 == None:      
              raise forms.ValidationError("Some fields are missing" )
              

        if not self.validate(password1):
            raise forms.ValidationError("Password must be 8 characters(1 upper, 1 lower, 1 number, 1 special character)" )
        else:
            return cleaned_data

这是我的 HTML 文件,问题是我使用的是 {{ form }} 而不是 HTML 输入:

{% extends "blog/base.html" %}
{% load crispy_forms_tags %}

{% block content %}

    <div class="content-section">

        <form method="POST" >

            {% csrf_token %}

            <fieldset class="form-group" aria-required="true">

                <legend class="border-bottom mb-4"> Join Today </legend>
                    {{ form|crispy }}

            </fieldset>

            <div class="form-group">

                <button class="btn btn-outline-info" type="submit" > Sign Up </button>

            </div>

        </form>

        <div class="border-top pt-3">
             <small class="text-muted">

             Already have an account? <a class="ml-2" href="{% url 'login' %}" >Sign In</a>

            </small> 
        </div>

    </div>

{% endblock content %}

【问题讨论】:

  • 您好,django 不提供任何客户端验证,您应该使用 javascript 对其进行编程(请记住,一些 html5 标签为您提供了一些开箱即用的验证),一旦您创建了您的 js 文件,使用 form.Media (docs.djangoproject.com/en/3.1/topics/forms/media) 将该文件包含在您的模板中
  • 感谢您的回复,您确定吗?我在 clean(self) 方法中为密码制定了自己的规则,它可以工作,但我无法验证输入是否为空
  • 所以您正在服务器端进行验证:) 您可以将 required=True 参数添加到您的表单字段以自动处理此问题,如果为 True,它将不允许空值和支持html5标签的浏览器,表单为空时不会发布给用户发送消息,查看并告诉我
  • 我发布了我的 html 文件以便您查看,我使用的是 {{ form }}

标签: python html django web server


【解决方案1】:

好的,您的模板看起来不错,只是在您的表单中添加了一些内容。

为了简化代码,我将required=True 添加到您定义的电子邮件字段中,并将相同的参数设置为其余字段的__init__ 方法,这将根据需要执行所有字段,您可以摆脱您的自定义clean中的“空值”验证


class UserRegisterForm(UserCreationForm):
    email = forms.EmailField(required=True)

    class Meta:
        model = User 
        fields = ['username', 'email', 'password1', 'password2']

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['username'].required = True
        self.fields['password1'].required = True
        self.fields['password2'].required = True

    def validate(self,password):

        return self.short_enough(password) and self.has_lowercase(password) and self.has_uppercase(password) and self.has_numeric(password) and self.has_special(password)


    def short_enough(self,pw):
         return len(pw) == 8

    def has_lowercase(self,pw):
        'Password must contain a lowercase letter'
        return len(set(string.ascii_lowercase).intersection(pw)) > 0

    def has_uppercase(self,pw):
        'Password must contain an uppercase letter'
        return len(set(string.ascii_uppercase).intersection(pw)) > 0

    def has_numeric(self,pw):
        'Password must contain a digit'
        return len(set(string.digits).intersection(pw)) > 0

    def has_special(self,pw):
        'Password must contain a special character'
        return len(set(string.punctuation).intersection(pw)) > 0

    def clean(self):
        cleaned_data = super(UserRegisterForm, self).clean()
        password1 = cleaned_data.get('password1')
        password2 = cleaned_data.get("password2")          

        if not self.validate(password1):
            raise forms.ValidationError("Password must be 8 characters(1 upper, 1 lower, 1 number, 1 special character)" )
        else:
            return cleaned_data

另一方面,要进行单字段验证,我建议您使用 django 提供的方法 clean_&lt;fieldname&gt;,查看此处的文档 --> https://docs.djangoproject.com/en/3.1/ref/forms/validation/#cleaning-a-specific-field-attribute

当您使用 django 脆皮表单时,您可以在表单定义中包含提交按钮以及表单标签,它会将所有表单 DOM 封装在您的 python 代码中,我认为这很棒,请查看文档- > https://django-crispy-forms.readthedocs.io/en/latest/layouts.html

【讨论】:

  • 谢谢!如果我想比较两个密码是否匹配,我必须在 validate() 中添加条件吗?
  • 是的,您可以像其他验证一样进行操作
  • 但是我建议你去掉你自定义的validate 方法,因为它与默认的clean 是多余的,只需将代码从validate 移动到clean IMOO
  • 问题是我被要求在客户端进行验证,我可以阻止 django 对 2 个密码的默认验证吗?
  • 有一个设置来设置密码验证器运行,检查文档 --> docs.djangoproject.com/en/3.1/topics/auth/passwords/… 这应该是方式
猜你喜欢
  • 2013-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-05
  • 1970-01-01
  • 2016-08-29
  • 2012-07-29
相关资源
最近更新 更多