zoukankan      html  css  js  c++  java
  • Auth组件,Forms组件

    一、Auth组件默认auth_user表常用操作

    #1.配置settings,使django与数据库连接
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'dg74_1',
            'USER': 'root',
            'PASSWORD': "940828",
            'HOST': '127.0.0.1'
        }
    }
    
    #2.
    import pymysql
    pymysql.install_as_MySQLdb()
    
    #3.直接进行数据库迁移,这样django就会在数据库中建立出一个auth_user表
    
    
    
    #操作auth_user 数据库不区分大小写
    from django.contrib.auth.models import User
    # 1、创建普通用户
    User.objects.create_user(username='Henry',password='123')
    
    # 2、创建超级用户
    User.objects.create_superuser(username='root', password='root', email='root@root.com')
    
    # 3、获取第一个用户
    user = User.objects.first()
    
    # 4、修改密码
    user.set_password('000')
    user.save()
    
    # 5、校验密码
    res = user.check_password('000')
    print(res) 校验成功:True 校验失败:False

    二、Auth组件常用功能

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

    后台

    from django.shortcuts import render,redirect
    from django.contrib.auth import login,logout,authenticate
    from django.contrib.auth.decorators import login_required
    
    def index(request):
        return render(request,'index.html')
    
    def user_login(request):
        if request.method == 'GET':
            return render(request,'login.html')
        if request.method == 'POST':
            #在请求url中通过next取出回跳的页面路径,因为使用?拼接所以用get取值,没有值返回主页
            back_url = request.GET.get('next','/')
            usr = request.POST.get('usr',None)
            pwd = request.POST.get('pwd',None)
    
            #用前台传入的账户密码进行登录校验
            user = authenticate(username=usr,password=pwd)
    
            if user:
                #记录登录状态
                login(request,user)
            return redirect(back_url)
    
    def user_logout(request):
        logout(request)
        return redirect('/')
    
    #装饰器的页面返回key是next:/user_login/?next=/user_order/
    @login_required(login_url='/user_login/') #没有登录返回登录界面,登录成功又跳转回该页面
    def user_order(request):
        return render(request,'order.html',locals())
    
    @login_required(login_url='/user_login/')
    def user_home(request):
        return render(request,'user.html',locals())

    前台

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>主页</title>
    </head>
    <body>
    <h1>主页</h1>
    
    <p>
        {% if request.user.is_authenticated %} 
            <a href="/user_home/">{{ request.user.username }}</a>
            |
            <a href="/user_logout/">注销</a>
        {% else %}
            <a href="/user_login/">登录</a>
        {% endif %}
    </p>
    <hr>
    <a href="/user_order/">订单详情</a>
    
    </body>
    </html>
    
    
    //{% if request.user.is_authenticated %}  检验用户登录状态
    //request.user.username 固定的取法,取得登录的用户名

    三、自定义auth模块的user表,将auth_user表替换为app_user表

    # app/models.py
    from django.contrib.auth.models import AbstractUser
    class User(AbstractUser):
        # 增加自定义字段
    	info = models.TextField(null=True)
        
    # settings.py配置,auth模块默认采用的是app应用下的自定义user表
    AUTH_USER_MODEL = 'app.User'
    
    #数据库迁移后auth_user表不再创建由app_user表替换
    

    四、Form完成表单校验 (自定义错误信息)

    '''
    1. 校验的字段属性名要与校验的form表单中元素的name值进行匹配
    2. 校验字段的参数required
    默认为True,代表数据必须传入该校验值
    如果设置为False,校验数据中可以不包含该校验值(可以为空),但如果输入了该字段就会对其进行校验
    3. error_messages自定义校验失败的错误信息
    '''
    
    '''
    from django import forms
    class CheckForm(forms.Form):
        usr = forms.CharField(min_length=3, max_length=10)
        pwd = forms.CharField(
            min_length=3,
            max_length=10,
            error_messages={
                "min_length": "最少3",  # 某个校验规则对应的中文提示的错误信息
                "max_length": "最多10",
                'required': "必填项"  # 除了自定义校验规则,还可以明确默认校验规则的中文提示错误信息
            }
        )
    
    def register(request):
        check_form = CheckForm(request.POST)
        if check_form.is_valid():
                print("校验成功")
                print(check_form.cleaned_data)
            else:
                print("校验失败")
                print(check_form.cleaned_data)  # 如果部分成功,仍然可以获得部分成功的数据
                print(check_form.errors)  # 部分失败的信息
    '''

    五、局部钩子:在系统提供的校验结束后,在对具体的字段进行自定义二次校验

    class CheckForm(forms.Form):
        usr = forms.CharField(...)
        # ...
        # 局部钩子
        def clean_usr(self):
            cleaned_usr = self.cleaned_data.get('usr', None)
            # 自定义校验规则
            import re
            if re.match('^[0-9]', cleaned_usr):  # 通过正则匹配不能以数字开头
                from django.core.exceptions import ValidationError
                raise ValidationError('不能以数字开头')  # 抛ValidationError信息就会被添加到self.errors中
            return cleaned_usr

    六、全局钩子:在系统提供的校验结束后,在对所有的字段进行自定义二次校验

    class CheckForm(forms.Form):
        # ...
        # 全局钩子
        def clean(self):
            cleaned_pwd = self.cleaned_data.get('pwd', None)
            cleaned_re_pwd = self.cleaned_data.get('re_pwd', None)
            if cleaned_pwd != cleaned_re_pwd:
                from django.core.exceptions import ValidationError
                raise ValidationError('两次密码不一致')  # 抛ValidationError信息就会被添加到self.errors中
            return self.cleaned_data

    后台

    from django.shortcuts import render,redirect
    from django import forms
    
    class CheckForm(forms.Form):
        usr = forms.CharField(min_length=3,max_length=10,
                              error_messages={
                                  'required':'必须填',
                                  'min_length':'最少3',
                                  'max_length':'最多10'
                              })
        pwd = forms.CharField(min_length=3,max_length=10,
                              error_messages={
                                  'required':'必须填',
                                  'min_length':'最少3',
                                  'max_length':'最多10'
                              })
        re_pwd = forms.CharField(min_length=3,max_length=10,
                              error_messages={
                                  'required':'必须填',
                                  'min_length':'最少3',
                                  'max_length':'最多10'
                              })
        email = forms.EmailField(
            error_messages={
                'invalid':'email格式不正确',
                'required':'必填项'
            }
        )
        # 局部钩子:对usr进行局部钩子的校验,该方法会在usr属性校验通过后,系统调用该方法继续校验,是一个回调函数
        def clean_usr(self):
            cleaned_usr = self.cleaned_data.get('usr', None)  # type: str
    
            # 通过正则匹配不能以数字开头
            import re
            if re.match('^[0-9]', cleaned_usr):
                from django.core.exceptions import ValidationError
                raise ValidationError('不能以数字开头')
            return cleaned_usr #返回局部钩子校验的数据
    
        # 全局钩子:代表校验类中的所有属性校验通过后,系统调用该方法继续校验
        def clean(self):
            cleaned_pwd = self.cleaned_data.get('pwd', None)
            cleaned_re_pwd = self.cleaned_data.get('re_pwd', None)
            if cleaned_pwd != cleaned_re_pwd:
                from django.core.exceptions import ValidationError
                raise ValidationError('两次密码不一致')  #抛出异常,必须接受,否则报错
            return self.cleaned_data  #全部返回
    
    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('校验成功')
                print(check_form.cleaned_data)
            else:
                print('校验失败')
                print(check_form.cleaned_data)
                print(check_form.errors)
            return redirect('/')

    前台

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>注册</title>
    </head>
    <body>
    <form action="" method="post" novalidate>
        <p>
            <label for="usr">账号:</label>
            <input type="text" name="usr" id="usr">
        </p>
        <p>
            <label for="pwd">密码:</label>
            <input type="password" name="pwd" id="pwd">
        </p>
        <p>
            <label for="re_pwd">确认:</label>
            <input type="password" name="re_pwd" id="re_pwd">
        </p>
        <p>
            <label for="email">邮箱:</label>
            <input type="email" name="email" id="email">
        </p>
        <input type="submit" value="注册">
    </form>
    </body>
    </html>

    七、模板渲染

    class CheckForm(forms.Form):
        # 校验需求:账号不能以数字开头
        usr = forms.CharField(min_length=3, max_length=10, label="账号:",
                              error_messages={
                                  'required': "必填项",
                                  'min_length': "最少3",
                                  'max_length': "最多10"
                              })
        pwd = forms.CharField(min_length=3, max_length=10, label="密码:",
                              error_messages={
                                  'required': "必填项",
                                  'min_length': "最少3",
                                  'max_length': "最多10"
                              },
                              widget=forms.PasswordInput(attrs={
                                  'class': 'pwd',
                                  'placeholder': '请输入密码'
                              })
                              )
        re_pwd = forms.CharField(min_length=3, max_length=10, label="确认:",
                                 error_messages={
                                     'required': "必填项",
                                     'min_length': "最少3",
                                     'max_length': "最多10"
                                 },
                                 widget=forms.PasswordInput)
        email = forms.EmailField(label="邮箱:",
                                 error_messages={
                                     'invalid': "格式不正确",
                                     'required': "必填项"
                                 }
                                 )
    
        # 局部钩子:对usr进行局部钩子的校验,该方法会在usr属性校验通过后,系统调用该方法继续校验
        def clean_usr(self):
            cleaned_usr = self.cleaned_data.get('usr', None)  # type: str
            # 通过正则匹配不能以数字开头
            import re
            if re.match('^[0-9]', cleaned_usr):
                from django.core.exceptions import ValidationError
                raise ValidationError('不能以数字开头')
            return cleaned_usr
    
        # 全局钩子:代表校验类中的所有属性校验通过后,系统调用该方法继续校验
        def clean(self):
            cleaned_pwd = self.cleaned_data.get('pwd', None)
            cleaned_re_pwd = self.cleaned_data.get('re_pwd', None)
            if cleaned_pwd != cleaned_re_pwd:
                from django.core.exceptions import ValidationError
                raise ValidationError('两次密码不一致')
            return self.cleaned_data
    
    
    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:
                print(check_form.errors.as_data)
                all_error = check_form.errors.get('__all__')
        return render(request, 'register.html', locals())

    渲染方法1

    <form action="" method="post" novalidate>
        <p>
            <label for="id_usr">账号:</label>
            {{ check_form.usr }}
        </p>
        <p>
            <label for="id_pwd">密码:</label>
            {{ check_form.pwd }}
        </p>
        <p>
            <label for="id_re_pwd">确认:</label>
            {{ check_form.re_pwd }}
        </p>
        <p>
            <label for="id_email">邮箱:</label>
            {{ check_form.email }}
        </p>
        <input type="submit" value="注册">
    </form>
    
    //命名规范 id_ 这样点击输入框前的名字也可以选定输入框

    渲染方法2

    <form action="" method="post" novalidate>
        {% for ele in check_form %}
            <p>
                <label for="">{{ ele.label }}</label>
                {{ ele }}
                <span style="color: red;">{{ ele.errors.0 }}</span>
                {% if ele == check_form.re_pwd %}
                    <span style="color: red;">{{ all_error.0 }}</span>
                {% endif %}
            </p>
        {% endfor %}
        <input type="submit" value="注册">
    </form>

    渲染方式3

    <form action="" method="post" novalidate>
        {{ check_form.as_p }}
        <input type="submit" value="注册">
    </form>
    <hr>

    渲染方式了解

    <table>
        {{ check_form.as_table }}
    </table>
    
    <ul>
        {{ check_form.as_ul }}
    </ul>
  • 相关阅读:
    如何将List<T>转换相应的Html(xsl动态转换)(一)
    如何将List<T>转换相应的Html(xsl动态转换)(二)
    JavaScript设计模式之一Interface接口
    架构设计资源
    将ASP.NET MVC 2.0 部署在IIS6和IIS7上的教程
    如何将List<T>转换相应的Html(xsl动态转换)(一)
    步步为营 .NET 代码重构学习笔记 六
    如何将List<T>转换相应的Html(xsl动态转换)(二)
    模式资源
    Entity Framework Code First
  • 原文地址:https://www.cnblogs.com/lizeqian1994/p/10532683.html
Copyright © 2011-2022 走看看