项目参考代码

表结构代码

from django.db import models

# Create your models here.

from django.contrib.auth.models import AbstractUser



from django.db import models
from django.contrib import auth
from django.core.exceptions import PermissionDenied
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager, User
from django.utils.translation import ugettext_lazy as _
from multiselectfield import MultiSelectField
from django.utils.safestring import mark_safe

course_choices = (('LinuxL', '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 UserInfo(AbstractUser):
    tel=models.CharField(max_length=32,null=True,blank=True)
    gender=models.IntegerField(choices=((1,""),(2,"")),default=1)


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('Customer', verbose_name="转介绍自学员", blank=True, null=True,on_delete=models.CASCADE)
    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="选择客户此时的状态")
    date = models.DateTimeField("咨询日期", auto_now_add=True)
    last_consult_date = models.DateField("最后跟进日期", auto_now_add=True)
    next_date = models.DateField("预计再次跟进时间", blank=True, null=True)
    consultant = models.ForeignKey('UserInfo', verbose_name="销售", related_name='customers', blank=True, null=True,on_delete=models.CASCADE )
    class_list = models.ManyToManyField('ClassList', verbose_name="已报班级", )

    def __str__(self):
        return self.name+":"+self.qq


    def get_classlist(self):
        l=[]
        for cls in self.class_list.all():
            l.append(str(cls))
        return mark_safe(",".join(l))

class Campuses(models.Model):
    """
    校区表
    """
    name = models.CharField(verbose_name='校区', max_length=64)
    address = models.CharField(verbose_name='详细地址', max_length=512, blank=True, null=True)

    def __str__(self):
        return self.name




class ClassList(models.Model):
    """
    班级表
    """
    course = models.CharField("课程名称", max_length=64, choices=course_choices)
    semester = models.IntegerField("学期")
    campuses = models.ForeignKey('Campuses', verbose_name="校区",on_delete=models.CASCADE)
    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)
    #contract = models.ForeignKey('ContractTemplate', verbose_name="选择合同模版", blank=True, null=True,on_delete=models.CASCADE)
    teachers = models.ManyToManyField('UserInfo', 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')

    def __str__(self):
        return "{}{}({})".format(self.get_course_display(), self.semester, self.campuses)

#############################################################

# class ContractTemplate(models.Model):
#     """
#     合同模板表
#     """
#     name = models.CharField("合同名称", max_length=128, unique=True)
#     content = models.TextField("合同内容")
#     date = models.DateField(auto_now=True)
#
#
# 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')

登陆逻辑代码

def login(request):
    '''
    基于ajax和用户认证组件实现的登录功能
    :param request:
    :return:
    '''
    # if request.method=="POST":
    if request.is_ajax():
        # 将所需要的基本信息提取出来
        user=request.POST.get("user")
        pwd=request.POST.get("pwd")
        # 获取验证码:
        validcode=request.POST.get("validcode")

        #Ajax请求返回一个字典
        response={"user":None,"err_msg":""}
        # 判断验证码是否一致
        if validcode.upper() == request.session.get("keep_str").upper():
            user_obj=auth.authenticate(username=user,password=pwd)
            if user_obj:
                auth.login(request,user_obj) # request.session["user_id"]=user_obj.pk
                response["user"]=user
            else:
                response['err_msg']="用户名或者密码错误!"
        else:
            response["err_msg"]="验证码错误!"

        return JsonResponse(response)  # 一步完成序列化和反序列化
    else:
        return render(request, "login.html")
基于ajax和用户认证组件实现的登录功能

验证码逻辑代码

from PIL import Image,ImageDraw,ImageFont    #python中自带的验证码生成模块
import random    #为产生随机字母和数字做准备
from io import BytesIO  #为验证码做噪点和噪线
def get_valid_img(request):
    #产生随机的颜色框来放置验证码
    def get_random_color():
        import random
        return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
    img = Image.new("RGB", (350, 38), get_random_color())
    draw = ImageDraw.Draw(img)
    font = ImageFont.truetype("static/font/kumo.ttf", 32)

    keep_str = ""
    for i in range(6):  #参数为几位验证码
        random_num = str(random.randint(0, 9))
        random_lowalf = chr(random.randint(97, 122))
        random_upperalf = chr(random.randint(65, 90))
        random_char = random.choice([random_num, random_lowalf, random_upperalf])
        draw.text((i * 30 + 50, 0), random_char, get_random_color(), font=font)
        keep_str += random_char

    # #加噪点和躁线防止机器攻击
    # width = 350        #参数一定要与前面的随机框保持一致
    # height=38
    # for i in range(10):          #参数越大越识别
    #     x1 = random.randint(0, width)
    #     x2 = random.randint(0, width)
    #     y1 = random.randint(0, height)
    #     y2 = random.randint(0, height)
    #     draw.line((x1, y1, x2, y2), fill=get_random_color())
    #
    # for i in range(50):
    #     draw.point([random.randint(0, width), random.randint(0, height)], fill=get_random_color())
    #     x = random.randint(0, width)
    #     y = random.randint(0, height)
    #     draw.arc((x, y, x + 4, y + 4), 0, 90, fill=get_random_color())

    # 写与读
    f = BytesIO()
    img.save(f, "png")
    data = f.getvalue()

    print('keep_str', keep_str)

    # 将验证码存在各自的session中

    request.session['keep_str'] = keep_str

    return HttpResponse(data)
基于django有噪点和躁线的验证码

注册逻辑代码

def reg(request):

    if request.method=="POST":
        form=UserModelForm(request.POST)
        res={"user":None,"err_msg":""}
        if form.is_valid():
            form.save()
        else:
            res["err_msg"] =form.errors

        return JsonResponse(res)


    else:
        form=UserModelForm()
        return  render(request,"reg.html",locals())
基于ModelForm的注册代码

 form组件代码

from django.forms import widgets

from app01.models import UserInfo
from django.core.exceptions import ValidationError
import re
from django import forms
class UserForm(forms.Form):
    user=forms.CharField(min_length=2,label="用户名")
    gender=forms.ChoiceField(choices=((1,""),(2,"")))
    pwd=forms.CharField(min_length=5,widget=widgets.PasswordInput(),label="密码")
    r_pwd=forms.CharField(min_length=5,widget=widgets.PasswordInput(),label="确认密码")
    email=forms.EmailField(min_length=5,label="邮箱")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for filed in self.fields.values():
            filed.widget.attrs.update({'class': 'form-control'})


    def clean_user(self):
        val=self.cleaned_data.get("user")
        user=UserInfo.objects.filter(username=val).first()
        if user:
            raise ValidationError("用户已存在!")
        else:
            return val

    def clean_pwd(self):
        val=self.cleaned_data.get("pwd")
        if val.isdigit():
            raise ValidationError("密码不能是纯数字!")
        else:
            return val

    def clean_email(self):
        val=self.cleaned_data.get("email")
        if re.search("\w+@163.com$",val):
            return val
        else:
            raise ValidationError("邮箱必须是163邮箱!")

    def clean(self):
        pwd=self.cleaned_data.get("pwd")
        r_pwd=self.cleaned_data.get("r_pwd")

        if pwd and r_pwd and r_pwd!=pwd:
            self.add_error("r_pwd", ValidationError("两次密码不一致!"))
        else:
            return self.cleaned_data
form组件中的钩子设置

 

登陆页面代码

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css">
</head>
<body>
<h3>登录页面</h3>

<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <form action="" method="post">
                {% csrf_token %}
                <div class="form-group">
                    <label for="">用户名</label>
                    <input type="text" class="form-control" id="user">
                </div>
                 <div class="form-group">
                    <label for="">密码</label>
                    <input type="password" class="form-control" id="pwd">
                </div>
                <div class="form-group">
                    <label for="">验证码</label>
                    <div class="row">
                       <div class="col-md-6">
                            <input type="text" class="form-control" id="validcode">
                       </div>
                       <div class="col-md-6">
                           <img width="350" height="38" src="/get_valid_img/" alt="" id="img">
                       </div>
                    </div>

                </div>


                <input type="button" class="btn btn-primary pull-right login_btn" value="登录">
                <span class="error"></span>
            </form>
        </div>
    </div>
</div>


<script src="/static/js/jquery.js"></script>
<script>

     $(".login_btn").click(function () {


         $.ajax({
             url:"",
             type:"post",
             data:{
                 user:$("#user").val(),
                 pwd:$("#pwd").val(),
                 validcode:$("#validcode").val(),
                 csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val()
             },
             success:function (response) {
                     console.log(response);

                     if(response.user){
                         // 登录成功
                         location.href="http://www.luffycity.com"
                     }
                     else{
                         // 登录失败
                         $(".error").html(response.err_msg).css("color","red")
                     }
             }
         })


     })

    //  验证码刷新
    $("#img").click(function () {
        this.src+="?"
    })

</script>
</body>
</html>
基于bootstrap搭建带ajax提交form渲染

注册页面代码

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css">
</head>
<body>
<h3>注册页面</h3>

<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <form action="" method="post">
                {% csrf_token %}
                {% for field in form %}
                       <div class="form-group">
                            <label for="">{{ field.label }}</label>
                            {{ field }}
                            <span class="error pull-right"></span>
                        </div>
                {% endfor %}
                <input type="button" class="btn btn-primary reg_btn" value="注册">
            </form>
        </div>
    </div>
</div>


<script src="/static/js/jquery.js"></script>
<script>

    $(".reg_btn").click(function () {


        $.ajax({
            url:"",
            type:"post",
            data:{
                user:$("#id_user").val(),
                pwd:$("#id_pwd").val(),
                r_pwd:$("#id_r_pwd").val(),
                email:$("#id_email").val(),
                csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val()

            },
            success:function (res) {
                console.log(res);

                if (res.user){
                    // 注册成功
                    location.href="/login/"
                }
                else{

                 // 清除错误
                $(".error").html("");
                $(".form-group").removeClass("has-error");

                //  展示新的错误
                $.each(res.err_msg,function (i,j) {
                    console.log(i,j);

                    $("#id_"+i).next().html(j[0]).css("color","red").parent().addClass("has-error")



                })


                }



            }
        })



    })


</script>
</body>
</html>
基于form带ajax注册页面

 

posted @ 2018-11-08 20:08  RootEvils  阅读(157)  评论(0)    收藏  举报