• crm 系统项目(一) 登录,注册,校验


    crm 系统项目(一) 登录,注册,校验

    首先创建一个Django项目,关于配置信息不多说,前面有~

    models.py文件下创建需要的表格信息,之后导入数据库

    from django.db import models
    from multiselectfield import MultiSelectField
    
    course_choices = (('Linux', 'Linux中高级'),
                      ('PythonFullStack', 'Python高级全栈开发'),)
    
    class_type_choices = (('fulltime', '脱产班',),
                          ('online', '网络班'),
                          ('weekend', '周末班',),)
    
    source_type = (('qq', "qq群"),
                   ('referral', "内部转介绍"),
                   ('website', "官方网站"),
                   ('baidu_ads', "百度推广"),
                   ('office_direct', "直接上门"),
                   ('WoM', "口碑"),
                   ('public_class', "公开课"),
                   ('website_luffy', "路飞官网"),
                   ('others', "其它"),)
    
    enroll_status_choices = (('signed', "已报名"),
                             ('unregistered', "未报名"),
                             ('studying', '学习中'),
                             ('paid_in_full', "学费已交齐"))
    
    seek_status_choices = (('A', '近期无报名计划'), ('B', '1个月内报名'), ('C', '2周内报名'), ('D', '1周内报名'),
                           ('E', '定金'), ('F', '到班'), ('G', '全款'), ('H', '无效'),)
    pay_type_choices = (('deposit', "订金/报名费"),
                        ('tuition', "学费"),
                        ('transfer', "转班"),
                        ('dropout', "退学"),
                        ('refund', "退款"),)
    
    attendance_choices = (('checked', "已签到"),
                          ('vacate', "请假"),
                          ('late', "迟到"),
                          ('absence', "缺勤"),
                          ('leave_early', "早退"),)
    
    score_choices = ((100, 'A+'),
                     (90, 'A'),
                     (85, 'B+'),
                     (80, 'B'),
                     (70, 'B-'),
                     (60, 'C+'),
                     (50, 'C'),
                     (40, 'C-'),
                     (0, ' D'),
                     (-1, 'N/A'),
                     (-100, 'COPY'),
                     (-1000, 'FAIL'),)
    
    
    class Department(models.Model):
        """
        部门表
        """
        name = models.CharField(max_length=32, verbose_name="部门名称")
        count = models.IntegerField(verbose_name="人数", default=0)
    
        # class Meta:
        #     db_table = 'xxx'   # 表名
    
    
    class UserProfile(models.Model):
        """
        用户表
        """
        username = models.EmailField(max_length=255, unique=True,)
        password = models.CharField(max_length=128)
        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)
        is_active = models.BooleanField(default=True)
    
    
    class Customer(models.Model):
        """
        客户表
        """
        qq = models.CharField('QQ', max_length=64, unique=True, help_text='QQ号必须唯一')
        qq_name = models.CharField('QQ昵称', max_length=64, blank=True, null=True)
        name = models.CharField('姓名', max_length=32, blank=True, null=True, help_text='学员报名后,请改为真实姓名')
        sex_type = (('male', ''), ('female', ''))
        sex = models.CharField("性别", choices=sex_type, max_length=16, default='male', blank=True, null=True)
        birthday = models.DateField('出生日期', default=None, help_text="格式yyyy-mm-dd", blank=True, null=True)
        phone = models.BigIntegerField('手机号', blank=True, null=True)
        source = models.CharField('客户来源', max_length=64, choices=source_type, default='qq')
        introduce_from = models.ForeignKey('self', verbose_name="转介绍自学员", blank=True, null=True)
        course = MultiSelectField("咨询课程", choices=course_choices)
        class_type = models.CharField("班级类型", max_length=64, choices=class_type_choices, default='fulltime')
        customer_note = models.TextField("客户备注", blank=True, null=True, )
        status = models.CharField("状态", choices=enroll_status_choices, max_length=64, default="unregistered",
                                  help_text="选择客户此时的状态")
        network_consult_note = models.TextField(blank=True, null=True, verbose_name='网络咨询师咨询内容')
        date = models.DateTimeField("咨询日期", auto_now_add=True)
        last_consult_date = models.DateField("最后跟进日期", auto_now_add=True)
        next_date = models.DateField("预计再次跟进时间", blank=True, null=True)
        network_consultant = models.ForeignKey('UserProfile', blank=True, null=True, verbose_name='咨询师',
                                               related_name='network_consultant')
        consultant = models.ForeignKey('UserProfile', verbose_name="销售", related_name='customers', blank=True, null=True, )
        class_list = models.ManyToManyField('ClassList', verbose_name="已报班级", )
    
    
    class Campuses(models.Model):
        """
        校区表
        """
        name = models.CharField(verbose_name='校区', max_length=64)
        address = models.CharField(verbose_name='详细地址', max_length=512, blank=True, null=True)
    
    
    class ClassList(models.Model):
        """
        班级表
        """
        course = models.CharField("课程名称", max_length=64, choices=course_choices)
        semester = models.IntegerField("学期")
        campuses = models.ForeignKey('Campuses', verbose_name="校区")
        price = models.IntegerField("学费", default=10000)
        memo = models.CharField('说明', blank=True, null=True, max_length=100)
        start_date = models.DateField("开班日期")
        graduate_date = models.DateField("结业日期", blank=True, null=True)
        teachers = models.ManyToManyField('UserProfile', verbose_name="老师")
        class_type = models.CharField(choices=class_type_choices, max_length=64, verbose_name='班额及类型', blank=True,
                                      null=True)
    
        class Meta:
            unique_together = ("course", "semester", 'campuses')
    
    
    class ConsultRecord(models.Model):
        """
        跟进记录表
        """
        customer = models.ForeignKey('Customer', verbose_name="所咨询客户")
        note = models.TextField(verbose_name="跟进内容...")
        status = models.CharField("跟进状态", max_length=8, choices=seek_status_choices, help_text="选择客户此时的状态")
        consultant = models.ForeignKey("UserProfile", verbose_name="跟进人", related_name='records')
        date = models.DateTimeField("跟进日期", auto_now_add=True)
        delete_status = models.BooleanField(verbose_name='删除状态', default=False)
    
    
    class Enrollment(models.Model):
        """
        报名表
        """
    
        why_us = models.TextField("为什么报名", max_length=1024, default=None, blank=True, null=True)
        your_expectation = models.TextField("学完想达到的具体期望", max_length=1024, blank=True, null=True)
        contract_agreed = models.BooleanField("我已认真阅读完培训协议并同意全部协议内容", default=False)
        contract_approved = models.BooleanField("审批通过", help_text="在审阅完学员的资料无误后勾选此项,合同即生效", default=False)
        enrolled_date = models.DateTimeField(auto_now_add=True, verbose_name="报名日期")
        memo = models.TextField('备注', blank=True, null=True)
        delete_status = models.BooleanField(verbose_name='删除状态', default=False)
        customer = models.ForeignKey('Customer', verbose_name='客户名称')
        school = models.ForeignKey('Campuses')
        enrolment_class = models.ForeignKey("ClassList", verbose_name="所报班级")
    
        class Meta:
            unique_together = ('enrolment_class', 'customer')
    
    
    class PaymentRecord(models.Model):
        """
        缴费记录表
        """
        pay_type = models.CharField("费用类型", choices=pay_type_choices, max_length=64, default="deposit")
        paid_fee = models.IntegerField("费用数额", default=0)
        note = models.TextField("备注", blank=True, null=True)
        date = models.DateTimeField("交款日期", auto_now_add=True)
        course = models.CharField("课程名", choices=course_choices, max_length=64, blank=True, null=True, default='N/A')
        class_type = models.CharField("班级类型", choices=class_type_choices, max_length=64, blank=True, null=True,
                                      default='N/A')
        enrolment_class = models.ForeignKey('ClassList', verbose_name='所报班级', blank=True, null=True)
        customer = models.ForeignKey('Customer', verbose_name="客户")
        consultant = models.ForeignKey('UserProfile', verbose_name="销售")
        delete_status = models.BooleanField(verbose_name='删除状态', default=False)
    
        status_choices = (
            (1, '未审核'),
            (2, '已审核'),
        )
        status = models.IntegerField(verbose_name='审核', default=1, choices=status_choices)
    
        confirm_date = models.DateTimeField(verbose_name="确认日期", null=True, blank=True)
        confirm_user = models.ForeignKey(verbose_name="确认人", to='UserProfile', related_name='confirms', null=True,
                                         blank=True)
    
    
    class CourseRecord(models.Model):
        """课程记录表"""
        day_num = models.IntegerField("节次", help_text="此处填写第几节课或第几天课程...,必须为数字")
        date = models.DateField(auto_now_add=True, verbose_name="上课日期")
        course_title = models.CharField('本节课程标题', max_length=64, blank=True, null=True)
        course_memo = models.TextField('本节课程内容', max_length=300, blank=True, null=True)
        has_homework = models.BooleanField(default=True, verbose_name="本节有作业")
        homework_title = models.CharField('本节作业标题', max_length=64, blank=True, null=True)
        homework_memo = models.TextField('作业描述', max_length=500, blank=True, null=True)
        scoring_point = models.TextField('得分点', max_length=300, blank=True, null=True)
        re_class = models.ForeignKey('ClassList', verbose_name="班级")
        teacher = models.ForeignKey('UserProfile', verbose_name="讲师")
    
        class Meta:
            unique_together = ('re_class', 'day_num')
    
    
    class StudyRecord(models.Model):
        """
        学习记录
        """
    
        attendance = models.CharField("考勤", choices=attendance_choices, default="checked", max_length=64)
        score = models.IntegerField("本节成绩", choices=score_choices, default=-1)
        homework_note = models.CharField(max_length=255, verbose_name='作业批语', blank=True, null=True)
        date = models.DateTimeField(auto_now_add=True)
        note = models.CharField("备注", max_length=255, blank=True, null=True)
        homework = models.FileField(verbose_name='作业文件', blank=True, null=True, default=None)
        course_record = models.ForeignKey('CourseRecord', verbose_name="某节课程")
        student = models.ForeignKey('Customer', verbose_name="学员")
    
        class Meta:
            unique_together = ('course_record', 'student')
    mdels.py

     urls.py

    from django.contrib import admin
    from django.conf.urls import url
    from app1 import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^login/', views.login),
        url(r'^index', views.index),
        url(r'^reg', views.reg),
    ]
    urls.py

    login.html  登录页面

      css样式以及js用到 Bootscraipt

    {% load static %}
    {#静态文件的方式#}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>登录界面</title>
        <link rel="stylesheet" href="{% static 'css/reset.css' %}">
        <link rel="stylesheet" href="{% static 'css/style.css' %}">
    </head>
        <div id="particles-js">
        <div class="login">
            <div class="login-top">
                登录
            </div>
            <form action="" method="post">
               {% csrf_token %}    {# 由于没有注释中间件csrf, 需要在form 后 加此, 否则post失败#}
                <div class="login-center clearfix">
                    <div class="login-center-img"><img src="{% static 'img/name.png' %}"></div>
                    <div class="login-center-input">
                        <input type="text" name="user" 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 'img/password.png' %}"></div>
                    <div class="login-center-input">
                        <input type="password" name="pwd" value="" placeholder="请输入您的密码" onfocus="this.placeholder=''"
                               onblur="this.placeholder='请输入您的密码'">
                        <div class="login-center-input-text">密码</div>
                    </div>
                </div>
                <p style="color: red;text-align: center">{{ err_msg }}</p>
                <div style="text-align: center">
                    <button class="login-button">登录</button>
                </div>
            </form>
        </div>
        <div class="sk-rotating-plane"></div>
        <canvas class="particles-js-canvas-el" width="1343" height="163" style=" 100%; height: 100%;"></canvas>
    </div>
    
    <script src="{% static 'js/particles.min.js' %}"></script>
    <script src="{% static 'js/app.js' %}"></script>
    <script type="text/javascript">
        function hasClass(elem, cls) {
            cls = cls || '';
            if (cls.replace(/s/g, '').length == 0) return false; //当cls没有参数时,返回false
            return new RegExp(' ' + cls + ' ').test(' ' + elem.className + ' ');
        }
    
        function addClass(ele, cls) {
            if (!hasClass(ele, cls)) {
                ele.className = ele.className == '' ? cls : ele.className + ' ' + cls;
            }
        }
    
        function removeClass(ele, cls) {
            if (hasClass(ele, cls)) {
                var newClass = ' ' + ele.className.replace(/[	
    ]/g, '') + ' ';
                while (newClass.indexOf(' ' + cls + ' ') >= 0) {
                    newClass = newClass.replace(' ' + cls + ' ', ' ');
                }
                ele.className = newClass.replace(/^s+|s+$/g, '');
            }
        }
    
        document.querySelector(".login-button").onclick = function () {
            addClass(document.querySelector(".login"), "active")
            setTimeout(function () {
                addClass(document.querySelector(".sk-rotating-plane"), "active")
                document.querySelector(".login").style.display = "none"
            }, 800)
            setTimeout(function () {
                removeClass(document.querySelector(".login"), "active")
                removeClass(document.querySelector(".sk-rotating-plane"), "active")
                document.querySelector(".login").style.display = "block"
                alert("登录成功")
    
            }, 5000)
        }
    </script>
    </html>
    View Code

    reg.html  注册页面

      css样式以及js用到 Bootscraipt,

      form 标签加上novalidate 前段不进行校验 

      {{ form_obj.as_p }} ——》 生成所有的p标签 label input

      {{ form_obj.errors }} ——》所有字段的错误

      {{ form_obj.user }} ——》 该字段的input框
      {{ form_obj.user.label }} ——》 该字段的label 中文提示
      {{ form_obj.user.id_for_label }} ——》 该字段的id
      {{ form_obj.user.errors }} ——》 该字段的所有的错误信息
      {{ form_obj.user.errors.0 }} ——》 该字段的第一个的错误信息

    {% load static %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="{% static 'plugins/bootstrap/css/bootstrap.css' %}">
    </head>
    <body>
    
    <div class="container">
        <div class="row" style="margin-top: 70px">
            <div class="col-sm-6 col-sm-offset-3">
                <form class="form-horizontal" method="post" action="" novalidate>
                    {% csrf_token %}
    
                    <div class="form-group">
                        <label for="{{ form_obj.username.id_for_label }}"
                               class="col-sm-2 control-label">{{ form_obj.username.label }}</label>
                        <div class="col-sm-10">
                            {{ form_obj.username }}
                            {{ form_obj.username.errors.0 }}
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="{{ form_obj.password.id_for_label }}"
                               class="col-sm-2 control-label">{{ form_obj.password.label }}</label>
                        <div class="col-sm-10">
                            {{ form_obj.password }}
                            {{ form_obj.password.errors.0 }}
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="{{ form_obj.re_password.id_for_label }}"
                               class="col-sm-2 control-label">{{ form_obj.re_password.label }}</label>
                        <div class="col-sm-10">
                            {{ form_obj.re_password }}
                            {{ form_obj.re_password.errors.0 }}
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="{{ form_obj.name.id_for_label }}"
                               class="col-sm-2 control-label">{{ form_obj.name.label }}</label>
                        <div class="col-sm-10">
                            {{ form_obj.name }}
                            {{ form_obj.name.errors.0 }}
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="{{ form_obj.department.id_for_label }}"
                               class="col-sm-2 control-label">{{ form_obj.department.label }}</label>
                        <div class="col-sm-10">
                            {{ form_obj.department }}
                            {{ form_obj.department.errors.0 }}
                        </div>
                    </div>
    
                    <div class="form-group">
                        <div class="col-sm-offset-2 col-sm-10">
                            <button type="submit" class="btn btn-default">Sign in</button>
                        </div>
                    </div>
                </form>
            </div>
    
        </div>
    </div>
    
    </body>
    </html>
    reg.html

    app下新建 form.py  用于注册时 form表单 建立校验等

    from django import forms
    from app1 import models
    from django.core.exceptions import ValidationError
    import hashlib
    
    # md5加密
    def enc_md5(str=''):
        md = hashlib.md5() #创建MD5对象
        md.update(str.encode(encoding='utf-8'))
        return md.hexdigest()
    
    # 注册form
    class ReForm(forms.ModelForm):
        password = forms.CharField(widget=forms.PasswordInput(), label='密码', min_length=6)
        re_password = forms.CharField(widget=forms.PasswordInput(), label='确认密码', min_length=6)
    
        class Meta:     #通过models 自动创建表单
            model = models.UserProfile
            fields = "__all__"  # 所有字段
            # fields = ['username','password']
            exclude = ['is_active']  # 排除某些字段
    
            labels = {
                'username': '用户名',
                'password': '密码',
                # 're_password': '确认密码',
                'department': '部门',
            }
    
            widgets = {
                # 'password': forms.PasswordInput(attrs={'class': 'form-control'})
            }
    
            error_messages = {
                'username': {
                    'required': '不能为空',
                    'invalid': '格式错误'
                }
            }
        # 给某些表单添加bootscript 类名
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            for field in self.fields.values():
                field.widget.attrs.update({'class': 'form-control'})
        # 全局钩子验证
        def clean(self):
            pwd = self.cleaned_data.get('password')
            re_pwd = self.cleaned_data.get('re_password')
            if pwd == re_pwd and pwd:
                # 对密码进行加密
                # md5 = hashlib.md5()
                # md5.update(pwd.encode("utf-8"))
                # pwd = md5.hexdigest()
                # print(pwd)
                enc_md5(pwd)
                print(enc_md5(pwd))
                self.cleaned_data['password'] = pwd
                return self.cleaned_data
            self.add_error('re_password', '两次密码不一致')
            raise ValidationError('两次密码不一致')
    View Code

    views.py  视图

    from django.shortcuts import render, redirect, HttpResponse
    from app1 import models
    import hashlib
    from app1.forms import ReForm
    
    # md5加密
    def enc_md5(str=''):
        md = hashlib.md5() #创建MD5对象
        md.update(str.encode(encoding='utf-8'))
        return md.hexdigest()
    
    
    def index(request):
        HttpResponse('hahahhahh')
    
    # 登录
    def login(request):
        err_msg = ''
        if request.method == 'POST':
            user = request.POST.get('user')
            pwd = request.POST.get('pwd')
            print(user)
            # md5 = hashlib.md5()
            # md5.update(pwd.encode('utf-8'))
            # pwd = md5.hexdigest()
            enc_md5(pwd)
            # 按照输入账户密码从数据库中查找
            obj = models.UserProfile.objects.filter(username=user, password=pwd, is_active=True).first()
            if obj:
                return redirect('/index/')
            err_msg = '用户名或密码错误'
        return render(request, 'login.html', {'err_msg': err_msg})
    
    # 注册
    def reg(request):
        form_obj = ReForm()     #form表单校验之后的结果
        if request.method == 'POST':
            form_obj = ReForm(request.POST)     #把 POST 请求放入到form 验证
            if form_obj.is_valid():     #如果通过验证
                form_obj.save()         #保存数据
                return redirect('/login/')
        return render(request, 'reg.html',{'form_obj':form_obj})
    View Code

    效果图:

      登录  >>>>>>>>>

      注册  >>>>>>>>>>>>>>

  • 相关阅读:
    Away3d学习笔记2三维世界的四个基本构件
    实验报告2
    实验报告
    WPF基础——Application
    COM技术内幕(笔记)
    关于一个GetLevelDesc函数 的认知问题
    UI库阶段性进展(完成文字列表,样式列表(样式列表可继承))
    UI库阶段性进展
    UI库阶段性进展(按钮初具雏形)
    UI库阶段性进展(button在文本对齐的基础上增加文本偏移让文本位置更精准)
  • 原文地址:https://www.cnblogs.com/konghui/p/10127925.html
Copyright © 2020-2023  润新知