CRM手记-1 | Django

Posted 胡说八道

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CRM手记-1 | Django相关的知识,希望对你有一定的参考价值。

1.模型类的创建

技术分享图片
from django.db import models
# 使用django内置的用户表
from django.contrib.auth.models import User


class UserProfile(models.Model):
    """
    用户信息表
    """
    user = models.OneToOneField(User)  # 创建外键,关联django用户表
    # 扩展用户字段
    name = models.CharField(max_length=32, verbose_name="姓名")
    role = models.ManyToManyField("Role", blank=True)  # 双向一对多==多对多

    def __str__(self):
        return self.name


class Role(models.Model):
    """
    角色表
    """
    name = models.CharField(max_length=32, unique=True)  # 角色名不可以重复
    menus = models.ManyToManyField("Menus",blank=True)

    def __str__(self):
        return self.name


class CustomerInfo(models.Model):
    """
    客户信息
    """
    name = models.CharField(max_length=32, default=None)  # 首次报名可能不知道名字
    source_choices = (
                (0, QQ群),
                (1, 51CTO),
                (2, 百度推广),
                (3, 知乎),
                (4, 转介绍),
                (5, 其它)
            )
    source = models.SmallIntegerField(choices=source_choices)
    referral_from = models.ForeignKey("self",blank=True,null=True,verbose_name="转介绍")  # 关联自己
    contact_type_choices = (
                (0, qq),
                (1, 微信),
                (2, 手机),
            )
    contact_type = models.SmallIntegerField(choices=contact_type_choices)
    contact = models.CharField(max_length=64, unique=True)
    consult_courses = models.ManyToManyField("Course", verbose_name="咨询课程")
    consult_content = models.TextField(verbose_name="咨询内容")
    consultant = models.ForeignKey("UserProfile",verbose_name="课程顾问")
    status_choices = (
                (0, 未报名),
                (1, 已报名),
                (2, 已退学),
            )
    status = models.SmallIntegerField(choices=status_choices)
    date = models.DateField(auto_now_add=True)

    def __str__(self):
        return self.name


class CustomerFollowUp(models.Model):
    """
    客户跟踪记录表
    """
    customer = models.ForeignKey(CustomerInfo)
    content = models.TextField(verbose_name="跟踪内容")
    user = models.ForeignKey(UserProfile, verbose_name="跟进人")  
    date = models.DateTimeField(auto_now_add=True)
    status_choices = (
                (0, 近期无报名计划),
                (1, 一个月内报名),
                (2, 2周内报名),
                (3, 已报名),
            )
    status = models.SmallIntegerField(choices=status_choices,verbose_name="跟进状态")

    def __str__(self):
        return self.content


class Course(models.Model):
    """
    课程
    """
    name = models.CharField(verbose_name="课程名", unique=True, max_length=64)
    price = models.PositiveSmallIntegerField()
    outline = models.TextField(verbose_name="课程大纲")
    period = models.PositiveSmallIntegerField(verbose_name="课程周期(月)", default=5)

    def __str__(self):
        return self.name


class ClassList(models.Model):
    """
    班级列表
    """
    branch = models.ForeignKey(Branch)  # 关联校区
    course = models.ForeignKey("Course")
    class_type_choices = ((0,脱产),(1,周末),(2,网络班))
    class_type = models.SmallIntegerField(choices=class_type_choices,default=0)
    semester = models.SmallIntegerField(verbose_name="学期")
    teachers = models.ManyToManyField(UserProfile, verbose_name="讲师")
    start_date = models.DateField(verbose_name="开班日期")
    graduate_date = models.DateField("毕业日期", blank=True, null=True)

    def __str__(self):
        return "{0}({1})期".format(self.course.name,self.semester)

    class Meta:
        """联合唯一"""
        unique_together = (branch,course, semester)


class CourseRecord(models.Model):
    """
    上课记录
    """
    class_grade = models.ForeignKey("ClassList", verbose_name="上课班级")
    day_num = models.PositiveSmallIntegerField(verbose_name="课程节次")
    teacher = models.ForeignKey("UserProfile", verbose_name="本节讲师")
    title = models.CharField("本节主题", max_length=64)
    content = models.TextField("本节内容")
    has_homework = models.BooleanField("本节有作业", default=True)
    homework = models.TextField("作业需求", blank=True, null=True)
    date = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return "{0}第{1}节".format(self.class_grade,self.day_num)
    
    class Meta:
        unique_together = (class_grade, day_num)


class StudyRecord(models.Model):
    """
    学习记录
    """
    course_record = models.ForeignKey(CourseRecord)
    student = models.ForeignKey("Student")
    score_choices = (
                (100, "A+"),
                (90, "A"),
                (85, "B+"),
                (80, "B"),
                (75, "B-"),
                (70, "C+"),
                (60, "C"),
                (40, "C-"),
                (-50, "D"),
                (0, "N/A"),
            )
    score = models.SmallIntegerField(choices=score_choices)
    show_choices = (
                (0, "缺勤"),
                (1, "已签到"),
                (2, "迟到"),
                (3, "早退"),
            )
    show_status = models.SmallIntegerField(choices=show_choices,default=1)
    note = models.TextField("成绩备注", blank=True, null=True)
    date = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return "{0} {1} {2}".format(self.course_record,self.student,self.score)


class Student(models.Model):
    """
    学员表
    """
    customer = models.ForeignKey("CustomerInfo")
    class_grade = models.ManyToManyField("ClassList")

    def __str__(self):
        return self.customer



class Branch(models.Model):
    """
    校区
    """
    name = models.CharField(max_length=32, unique=True)
    addr = models.CharField(max_length=128, blank=True, null=True)

    def __str__(self):
        return self.name


class Menus(models.Model):
    """动态菜单"""
    name = models.CharField(max_length=64)
    url_type_choices = (
        (0, absolute),
        (1, dynamic)
    )
    url_type = models.SmallIntegerField(choices=url_type_choices, default=0)
    url_name = models.CharField(max_length=128)

    def __str__(self):
        return self.name

    class Meta:
        unique_together = (name, url_name)
View Code

2.类似djang-admin功能的页面开发之左侧菜单栏 | 登录

# base.html存放公共的静态文件;
# index.html存放整体布局;
    # 继承
    {% extends base.html %}
# PerfectCRM/urls.py
    ...
    url(rcrm/, include(crm.urls))
# crm/urls.py
    ...
    url(r^$, views.dashboard)
# crm/views.py
    def dashboard(request):
        return render(request, crm/dashboard.html)

# template-crm-dashboard.html|继承index.html
#           -

# 配置显示静态文件

# 将base.html中body部分放入index.html

# 去掉search,Dashboard,Settings,Profile
# 在help位置显示用户登录状态;
# Dashboard下所有标签以及左侧菜单ul标签内容都删除;

# 左侧菜单显示当前登录角色的表;

# 不同角色,拥有几乎完全不同的页面,但是共同点是都需要一个动态的菜单栏;
# 用一个表分别记录菜单栏上的名字以及对应的url并且与角色关联;
# url可能涉及(\d+)等参数,所以分成动态url与静态url供用户选择
class Menus(models.Model):
    """动态菜单"""
    name = models.CharField(max_length=64)
    url_type_choices = (
        (0, absolute),
        (1, dynamic)
    )
    url_type = models.SmallIntegerField(chioces=url_type_choicesm,default=0)
    url_name = models.CharField(max_length=128)
    
    def __str__(self):
        return self.name
    
    class Meta:
        unique_together = (name,url_name)
# 角色与菜单多对多关系,在Role表中添加关联
class Role(models.Model):
    ...
    menus = models.ManyToManyField("Menus",blank=True)
# 迁移

# 在后台管理系统中添加Menus
    Name:首页
    Url type:dynamic
    Url name:sales_dashboard
    # 意味着urls.py中name=‘sales_dashboard‘
    Name:客户库
    Url type:absolute
    Url name:/crm/customers
    Name:我的课程
    Url type:absolute
    Url name:/student/my_courses
# 在后台管理系统中添加Roles
    Names:sales
    Menus:首页,客户库
    Names:students
    Menus:我的课程
# 创建用户关联UserProfile
    User:python    
    姓名:miaokela
    Role:sales
    User:python    
    姓名:mic
    Role:students
    # 这里出现了一个问题,两个用户共用了django的一个账户;
    # 所以需要将与django自带的user表改成一对一关联
    User:python    
    姓名:miaokela
    Role:sales
    User:Lily    
    姓名:赵丽颖
    Role:students
# ==============>>>> 测试不通过角色登录之后显示的动态菜单;
# --->> 用django自带的auth写一个用户登录;
# 在bootstrap上找一个登录页面;
# 拷贝框,以及signin.css,载入到base.html
# 新建一个登录页面login.html
    {% extends index.html %}
    {% block body %}
    <div class="container">
        <!-- action不写,默认为当前页 -->
        <form class="form-signin" method="post">
        {% csrf_token %}
            <h2 class="form-signin-heading">PerfectCRM</h2>
            <label for="inputEmail" class="sr-only">Username</label>
            <input type="email" id="inputEmail" name=username class="form-control" placeholder="Username" required autofocus>
            <label for="inputPassword" class="sr-only">Password</label>
            <input type="password" id="inputPassword" name=password class="form-control" placeholder="Password" required>
            <div class="checkbox">
              <label>
                <input type="checkbox" value="remember-me"> Remember me
              </label>
            </div>
            <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
        </form>

    </div>
    {% endblock body %}
# 写一个登录的views以及urls(写在项目全局中)
    # views.py
    def user_login(request):
        return render(request, login.html)
    # urls.py
    ...
    url(r^login/,views.login)
# 完善login.html里的table,action不填表示当前页面
# 后端收到POST提交数据
    # views.py
    def user_login(request):
        if request.method == "POST":
            username = request.POST.get("username")
            password = request.POST.get("password")
            print(username,password)
        return render(reqyest, login.html)
    # 打印username,password,说明提交成功;
# 登录验证
    # views.py
    from django.shortcut import render,redirect
    from django.contrib.auth import authenticate
    def login(request):
        if request.method == "POST":
            username = request.POST.get("username")
            password = request.POST.get("password")
            user = authenticate(username=username,password=password)
            if user:
                print(authenticate successed)
            print(user,username,password)
            # 验证成功时,user返回python,不成功返回None;
            return redirect("/crm/")
        return render(reqyest, login.html)
    # 将右上角Help改成{{request.user}},显示登录用户python
    # 现在出现一个问题,当admin账户登出之后,右上角显示AnonymousUser,游客登录;
    # 再到login.html页面登录,右上角显示还是匿名登录;
    # 为什么呢?
    # 其实刚才一直没有登录,只是因为自己登录了admin后台,才有的request.user的值;
    # views.py
    from django.shortcut import render,redirect
    from django.contrib.auth import authenticate,login
    def user_login(request):
        if request.method == "POST":
            username = request.POST.get("username")
            password = request.POST.get("password")
            user = authenticate(username=username,password=password)
            if user:
                # 登录
                login(request,user)
                print(authenticate successed)
            print(user,username,password)
            # 验证成功时,user返回python,不成功返回None;
            return redirect("/crm/")
        return render(reqyest, login.html)
    # 这样就登录成功了!
    # 如果登录失败返回错误信息.在前端显示 
    error_message = ‘‘
    ...
    else:
        error_message = "wrong username or password!"
# 注销登录|bootstrap里找一个下拉框
    <li class="dropdown">
        <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="true">{{ request.user }}<span class="caret"></span></a>
        <ul class="dropdown-menu">
            <li><a href="#">个人信息</a></li>
            <li><a href="{% url ‘logout‘ %}">注销</a></li>
        </ul>
    </li>
    # 写一个登出视图以及urlconf
    # views.py
    from django.shortcut import redirect
    from django.contrib.auth import logout
    def logout(request):
        logout(request)
        return redirect(/login/)
    # urls.py
    ...
    url(r^logout/,views.user_logout,name=logout)
    # 这样就完成了登出的过程
# 但是,我们在没有登录的时候直接url输入访问页面,也可以访问?
# 依然是匿名登录状态;
    from django.contrib.auth.decorators import login_required

    # 在具体的每个页面添加
    @login_required
    def dashboard(request):
        return render(request, crm/dashboard.html)
    # 这个时候就报错了
    http://localhost:8000/accounts/login/?next=/ 这个url找不到;
    # 这个是django自带的跳转页面,如果没有验证成功自动跳转这个页面;
    # 措施:
    # settings.py 添加配置
    # 没有登录,直接访问页面自动跳转该页面
    LOGIN_URL = /login/
    # 此时访问页面跳转至:
    http://localhost:8000/login/?next=/
    # 这段url表示,当登录之后自动跳转之前你访问的页面;
    # 当你login()时,它会帮你记录上次访问的页面;
# 现在来解决登录成功后跳转的页面
    # views.py
    from django.shortcut import render,redirect
    from django.contrib.auth import authenticate,login
    def user_login(request):
        if request.method == "POST":
            username = request.POST.get("username")
            password = request.POST.get("password")
            user = authenticate(username=username,password=password)
            if user:
                # 登录
                login(request,user)
                print(authenticate successed)
            print(user,username,password)
            # 验证成功时,user返回python,不成功返回None;
            return redirect("/crm/") # 跳转至上次访问页面
        return render(reqyest, login.html)
    # 登录成功之后要访问的是next参数指定的页面;
    # 如果没有next的值,就跳转至首页;
    return redirect(request.GET.get(next,/))

 

以上是关于CRM手记-1 | Django的主要内容,如果未能解决你的问题,请参考以下文章

CRM手记-4 | Django

CRM手记- 11 | Django

CRM手记-7 | Django

CRM手记-2 | Django

CRM手记-5 | Django

CRM手记-8 | Django