第五十七篇 Django-CRM系统-1登录,注册,修改密码

一、CRM框架简介

在这里插入图片描述

二、登录之设计表

在登录之前,我们需要用到django内置的登录验证去做,必须得使用django定义好的表结构或者我们重写表,使用一些我们需要的字段来进行验证。没有重写之前的表为USER表,它所在的位置为:from django.contrib.auth.models import User

源码:User继承了AbstractUser表

class User(AbstractUser):
    """
    Users within the Django authentication system are represented by this
    model.

    Username and password are required. Other fields are optional.
    """
    class Meta(AbstractUser.Meta):
        swappable = 'AUTH_USER_MODEL'

源码:AbstractUser继承了AbstractBaseUser和PermissionsMixin

class AbstractUser(AbstractBaseUser, PermissionsMixin):
    """
    An abstract base class implementing a fully featured User model with
    admin-compliant permissions.

    Username and password are required. Other fields are optional.
    """
    username_validator = UnicodeUsernameValidator()

    username = models.CharField(

我们只需要重写AbstractUser表,示例如下:

from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager, User

class UserProfile(AbstractBaseUser, PermissionsMixin):
    username = models.EmailField(
        max_length=255,
        unique=True,
    )
    is_staff = models.BooleanField(
        _('staff status'),
        default=False,
        help_text=_('Designates whether the user can log into this admin site.'),
    )
    is_admin = models.BooleanField(default=False)
    name = models.CharField('名字', max_length=32)
    department = models.ForeignKey('Department', default=None, blank=True, null=True)
    mobile = models.CharField('手机', max_length=32, default=None, blank=True, null=True)

    memo = models.TextField('备注', blank=True, null=True, default=None)
    date_joined = models.DateTimeField(auto_now_add=True)

    USERNAME_FIELD = 'username'   #定义使用的账户字段
    REQUIRED_FIELDS = ['name']

    class Meta:
        verbose_name = '账户信息'
        verbose_name_plural = "账户信息"

    def get_full_name(self):
        # The user is identified by their email address
        return self.name

    def get_short_name(self):
        # The user is identified by their email address
        return self.username

    def __str__(self):  # __unicode__ on Python 2
        return self.username

    def has_perm(self, perm, obj=None):
        #     "Does the user have a specific permission?"
        # Simplest possible answer: Yes, always

        if self.is_active and self.is_superuser:
            return True
        return _user_has_perm(self, perm, obj)

    def has_perms(self, perm_list, obj=None):
        #     "Does the user have a specific permission?"
        # Simplest possible answer: Yes, always
        for perm in perm_list:
            if not self.has_perm(perm, obj):
                return False
        return True

    def has_module_perms(self, app_label):
        #     "Does the user have permissions to view the app `app_label`?"
        #     Simplest possible answer: Yes, always
        if self.is_active and self.is_superuser:
            return True

        return _user_has_module_perms(self, app_label)

当需要这张表生效时,需要在settings.py中加入AUTH_USER_MODEL = 'crm.UserProfile'

三、登录视图函数和路由

urls.py

from django.conf.urls import url,include
from django.contrib import admin
from crm import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^login/', views.login,name='login'),
    url(r'^register/', views.register,name='register'),
    url(r'^index/', views.index,name='index'),
    url(r'^logout/', views.logout,name='logout'),
    url(r'^change_pwd/', views.change_pwd,name='change_pwd'),
    url(r'^crm/', include('crm.urls')),
]

Model == 强大的数据库操作,弱小的数据验证
Form ==强大的数据验证
ModelForm ==二者结合,强大的数据验证,适中的数据库操作。在ModelForm是能够封装一个model对象

froms.py

from django import forms
from crm import models
from django.core.exceptions import ValidationError


# 注册form
class RegForm(forms.ModelForm):
    password = forms.CharField(   #重写models中定义的字段
        label='密码',
        widget=forms.widgets.PasswordInput(attrs={'placeholder': '请输入密码'}),
        min_length=6,
        error_messages={'required': '密码不能为空', 'min_length': '最小长度为6'}
    )
    re_password = forms.CharField(   #新定义的字段
        label='确认密码',
        widget=forms.widgets.PasswordInput(attrs={'placeholder': '请再次确认密码'}),
        min_length=6,
        error_messages={'required': '密码不能为空', 'min_length': '最小长度为6'}
    )

    class Meta:
        model = models.UserProfile
        # fields = '__all__'   # 所有字段
        fields = ['username', 'password', 're_password', 'name', 'department']  # 指定字段
        # exclude = [''] #排除的字段
        widgets = { #定义插件,加入属性提示信息
            'username': forms.widgets.EmailInput(attrs={'placeholder': '请输入用户名'}),
            'name': forms.widgets.TextInput(attrs={'placeholder': '请输入姓名'}),

        }

        labels = {  #显示名称
            'username': '用户名',
            'password': '密码',
            'name': '姓名',
            'department': '部门',
        }

        error_messages = {
            'username': {
                'required': '账号不能为空',
            },
            'name': {
                'required': '姓名不能为空',
            }
        }

	#遍历所有字段
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for filed in self.fields.values():
            filed.widget.attrs.update({'class': 'form-control'})
	
	#对clean_data的数据先进行一次验证
    def clean(self):
        pwd = self.cleaned_data.get('password')
        re_pwd = self.cleaned_data.get('re_password')
        if pwd == re_pwd:
            return self.cleaned_data
        self.add_error('re_password', '两次密码不一致')
        raise ValidationError('两次密码不一致')

views.py

from django.shortcuts import render, HttpResponse, reverse, redirect
from django.contrib import auth
from django.contrib.auth.decorators import login_required  #登录校验
from .models import UserProfile  #用户表
from crm.forms import RegForm

def login(request):
    if request.method == "POST":
        username = request.POST.get('username')
        password = request.POST.get('password')
        print(username, password)
        ok = auth.authenticate(username=username, password=password)
        #Django提供的auth方法去数据库中验证用户
        if ok:
            auth.login(request, ok)
            return redirect(reverse('customer'))

    return render(request, 'login.html')


def register(request):
    form_obj = RegForm()  #实例化字段
    if request.method == "POST":
        form_obj = RegForm(request.POST)
        if form_obj.is_valid():
            print("校验成功")
            form_obj.cleaned_data.pop('re_password')  # 剔除重复的密码
            UserProfile.objects.create_user(**form_obj.cleaned_data)
            return redirect(reverse('login'))

    return render(request, 'register.html', context={"form_obj": form_obj})


@login_required
def index(request):
    return render(request, 'index.html')

#注销登录
def logout(request):
    auth.logout(request) 

    return redirect(reverse('login'))

#改密
def change_pwd(request):
    error = ''
    if request.method == "POST":
        username = request.POST.get('username')
        password = request.POST.get('password')
        new_password = request.POST.get('new_password')
        re_new_password = request.POST.get('re_new_password')
        ok = auth.authenticate(username=username, password=password)
        print(request)
        if ok:
            auth.login(request, ok)
            print("原账户密码正确")
            if new_password:
                print("密码不是空")
                if new_password == re_new_password:
                    print("两次密码一致")
                    request.user.set_password(new_password)
                    request.user.save()
                    return redirect(reverse('login'))
                else:
                    error = "两次密码不一致"

            else:
                error = "密码不能为空"
        else:
            error = "原账户或密码不正确"

    return render(request, 'change_pwd.html', context={"error": error})

四、前端代码实现

1.配置settings.py

#当前端有时间显示时,会按照以下格式进行显示
DATETIME_FORMAT = 'Y-m-d H:i:s'
DATE_FORMAT = 'Y-m-d'

STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR,'static')
]

AUTH_USER_MODEL = 'crm.UserProfile'   #生效的账户表
LOGIN_URL = '/login/'  # 这里配置成你项目登录页面的路由

2.导入静态文件

bootstrap框架和jquey框架还有小图标框架等
前端框架 https://www.bootcdn.cn/
小图标框架 http://fontawesome.dashgame.com/
在这里插入图片描述
3.寻找模板
寻找合适的登录或者注册界面框架,提取需要代码和配置文件
在这里插入图片描述
4 login.html

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% static 'css/reset.css' %}">
    <link rel="stylesheet" href="{% static 'css/style.css' %}">

</head>
<body>
<div id="particles-js">
    <div class="login">
        <div class="login-top">
            登录
        </div>
        <div class="login-center clearfix">
            <div class="login-center-img"><img src="{% static 'imgs/name.png'%}"></div>
            <form action="" method="post">
                {% csrf_token %}
                <div class="login-center-input">
                    <input type="text" name="username" value="admin" placeholder="请输入您的用户名" onfocus="this.placeholder=''"
                           onblur="this.placeholder='请输入您的用户名'">
                    <div class="login-center-input-text">用户名</div>
                </div>
        </div>
        <div class="login-center clearfix">
            <div class="login-center-img"><img src="{% static 'imgs/password.png'%}"></div>
            <div class="login-center-input">
                <input type="password" name="password" value="" placeholder="请输入您的密码" onfocus="this.placeholder=''"
                       onblur="this.placeholder='请输入您的密码'">
                <div class="login-center-input-text">密码</div>
            </div>
        </div>
        <div style="text-align: center">
            <button class="login-button">登录</button>
        </div>
        <div style="text-align: right; margin-top:50px;margin-right:50px;font-size:18px;">
            <a href="{% url 'change_pwd'%}" style="margin-right:120px">修改密码</a>
            <a href="{% url 'register'%}">注册</a>
        </div>
    </div>
    </form>
    <div class="sk-rotating-plane"></div>
    <canvas class="particles-js-canvas-el" width="616" height="754" style="width: 100%; height: 100%;"></canvas>
</div>
<!--<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>-->

<script src="{% static 'js/particles.min.js' %}"></script>
<script src="{% static 'js/app.js' %}"></script>


</body>
</html>

5.register.html

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册页面</title>
    <style>
        input{
            width:300px;
            height:30px;
            padding:10px;
        }
        .i5{
            font-size:20px;
        }
        span{
            margin-right:50px;
        }
        button{
            margin-top:30px;
            width:60px;
            height:35px;
            text-align:center;
            margin-right:50px;

        }
        span{
            color:red;
        }
        .ii{
             margin-top:30px;
        }
    </style>
</head>
<body>
<div class="i" style="width:500px;margin:50px auto;">
    <h2>注册页面</h2>
    <form action="" method="post" novalidate>
        {% csrf_token %}
        <div class="i1 ii">{{ form_obj.username }}
        </div>
        <span>{{ form_obj.username.errors.0 }}</span>
        <div class="i2 ii">{{ form_obj.password }}
        </div>
        <span>{{ form_obj.password.errors.0 }}</span>
        <div class="i3 ii">{{ form_obj.re_password }}
        </div>
        <span>{{ form_obj.re_password.errors.0 }}</span>
        <div class="i4 ii">{{ form_obj.name }}
        </div>
        <span>{{ form_obj.name.errors.0 }}</span>
        <div class="i5 ii">部门:{{ form_obj.department }}
        </div>
        <span>{{ form_obj.department.errors.0 }}</span>
        <div class="submit">
            <button>提交</button>
        </div>
    </form>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>

<script>

    $('input').focus(function () {
        $('span').text('')
    })
</script>
</body>
</html>

6.change_pwd.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>修改密码</title>
    <style>
        {
            margin:0;

        }
        input{
            width:300px;
            height:30px;
            margin-bottom:20px;
            padding:10px;
        }
        button{
            width:60px;
            height:35px;
            text-align:center;
            margin-right:50px;

        }
        span{
            color:red;

        }
        .i5{
            margin-bottom:15px;
        }
    </style>
</head>
<body>
<div class="i" style="width:500px;margin:50px auto;">
    <h2>修改密码页面</h2>
<form action="" method="post" >
    {% csrf_token %}
<div class="i1"><input type="text" name="username" value="" placeholder="请输入账号"></div>
<div class="i2"><input type="password" name="password" value="" placeholder="请输入密码"></div>
<div class="i3"><input type="password" name="new_password" value="" placeholder="请输入您的新密码"></div>
<div class="i4"><input type="password" name="re_new_password" value="" placeholder="请再次输入您的新密码"></div>
    <div class="i5">
        <span>{{ error }}</span>
    </div>
    <button>提交</button>
</form>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>

<script>

    $('input').focus(function () {
        $('span').text('')
    })
</script>
</body>
</html>

五、效果

具体字段功能不一一演示了
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值