zoukankan      html  css  js  c++  java
  • form组件注册ajax登录auth认证及验证码

    本项目采用django自带的数据库

    项目文件

      

     

    models.py

    1 from django.db import models
    2 from django.contrib.auth.models import AbstractUser
    3 # Create your models here.
    4  
    5 class Userinfo(AbstractUser):
    6     email = models.EmailField()
    View Code

    settings.py

    1 AUTH_USER_MODEL='app01.Userinfo'#自定义认证表
    2 LOGIN_URL='/login/'#指定认证失败的跳转页面
    3  
    4 STATIC_URL = '/static/'
    5 STATICFILES_DIRS=[
    6     os.path.join(BASE_DIR,'static_files')
    7 ]
    settings.py

    views.py

      1 from django.shortcuts import render, HttpResponse, redirect
      2 from django import forms#django的form组件
      3 from django.core.validators import RegexValidator#form组件中的validators自带校验器
      4 from django.core.exceptions import ValidationError#错误
      5 import re
      6 from app01 import models
      7 from django.http import JsonResponse#Json响应数据类型
      8 from django.urls import reverse#url反向解析
      9 from django.contrib import auth#django内置认证系统
     10 from django.contrib.auth.decorators import login_required#认证装饰器
     11  
     12  
     13 # Create your views here.
     14 #自定义校验函数
     15 def name_valid(value):
     16     name_re = re.compile(r'^[d]+')
     17     ret = name_re.match(value)
     18     if ret:
     19         raise ValidationError('用户名不能以数字开头!')
     20  
     21 #注册form组件
     22 class RegisterForm(forms.Form):
     23     name = forms.CharField(
     24         required=True,
     25         label='用户名:',
     26         min_length=6,
     27         max_length=32,
     28         help_text='只能有字母数字下划线组成,且不能以数字开头,长度6到32位!',
     29         # initial='admin123_',
     30         error_messages={
     31             'required': '用户名不能为空!',
     32             'min_length': '长度不能少于6位!',
     33             'max_length': '长度不能超过32位!',
     34         },
     35         validators=[RegexValidator(r'^[a-zA-Z0-9_]+$', '用户名只能包含字母数字下划线!'), name_valid],
     36     )
     37     password = forms.CharField(
     38         required=True,
     39         label='密码:',
     40         min_length=6,
     41         max_length=32,
     42         help_text='长度6到32位!',
     43         initial='',
     44         error_messages={
     45             'required': '密码不能为空!',
     46             'min_length': '长度不能少于6位!',
     47             'max_length': '长度不能超过32位!',
     48         },
     49         widget=forms.PasswordInput(render_value=True),
     50     )
     51     r_password = forms.CharField(
     52         required=True,
     53         label='确认密码:',
     54         min_length=6,
     55         max_length=32,
     56         help_text='长度6到32位!',
     57         initial='',
     58         error_messages={
     59             'required': '密码不能为空!',
     60             'min_length': '长度不能少于6位!',
     61             'max_length': '长度不能超过32位!',
     62         },
     63         widget=forms.PasswordInput(render_value=True),
     64     )
     65     email = forms.EmailField(
     66         required=True,
     67         label='邮箱',
     68         error_messages={
     69             'required': '邮箱不能为空!',
     70             'invalid':'邮箱格式不正确!'
     71         }
     72     )
     73     #全部字段添加样式
     74     def __init__(self, *args, **kwargs):
     75         super(RegisterForm, self).__init__(*args, **kwargs)
     76         for field in self.fields:
     77             self.fields[field].widget.attrs.update({'class': 'form-control'})
     78     #局部钩子
     79     def clean_name(self):
     80         pass
     81         return self.cleaned_data.get('name')
     82  
     83     def clean_password(self):
     84         pass
     85         return self.cleaned_data.get('password')
     86  
     87     def clean_r_password(self):
     88         pass
     89         return self.cleaned_data.get('r_password')
     90  
     91     def clean_email(self):
     92         pass
     93         return self.cleaned_data.get('email')
     94     #全局钩子
     95     def clean(self):
     96         password = self.cleaned_data.get('password')
     97         r_password = self.cleaned_data.get('r_password')
     98         if password != r_password:
     99             self.add_error('r_password', '两次密码不一致!')
    100             raise ValidationError('两次密码不一致!')
    101         else:
    102             return self.cleaned_data
    103  
    104  
    105 # 注册
    106 def register(request):
    107     if request.method == 'GET':
    108         register_obj = RegisterForm()
    109         return render(request, 'register.html', {'register_obj': register_obj})
    110     elif request.method == 'POST':
    111         data = request.POST
    112         # print(data)
    113         register_obj = RegisterForm(data)
    114         if register_obj.is_valid():
    115             user_obj = register_obj.cleaned_data
    116             print(user_obj)
    117             username = user_obj.get('name')
    118             password = user_obj.get('password')
    119             email = user_obj.get('email')
    120  
    121             if not models.Userinfo.objects.filter(username=username).exists():
    122                 new_obj = models.Userinfo.objects.create_user(username=username, password=password, email=email)
    123                 print(f'新用户{username}注册成功!')
    124                 return redirect('login')
    125             else:
    126                 register_obj.add_error('name', '用户名已存在!')
    127                 return render(request, 'register.html', {'register_obj': register_obj})
    128  
    129         else:
    130             return render(request, 'register.html', {'register_obj': register_obj})
    131  
    132 #登录页面的ModelForm组件(本次未使用)
    133 '''
    134 # class LoginForm(forms.ModelForm):
    135 #     class Meta:
    136 #         model = models.Userinfo  # 指定类
    137 #         # fields='__all__'
    138 #         # exclude=[]        #排除字段
    139 #         fields = ['username', 'password']  # 设置的字段
    140 #         labels = {  # 标签名
    141 #             'username': '用户名:',
    142 #             'password': '密码:'}
    143 #         error_messages = {  # 错误信息
    144 #             'username': {'required': '用户名不能为空!'},
    145 #             'password': {'required': '密码不能为空!'},
    146 #         }
    147 #         widgets = {  # 插件
    148 #             'username': forms.TextInput({"class": "form-control"}),
    149 #             'password': forms.TextInput({"class": "form-control"}),
    150 #
    151 #         }
    152 #         # def clean_username(self):
    153 #         #     pass
    154 #         #     return self.cleaned_data.get('username')
    155 #         # def clean(self):
    156 #         #     pass
    157 #         #     return self.cleaned_data
    158 #         # def __init__(self,*args,**kwargs):
    159 #         #     super().__init__(*args,**kwargs)
    160 #         #     for field in self.fields:
    161 #         #         self.fields[field].widget.attrs.update({'class':'form-control'})
    162  
    163 '''
    164  
    165  
    166  
    167  
    168  
    169 #随机验证码
    170 def get_cverification_code(request):
    171     import os
    172     from crmtest import settings
    173     import random
    174     def get_random_color():
    175         '''
    176         随机颜色
    177         :return: rgb颜色
    178         '''
    179         return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
    180  
    181     from PIL import Image, ImageDraw, ImageFont#要先安装pillow模块:pip install pillow
    182     img_obj = Image.new('RGB', (120, 40), get_random_color())#实例化图片对象
    183     draw_obj = ImageDraw.Draw(img_obj)#创建图片
    184  
    185     font_path = os.path.join(settings.BASE_DIR, r'static_filesfontsBRUX.otf')#字体路径(字体自己下载)
    186     print('>>>>', font_path)
    187     # font_obj = ImageFont.truetype(font_path, 26)#路径拼接注意不能有中文,否则报错
    188     font_obj = ImageFont.truetype(r'static_files/fonts/BRUX.otf', 26) #相对路径r'static_files/fonts/BRUX.otf'
    189     # font_obj = ImageFont.load_default().font#系统默认字体
    190     sum_str = ''
    191     for i in range(6):#生成随机的字母数字组合
    192         a = random.choice([str(random.randint(0, 9)), chr(random.randint(97, 122)),
    193                            chr(random.randint(65, 90))])  # 4  a  5  D  6  S
    194         sum_str += a
    195     print(sum_str)
    196     draw_obj.text((12, 2), sum_str, fill=get_random_color(), font=font_obj)
    197  
    198     width = 120
    199     height = 40
    200     # 添加噪线
    201     for i in range(5):#循环一次就是一条线:两点确定一条
    202         x1 = random.randint(0, width)
    203         x2 = random.randint(0, width)
    204         y1 = random.randint(0, height)
    205         y2 = random.randint(0, height)
    206         draw_obj.line((x1, y1, x2, y2), fill=get_random_color())
    207     # # 添加噪点
    208     for i in range(10):
    209         # 这是添加点,50个点
    210         draw_obj.point([random.randint(0, width), random.randint(0, height)], fill=get_random_color())
    211         # 下面是添加很小的弧线,看上去类似于一个点,50个小弧线
    212         x = random.randint(0, width)
    213         y = random.randint(0, height)
    214         draw_obj.arc((x, y, x + 4, y + 4), 0, 90, fill=get_random_color())
    215  
    216     from io import BytesIO#生成的图片格式指定和存在位置(缓存)
    217     f = BytesIO()
    218     img_obj.save(f, 'png')
    219     data = f.getvalue()
    220  
    221     # 验证码对应的数据保存到session里面
    222     request.session['valid_str'] = sum_str
    223  
    224     return HttpResponse(data)
    225  
    226 # 登录
    227 def login(request):
    228     if request.method == 'GET':
    229         return render(request, 'login.html')
    230     elif request.method == 'POST':
    231         # print(request.POST)
    232         username = request.POST.get('username')
    233         password = request.POST.get('password')
    234         cverification_code=request.POST.get('cverification_code')
    235  
    236         if cverification_code.upper()==request.session.get('valid_str').upper():
    237  
    238             user_obj = auth.authenticate(username=username, password=password)
    239             print(user_obj)
    240             if user_obj:
    241                 auth.login(request, user_obj)
    242                 return JsonResponse({'status': 1, 'url': reverse('index')})
    243             else:
    244                 return JsonResponse({'status': 0, 'url': '账号或密码有误!'})
    245         else:
    246             return JsonResponse({'status': 0, 'url': '验证码输入有误!'})
    247  
    248  
    249 #状态认证的首页访问(使用装饰器认证状态失败,会自动跳转一个路径,可以在settings中配置指定LOGIN_URL='/login/')
    250 #同时在页面的请求路径会自动加上'?next=/index/'(当前页面路径),
    251 # 借此可以在前端通过location.search获取后slice切边获取路径,登录成功之后在success回调函数location.href指向该路径,自动跳转访问的页面
    252 @login_required
    253 def index(request):
    254     # if request.user.is_authenticated:
    255     print(request.user)
    256     if request.method == 'GET':
    257         return render(request, 'index.html')
    258 # else:
    259 #     return redirect('login')
    260  
    261  
    262 #不加装饰器的方法判断状态
    263 '''
    264 def index(request):
    265     if request.user.is_authenticated:
    266         print(request.user)
    267         if request.method == 'GET':
    268             return render(request, 'index.html')
    269     else:
    270         return redirect('login')
    271 '''
    272  
    273  
    274 #注销
    275 def logout(request):
    276     auth.logout(request)
    277     return redirect('login')
    278  
    279 #修改密码
    280 def reset_psd(request):
    281     if request.user.is_authenticated:
    282         if request.method == 'GET':
    283             return render(request, 'reset_psd.html')
    284         elif request.method == 'POST':
    285             old_password = request.POST.get('old_password')
    286             new_password = request.POST.get('new_password')
    287             r_new_password = request.POST.get('r_new_password')
    288             # ret=request.user.check_password(old_password)
    289             # print(ret)
    290             if request.user.check_password(old_password):
    291                 if new_password == r_new_password:
    292                     request.user.set_password(new_password)
    293                     request.user.save()
    294                     return JsonResponse({'status': True, 'info': '操作成功!', 'url': reverse('index')})
    295                 else:
    296                     return JsonResponse({'status': False, 'info': '两次新密码不一致!', 'url': ''})
    297             else:
    298                 return JsonResponse({'status': False, 'info': '操作失败:原密码输入有误!', 'url': ''})
    299         return JsonResponse({'status': False, 'info': '操作失败!', 'url': ''})
    300  
    301     else:
    302         return redirect('login')
    views.py

     urls.py

     1 from django.conf.urls import url
     2 from django.contrib import admin
     3 from app01 import views
     4  
     5 urlpatterns = [
     6     url(r'^admin/', admin.site.urls),
     7     url(r'^register/', views.register, name='register'),
     8     url(r'^login/', views.login, name='login'),
     9     url(r'^index/', views.index, name='index'),
    10     url(r'^logout/', views.logout, name='logout'),
    11     url(r'^reset_psd/', views.reset_psd, name='reset_psd'),
    12     url(r'^get_cverification_code/', views.get_cverification_code, name='get_cverification_code'),#随机验证码
    13  
    14 ]
    urls.py

    templates

    register.html

     1 {% load static %}
     2 <!DOCTYPE html>
     3 <html lang="en">
     4 <head>
     5     <meta charset="UTF-8">
     6     <link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
     7  
     8     <title>用户注册</title>
     9 </head>
    10 <body style="background-image: url('{% static 'images/register_bg.gif' %}');background-size: cover">
    11 <div class="container">
    12     <div class="row">
    13         <div class="col-xs-6 col-xs-offset-3" style="margin-top: 12%;">
    14             <div class="container-fluid" style="background-color: rgba(255,255,255,0.2);border-radius: 5%">
    15                 <div class="row">
    16                     <h2 class="text-left col-xs-8 text-primary">新用户注册:</h2>
    17                 </div>
    18                 <div class="row" >
    19                     <form action="{% url 'register' %}" method="post" novalidate class="form-horizontal">
    20                         {% csrf_token %}
    21                         {% for field in register_obj %}
    22                             <div class="form-group" >
    23                                 <label for="{{ field.id_for_label }}"
    24                                        class="col-xs-3 control-label" >{{ field.label }}</label>
    25                                 <div class="col-xs-7">
    26                                     {{ field }}
    27                                     <div style="height: 10px;" class="text-danger">{{ field.errors.0 }}</div>
    28                                 </div>
    29                             </div>
    30                         {% endfor %}
    31                         <div class="form-group">
    32                             <div class="col-sm-7  col-xs-offset-3">
    33                                 <span class="col-xs-10 text-success text-center"
    34                                       style="line-height: 200%">已有账号,请<a href="{% url 'login' %}">登录</a></span>
    35                                 <input type="submit" class="btn btn-success btn-sm col-xs-2 pull-right">
    36  
    37                             </div>
    38                         </div>
    39                     </form>
    40                 </div>
    41             </div>
    42         </div>
    43     </div>
    44 </div>
    45  
    46 </body>
    47 <script src="{% static 'jquery-3.4.1.js' %}"></script>
    48 <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
    49 </html>
    register.html

      login.html

      1 {% load static %}
      2 <!DOCTYPE html>
      3 <html lang="en">
      4 <head>
      5     <meta charset="UTF-8">
      6     <link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
      7     <title>用户登录</title>
      8 </head>
      9 <body style="background-image: url('{% static "images/login_bg.jpg" %}');background-size: cover">
     10 <div>
     11     <div class="container">
     12         <div class="row">
     13             <div class='col-xs-4 col-xs-offset-4'>
     14                 <div class="row" style="margin-top: 50%;background-color: rgba(255,255,255,0.2 );border-radius: 3%">
     15                     <div class="row c1">
     16                         <h2 class=" col-xs-6  text-primary" style="margin-bottom: 30px">用户登录</h2>
     17                     </div>
     18                     <div class="row">
     19                         <div class="form-group" style="height: 60px;">
     20                             <label for="username" class="col-xs-3 control-label text-right">用户名:</label>
     21                             <div class="col-xs-8">
     22                                 <input type="text" class="form-control" id="username">
     23                                 <div class="text-danger"></div>
     24                             </div>
     25                         </div>
     26                         <div class="form-group" style="height: 60px;">
     27                             <label for="password" class="col-xs-3 control-label text-right">密码:</label>
     28                             <div class="col-xs-8">
     29                                 <input type="password" class="form-control" id="password">
     30                                 <div class="text-danger"></div>
     31                             </div>
     32                         </div>
     33  
     34                         <div class="form-group" style="height: 60px;">
     35                             <label for="code" class="col-xs-3 control-label text-right">验证码:</label>
     36                             <div class="col-xs-4">
     37                                 <input type="text" class="form-control" id="code">
     38                                 <div class="text-danger"></div>
     39                             </div>
     40                             <div class="col-xs-5" style="padding-left: 0"><img src="{% url 'get_cverification_code' %}"
     41                                                                                alt="" id="cverification_code"></div>
     42                         </div>
     43  
     44                         <div class="form-group" style="height: 60px;">
     45                             {% csrf_token %}
     46                             <div class="col-xs-8 col-xs-offset-3">
     47                                 <a href="{% url 'register' %}">
     48                                     <button class="btn btn-primary col-xs-offset-2" id="register">注册</button>
     49                                 </a>
     50                                 <button class="btn btn-success col-xs-offset-2" id="submit">登录</button>
     51                                 <div class=" text-danger"></div>
     52                             </div>
     53                         </div>
     54                     </div>
     55                 </div>
     56             </div>
     57         </div>
     58     </div>
     59 </div>
     60  
     61 </div>
     62 </div>
     63 </body>
     64 <script src="{% static 'jquery-3.4.1.js' %}"></script>
     65 <script src="{% static 'jquery-cookie-1.4.1.js' %}"></script>
     66 <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
     67 <script>
     68     $(function () {
     69         
     70         $('#cverification_code').on('click',function () {
     71             var src='{% url "get_cverification_code" %}?temp='+Math.random();
     72             console.log(src);
     73             $('#cverification_code').attr('src',src);
     74         });
     75         
     76         
     77         
     78         $('#username').blur(function () {
     79             if (username !== '') {
     80                 $('#username').next().text('');
     81             }
     82         });
     83         $('#password').blur(function () {
     84             if (username !== '') {
     85                 $('#password').next().text('');
     86             }
     87         });
     88         $('#code').blur(function () {
     89             if (username !== '') {
     90                 $('#code').next().text('');
     91             }
     92         });
     93         $('#username').focus(function () {
     94             if (username !== '') {
     95                 $('#submit').next().text('');
     96             }
     97         });
     98         $('#password').focus(function () {
     99             if (username !== '') {
    100                 $('#submit').next().text('');
    101             }
    102         });
    103         $('#code').focus(function () {
    104             if (username !== '') {
    105                 $('#code').next().text('');
    106             }
    107         });
    108  
    109  
    110         $('#submit').click(function () {
    111  
    112             var username = $('#username').val().trim();
    113             var password = $('#password').val().trim();
    114             var cverification_code = $('#code').val().trim();
    115             console.log(cverification_code);
    116             console.log(cverification_code.length);
    117  
    118  
    119             if (username === '' || password === '' || cverification_code.length !== 6) {
    120                 if (username === '') {
    121                     $('#username').next().text('用户名不能为空!');
    122                 }
    123                 ;
    124                 if (password === '') {
    125                     $('#password').next().text('密码不能为空!')
    126                 }
    127                 ;
    128                 if (cverification_code.length !== 6) {
    129                     $('#code').next().text('验证码为6位!');
    130                 }
    131                 ;
    132                 console.log(cverification_code.length);
    133                 if (cverification_code.length !== 6) {
    134                     $('#code').next().text('验证码为6位!');
    135                     return false
    136                 }
    137                 ;
    138  
    139             } else {
    140                 $.ajax({
    141                     url: '{% url 'login' %}',
    142                     type: 'POST',
    143                     headers: {'X-CSRFToken': $.cookie('csrftoken')},
    144                     data: {
    145                         'username': username,
    146                         'password': password,
    147                         'cverification_code': cverification_code,
    148  
    149                     },
    150                     success: function (request) {
    151                         console.log(request);
    152                         if (request.status === 1) {
    153                             location.href = request.url;
    154                         } else {
    155                             $('#submit').next().text(request.url);
    156                         }
    157                     }
    158                 })
    159             }
    160  
    161         })
    162     })
    163 </script>
    164 </html>
    login.html

      index. Html

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>首页</title>
     6 </head>
     7 <body>
     8 <h1>index</h1>
     9 <a href="{%  url 'logout' %}"><h6>注销</h6></a>
    10 <a href="{% url 'reset_psd' %}">修改密码</a>
    11 </body>
    12 </html>
    login.html

      reset_psd.html

     1 {% load static %}
     2 <!DOCTYPE html>
     3 <html lang="en">
     4 <head>
     5     <meta charset="UTF-8">
     6     <link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
     7     <title>修改密码</title>
     8 </head>
     9 <body>
    10 <div><h3>当前用户:{{ username }}</h3>
    11  
    12         <p>请输入原密码:<input type="password" id="old_password"></p>
    13         <P>请输入新密码:<input type="password" id="new_password"></P>
    14         <p>请确认新密码:<input type="password" id="r_new_password"></p>
    15         {% csrf_token %}
    16         <p><button class="btn btn-success" id="submit">保存</button></p>
    17  
    18 </div>
    19 </body>
    20 <script src="{% static 'jquery-3.4.1.js' %}"></script>
    21 <script src="{% static 'jquery-cookie-1.4.1.js' %}"></script>
    22 <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
    23 <script>
    24     $(function () {
    25         $('#submit').click(function () {
    26             var old_password=$('#old_password').val().trim();
    27             var new_password=$('#new_password').val().trim();
    28             var r_new_password=$('#r_new_password').val().trim();
    29  
    30             if(old_password===''||new_password==='' || r_new_password===''){
    31                 alert('不允许有空!');
    32                 return false
    33             };
    34  
    35             if(new_password!==r_new_password){
    36                 alert('两次输入的新密码不一致,请重新确认输入!');
    37                 return false
    38             };
    39  
    40  
    41             $.ajax({
    42                 url:'{% url "reset_psd" %}',
    43                 type:'post',
    44                 headers:{'X-CSRFToken':$.cookie('csrftoken')},
    45                 data:{
    46                     old_password:old_password,
    47                     new_password:new_password,
    48                     r_new_password:r_new_password,
    49                 },
    50                 success:function (response) {
    51                     if(response.status===true){
    52                         alert(response.info);
    53                         location.href=response.url;
    54                     }
    55                     else {
    56                         alert(response.info)
    57                     }
    58                 }
    59  
    60             }
    61             )
    62         })
    63     })
    64 </script>
    65 </html>
    reset_psd.html
  • 相关阅读:
    Apache Common-IO 使用
    Apache Compress-使用
    使用JavaConfig方式-Spring 基础学习
    设计模式-策略模式
    logback mybatis 打印sql语句
    oracle 迭代查询
    使用 Dom4j 将 XML 转换为 MAP
    Java连接Access数据库的那些坑
    如何从Maven中央存储库下载?
    sublime构建各个编译环境
  • 原文地址:https://www.cnblogs.com/open-yang/p/11223418.html
Copyright © 2011-2022 走看看