zoukankan      html  css  js  c++  java
  • Auth模块、Forms组件

    Auth模块

    auth模块是Django自带的用户认证模块:

    我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统。此时我们需要实现包括用户注册、用户登录、用户认证、注销、修改密码等功能,这还真是个麻烦的事情呢。

    Django作为一个完美主义者的终极框架,当然也会想到用户的这些痛点。它内置了强大的用户认证系统--auth,它默认使用 auth_user 表来存储用户数据。

     为了方便快捷的帮开发者完成登录相关的认证交互功能。

    auth_user表常用操作:

    from django.contrib.auth.models import User
    #创建普通用户
    User.objects.create_user(username='Owen', password='123')
    
    #创建超级用户
    User.objects.create_superuser(username='root',password='root',email='root@root.com')
    
    #获取第一个用户
    user = User.objects.first()
    
    #修改密码
    user.set_password('000')
    user.save()  #注:修改完成后必须要进行保存,即执行save()方法
    
    #校验密码
    res = user.check_password('000')

    auth组件常用功能:

    # 校验用户账号及密码,校验成功返回user对象
    from django.contrib.auth import authenticate
    #该模块需要两个参数,用户名和密码
    user=authenticate(username=usr, password=pwd)
    
    # 注册用户到request对象中,注册成功可以用request.user访问当前登录用户(会形成session记录)
    from django.contrib.auth import login
    login(request, user)  # 注册authenticate成功(当前登录)的用户
    
    # 注销当前注册的user(用户注销)
    from django.contrib.auth import logout
    logout(request)
    
    # 校验用户登录状态
    # 视图函数中使用
    if request.user.is_authenticated(): pass
    # 模板语言中使用
    {% if request.user.is_authenticated %}
    {% else %}
    {% endif %}
    
    # 校验登录状态的装饰器
    from django.contrib.auth.decorators import login_required
    @login_required(login_url='/user_login/')
    def user_home(request):
        return render(request, 'user.html', locals())
    
     

    若用户没有登录,则会跳转到django默认的 登录URL '/accounts/login/ ' 并传递当前访问url的绝对路径 (登陆成功后,会重定向到该路径)。

    如果需要自定义登录的URL,则需要在settings.py文件中通过LOGIN_URL进行修改。

    # 在settings.py中设置:
    LOGIN_URL = '/login/'  # 这里配置成你项目登录页面的路由

    扩展User表:

    # app/models.py
    #第一种方式:(建议使用)
    from django.contrib.auth.models import AbstractUser
    class User(AbstractUser):
        # 增加自定义字段
        info = models.TextField(null=True)
        
    # settings.py配置
    AUTH_USER_MODEL = 'app.User'
    
    # 在视图函数中导入的模块就是:
    from app.models import User
    

    #第二种方式:(不建议使用) from django.contrib.auth.models import User Create your models here. class UserInfo(models.Model): id = models.AutoField(primary_key=True) info = models.TextField(null=True) user = models.OneToOneField(to=User, to_field='username', db_constraint=False, null=True, on_delete=models.SET_NULL)

    Forms组件

    表单字段的校验:

    <!-- register.html核心代码 -->
    <form action="" method="post" novalidate>
        <input type="text" name="usr">
        <input type="password" name="pwd">
        <input type="email" name="email">
        <input type="submit" value="注册">
    </form>
    # views.py核心代码
    from django.shortcuts import render, HttpResponse
    from django import forms
    # 自定义校验表单字段的类,继承forms.Form,并用forms下具体字段完成校验
    class CheckForm(forms.Form):
        # 通过error_messages自定义错误信息
        usr = forms.CharField(min_length=3, max_length=10, error_messages={'min_length':'长度至少为3'})
        pwd = forms.CharField(min_length=3, max_length=10)
        email = forms.EmailField(error_messages={'invalid':'邮箱不合法', 'required': '必填项'})
    
    def register(request):
        if request.method == "GET":
            return render(request, 'register.html')
        if request.method == "POST":
            # 校验请求的所有数据
            check_form = CheckForm(request.POST)
            if check_form.is_valid():
                # 查看校验成功的数据,为字典类型
                print(check_form.cleaned_data)
                return HttpResponse('注册成功')
            else:
                # 查看校验失败的数据,为封装的字典类型
                print(check_form.errors)
        return HttpResponse('注册失败')

    表单元素的渲染:

    # view.py改动代码
    class CheckForm(forms.Form):
        usr = forms.CharField(min_length=3, max_length=10, label="用户名")
        pwd = forms.CharField(min_length=3, max_length=10, label="密码")
        email = forms.EmailField(, label="邮箱")
    
    def register(request):
        if request.method == "GET":
            check_form = CheckForm()
            return render(request, 'register.html', {'check_form': check_form})
    <!-- register.html核心代码 -->
    <!-- 方式一 -->
    <form action="" method="post">
        {{ check_form.usr }}
        {{ check_form.pwd }}
        {{ check_form.email }}
        <input type="submit" value="注册">
    </form>
    <!-- 方式二 -->
    <form action="" method="post">
        {% for foo in check_form %}   
             <label for="{{ foo.id_for_label }}" class="col-sm-2 control-label">{{ foo.label }}</label>       
             {{ foo }}  
         {% endfor %}
        <input type="submit" value="注册">
    </form>
    <!-- 方式三 -->
    <form action="" method="post">
        <table>{{ check_form.as_table}}</table>
        <input type="submit" value="注册">
    </form>
    <!-- 方式四 -->
    <form action="" method="post">
        <ul>{{ check_form.as_ul}}</ul>
        <input type="submit" value="注册">
    </form>
    <!-- 方式五 -->
    <form action="" method="post">
        {{ check_form.as_p}}
        <input type="submit" value="注册">
    </form>

    错误信息的渲染:

    # views.py
    class CheckForm(forms.Form):
        usr = forms.CharField(
            min_length=3,
            max_length=10,
            error_messages={
                'min_length': '长度至少为3',
                'max_length': '长度最多为10',
                'required': '必填项'
            },
            label="用户名"
        )
        pwd = forms.CharField(
            min_length=3,
            max_length=10,
            error_messages={
                'min_length': '长度至少为3',
                'max_length': '长度最多为10',
                'required': '必填项'
            },
            label="密码"
        )
        email = forms.EmailField(
            error_messages={
                'invalid': '邮箱不合法',
                'required': '必填项'}
        )
    
    def register(request):
        if request.method == "GET":
            check_form = CheckForm()
        if request.method == "POST":
            check_form = CheckForm(request.POST)
            if check_form.is_valid():
                return HttpResponse('注册成功')
        return render(request, 'register.html', locals())
    <form action="" method="post" novalidate>
        {% for ele in check_form %}
        <p>
            {{ ele.label }}:{{ ele }}
            <span style="color: red">{{ ele.errors.0 }}</span>
        </p>
        {% endfor %}
    
        <input type="submit" value="注册">
    </form>

    组件的参数设置:

    class Ret(Form):
        name = forms.CharField(max_length=10, min_length=2, label='用户名',
                               error_messages={'required': '该字段不能为空', 'invalid': '格式错误', 'max_length': '太长',
                                               'min_length': '太短'},
                               widget=widgets.TextInput(attrs={'class':'form-control'}))
        pwd = forms.CharField(max_length=10, min_length=2, widget=widgets.PasswordInput(attrs={'class':'form-control'}))
        email = forms.EmailField(label='邮箱', error_messages={'required': '该字段不能为空', 'invalid': '格式错误'})

    局部钩子:

    # 在自定义验证类CheckForm中添加局部验证钩子
    class CheckForm(forms.Form):
        ...
        def clean_usr(self):
            name = self.cleaned_data.get('usr')  # type: str
            import re
            if re.match('^[0-9]', name):
                from django.core.exceptions import ValidationError
                raise ValidationError('不能以数字开头')
            return name

    全局钩子:

    # views.py
    class CheckForm(forms.Form):
        usr = forms.CharField(
            min_length=3,
            max_length=10,
            error_messages={
                'min_length': '长度至少为3',
                'max_length': '长度最多为10',
                'required': '必填项'
            },
            label="用户名",
            widget=forms.TextInput(attrs={'placeholder': '请输入用户名'})
        )
        pwd = forms.CharField(
            min_length=3,
            max_length=10,
            error_messages={
                'min_length': '长度至少为3',
                'max_length': '长度最多为10',
                'required': '必填项'
            },
            label="密码",
            widget=forms.PasswordInput(attrs={'placeholder': '请输入密码'})
        )
        re_pwd = forms.CharField(
            min_length=3,
            max_length=10,
            error_messages={
                'min_length': '长度至少为3',
                'max_length': '长度最多为10',
                'required': '必填项'
            },
            label="确认密码",
            widget=forms.PasswordInput(attrs={'placeholder': '请确认密码'})
        )
        def clean(self):
            pwd = self.cleaned_data.get('pwd')
            re_pwd = self.cleaned_data.get('re_pwd')
            if pwd == re_pwd:
                return self.cleaned_data
            from django.core.exceptions import ValidationError
            raise ValidationError('两次密码不一致')
    
    def register(request):
        if request.method == "GET":
            check_form = CheckForm()
        if request.method == "POST":
            check_form = CheckForm(request.POST)
            if check_form.is_valid():
                return HttpResponse('注册成功')
            else:
                # 拿到全局钩子抛出的错误信息
                all_error = check_form.errors.get('__all__', None)
        return render(request, 'register.html', locals())
    <form action="" method="post" novalidate>
        {% for ele in check_form %}
            <p>
                {{ ele.label }}:{{ ele }}
                <span style="color: red">{{ ele.errors.0 }}</span>
                {% if ele.label == '确认密码' %}
                    <span style="color: red">{{ all_error.0 }}</span>
                {% endif %}
            </p>
        {% endfor %}
        <input type="submit" value="注册">
    </form>
  • 相关阅读:
    访问者模式
    oracle触发器简单实用示例
    C#控件交互效果类(也可以用作缩小面板放大,展示更多信息)
    23种设计模式探索C#
    windows快捷操作个人记录(常用)
    C#巧妙使用关键字async/await
    学习的枚举类型,结构以及初步了解数组
    目前学习.net时间让我摸不着头脑的事情
    对C#中几个循环语句的使用,请教
    学习了用控制台显示结果
  • 原文地址:https://www.cnblogs.com/wangke0917/p/10526257.html
Copyright © 2011-2022 走看看