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

Posted konghui

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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="width: 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

 

效果图:

  登录  >>>>>>>>>

 

技术分享图片

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

技术分享图片

 

以上是关于crm 系统项目 登录,注册,校验的主要内容,如果未能解决你的问题,请参考以下文章

django项目 crm登录 注册

Django项目:CRM(客户关系管理系统)--49--40PerfectCRM实现全局账号注册+验证码+页面刷新保留信息

巨蟒django之CRM1 需求分析&&表结构设计&&注册登录验证

案例47-crm练习登录校验拦截器

Java高级项目实战之CRM系统用户登录功能实现

Django项目:CRM(客户关系管理系统)--46--37PerfectCRM实现CRM用户注册