crm 系统项目(二) admin 后台操作表格

1. app下创建 templates 

  运行的时候 先找全局的templates——》 按照app的注册顺序找templates中的文件

2. app下在创建一个urls.py

  include()

3. 创建超级用户

  python manage.py createsuperuser

    邮箱可以忽略,密码默认为8位

4. 在admin中注册model

 from django.contrib import admin
from crm import models admin.site.register(models.Customer)
admin.site.register(models.ClassList)
admin.site.register(models.Campuses)

5. 使用http://127.0.0.1:8000/admin 添加数据

6.不同的字典不同显示

  a.普通字段 : {{ customer.qq }}

  b.含有choices字段: {{ customer.get_sex_display }}    # get_字段名_display() 方法  模板中不加()

  c. 多对多、特殊显示,在model中定义方法。

def show_classes(self):
return ' | '.join([str(i) for i in self.class_list.all()]) def show_status(self):
color_dict = {
'signed': 'green',
'unregistered': 'red',
'studying': 'blue',
'paid_in_full': 'yellow',
} return '<span style="background-color: {};color: white;padding: 3px">{}</span>'.format(
color_dict.get(self.status),
self.get_status_display())

  

admin.py

from django.contrib import admin
from app1 import models
# 在admin后台注册某个字段
admin.site.register(models.Customer)
admin.site.register(models.ClassList)
admin.site.register(models.Campuses)
admin.site.register(models.UserProfile)

admin.py

总的urls.py

from django.contrib import admin
from django.conf.urls import url, include
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), url(r'app1/', include('app1.urls'))
]

总的urls.py

app下的urls.py

from django.conf.urls import url
from app1 import views urlpatterns = [
url(r'^customer_list/', views.customer_list),
url(r'^user_list/', views.user_list),

app下的urls.py

setting.py 部分

USE_L10N = False   #本地格式化

USE_TZ = True
#格式化时间
DATETIME_FORMAT = "Y-m-d H:i:s"
DATE_FORMAT = "Y-m-d"

setting.py 部分

新的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) def __str__(self):
return self.name 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="已报班级", ) def show_classes(self):
return '|'.join([str(i) for i in self.class_list.all()])
def show_status(self):
color_dict={
'signed': 'green',
'unregistered': 'red',
'paid_in_full': 'yellow',
}
return '<span style="background-color: {};color: white;padding: 3px">{}</span>'.format(
color_dict.get(self.status),
self.get_status_display()) def __str__(self):
return self.name if self.name else self.qq
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="校区")
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') def __str__(self):
return "{}{}({})".format(self.get_course_display(), self.semester, self.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')

母板html

{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>路飞学城</title>
<link rel="shortcut icon" href="{% static 'img/luffy-study-logo.png' %} ">
<link rel="stylesheet" href="{% static 'plugins/bootstrap/css/bootstrap.css' %} "/>
<link rel="stylesheet" href="{% static 'plugins/font-awesome/css/font-awesome.css' %} "/>
<link rel="stylesheet" href="{% static 'css/commons.css' %} "/>
<link rel="stylesheet" href="{% static 'css/nav.css' %} "/>
<style>
body {
margin: 0;
} .no-radius {
border-radius: 0;
} .no-margin {
margin: 0;
} .pg-body > .left-menu {
background-color: #EAEDF1;
position: absolute;
left: 1px;
top: 48px;
bottom: 0;
width: 220px;
border: 1px solid #EAEDF1;
overflow: auto;
} .pg-body > .right-body {
position: absolute;
left: 225px;
right: 0;
top: 48px;
bottom: 0;
overflow: scroll;
border: 1px solid #ddd;
border-top: 0;
font-size: 13px;
min-width: 755px;
} .navbar-right {
float: right !important;
margin-right: -15px;
} .luffy-container {
padding: 15px;
} .left-menu .menu-body .static-menu { } .left-menu .menu-body .static-menu .icon-wrap {
width: 20px;
display: inline-block;
text-align: center;
} .left-menu .menu-body .static-menu a {
text-decoration: none;
padding: 8px 15px;
border-bottom: 1px solid #ccc;
color: #333;
display: block;
background: #efefef;
background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #efefef), color-stop(1, #fafafa));
background: -ms-linear-gradient(bottom, #efefef, #fafafa);
background: -o-linear-gradient(bottom, #efefef, #fafafa);
filter: progid:dximagetransform.microsoft.gradient(startColorStr='#e3e3e3', EndColorStr='#ffffff');
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#fafafa',EndColorStr='#efefef')";
box-shadow: inset 0 1px 1px white;
} .left-menu .menu-body .static-menu a:hover {
color: #2F72AB;
border-left: 2px solid #2F72AB;
} .left-menu .menu-body .static-menu a.active {
color: #2F72AB;
border-left: 2px solid #2F72AB;
}
</style>
{% block css %} {% endblock %}
</head>
<body> <div class="pg-header">
<div class="nav">
<div class="logo-area left">
<a href="#">
<img class="logo" src="{% static 'img/logo.svg' %}">
<span style="font-size: 18px;">路飞学城 </span>
</a>
</div> <div class="left-menu left">
<a class="menu-item">资产管理</a>
<a class="menu-item">用户信息</a>
<a class="menu-item">路飞管理</a>
<div class="menu-item">
<span>使用说明</span>
<i class="fa fa-caret-down" aria-hidden="true"></i>
<div class="more-info">
<a href="#" class="more-item">管他什么菜单</a>
<a href="#" class="more-item">实在是编不了</a>
</div>
</div>
</div> <div class="right-menu right clearfix"> <div class="user-info right">
<a href="#" class="avatar">
<img class="img-circle" src="{% static 'img/default.png' %}">
</a> <div class="more-info">
<a href="#" class="more-item">个人信息</a>
<a href="#" class="more-item">注销</a>
</div>
</div> <a class="user-menu right">
消息
<i class="fa fa-commenting-o" aria-hidden="true"></i>
<span class="badge bg-success">2</span>
</a> <a class="user-menu right">
通知
<i class="fa fa-envelope-o" aria-hidden="true"></i>
<span class="badge bg-success">2</span>
</a> <a class="user-menu right">
任务
<i class="fa fa-bell-o" aria-hidden="true"></i>
<span class="badge bg-danger">4</span>
</a>
</div> </div>
</div>
<div class="pg-body">
<div class="left-menu">
<div class="menu-body">
<div class="static-menu">
<a href="/crm/depart/list/"><span class="icon-wrap"><i class="fa fa-map-o" aria-hidden="true"></i></span> 部门管理</a>
<a href="/crm/user/list/"><span class="icon-wrap"><i class="fa fa-map-o" aria-hidden="true"></i></span> 用户管理</a>
</div>
</div>
</div>
<div class="right-body">
<div>
<ol class="breadcrumb no-radius no-margin" style="border-bottom: 1px solid #ddd;"> <li><a href="#">首页</a></li>
<li class="active">客户管理</li> </ol>
</div>
{% block content %} {% endblock %}
</div>
</div> <script src="{% static 'js/jquery-3.3.1.min.js' %} "></script>
<script src="{% static 'plugins/bootstrap/js/bootstrap.js' %} "></script>
{% block js %} {% endblock %}
</body>
</html>

layout.html

用于展示的html

{% extends 'layout.html' %}
{% block content %} <table class="table table-bordered table-hover">
<thead>
<tr>
<th>序号</th>
<th>QQ</th>
<th>姓名</th>
<th>性别</th>
<th>出生日期</th>
<th>客户来源</th>
<th>咨询课程</th>
<th>状态</th>
<th>咨询日期</th>
<th>销售</th>
<th>已报班级</th>
</tr>
</thead> <tbody>
{% for i in all_customer %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ i.qq }}</td>
<td>{{ i.name|default:'-' }}</td>
<td>{{ i.get_sex_display}}</td>
<td>{{ i.birthday }}</td>
<td>{{ i.get_source_display }}</td>
<td>{{ i.course }}</td>
<td>{{ i.show_status|safe }}</td>
<td>{{ i.date }}</td>
<td>{{ i.consultant}}</td>
<td>{{ i.show_classes }}</td>
</tr>
{% endfor %}
</tbody> </table>
{% endblock %}

customer_list.html

crm 系统项目(二) admin 后台操作表格的更多相关文章

  1. admin 后台操作表格

    1. app下创建 templates  运行的时候 先找全局的templates——> 按照app的注册顺序找templates中的文件 2. app下在创建一个urls.py include ...

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

    crm 系统项目(一) 登录,注册,校验 首先创建一个Django项目,关于配置信息不多说,前面有~ models.py文件下创建需要的表格信息,之后导入数据库 from django.db impo ...

  3. crm 系统项目(三) 自动分页

    crm 系统项目(三) 自动分页 需求: 1. 做一个自动分页, 每15条数据1页 2. 让当前页数在中间显示 3. 上一页, 下一页 注意情况: 1.总页数 小于 规定显示的页数 2. 左右两边极值 ...

  4. crm 系统项目(三) 业务

    1. 项目背景 crm系统是某教育平台正在使用的项目,系统主要为 销售部.运营部.教质部门提供管理平台,随着公司规模的扩展,对公司员工的业务信息量化以及信息化建设越来越重要. crm系统为不同角色的用 ...

  5. Django admin后台操作

    Django提供自动后台管理应用,简称admin. admin是一个应用,每个Web站点都需要它.admin通过让开发者可以在完成完整的UI之前验证处理数据的代码. 设置admin 打开setting ...

  6. CRM系统 - 总结 (二) stark组件

    介绍: stark组件,是一个帮助开发者快速实现数据库表的增删改查+的组件.目标: 10s 中完成一张表的增删改查. 前戏: django项目启动时,自定义执行某个py文件. django启动时,且在 ...

  7. 玩转Django2.0---Django笔记建站基础八(admin后台系统)

    第八章 admin后台系统 admin后台系统也成为网站后台管理系统,主要用于对网站前台的信息进行管理,如文字.图片.影音和其他日常使用文件的发布.更新.删除等操作,也包括功能信息的统计和管理,如用户 ...

  8. Python CRM项目二

    一.准备工作 如果没有配置基本的项目,请参考 http://www.cnblogs.com/luhuajun/p/7771196.html 当我们配置完成后首先准备我们的app 创建2个app分别对应 ...

  9. Django——12 中间件 上下文处理器 admin后台

    Django 中间件 中间件介绍 中间件的第一个例子 中间件的第二个例子 上下文处理器 admin后台管理   中间件 Django中间件(Middleware)是一个轻量级.底层的“插件”系统,可以 ...

随机推荐

  1. j2ee消息中间件

    http://blog.csdn.net/apanious/article/details/51014396

  2. FreeMarker 页面静态化解决方案

    一.网页的静态化方案 1.生成静态页面的时机:在做添加操作时,同时生成该新增内容的对应的静态页面 2.静态页面的名称:内容 id + ".html" 3.静态页面所在的路径:工程外 ...

  3. String类常见的方法

    类String public final class String extends Object implements Serializable, comparable<String>, ...

  4. oracle自定义判断是否数字函数isNumber()

    右击function选择新增 如果是数字返回本身,如果不是数字返回0: create or replace function isNumber(p in varchar2) return number ...

  5. bzoj 3236: [Ahoi2013]作业(缺线段树)

    3236: [Ahoi2013]作业 Time Limit: 100 Sec  Memory Limit: 512 MBSubmit: 1744  Solved: 702[Submit][Status ...

  6. [Windows Server]安装系统显示“缺少计算机所需的介质驱动程序”解决方案

    1.把电脑上插着的硬盘拔了 2.重试 3.修复计算机找到dos命令行 4.然后进入我们放置解压了的系统的那个符盘,(我这里放在D盘)输入:d:       找到刚才我们解压了的系统文件,进入sourc ...

  7. poj 3356

    Description Let x and y be two strings over some finite alphabet A. We would like to transform x int ...

  8. 使用Swift和SpriteKit写一个忍者游戏

    这篇文章的游戏使用SpriteKit和Swift语言来完毕. SpriteKit是苹果自己的游戏引擎,更能贴合iOS系统底层的API,只是架构和实现上都是模仿了Cocos2D.所以使用上事实上区别不大 ...

  9. ListView的adapter中getView方法一直调用

    当ListView的高度不定(比如重写ListView搞成可自己主动的扩展的ListView)或 ListView嵌套在SrollView(高度不定)中,listView中的一个item元素改变会使得 ...

  10. 0xC0000005;Access Violation(栈区空间很宝贵, linux上栈区空间默认为8M,vc6下默认栈空间大小为1M)

    写C/C++程序最怕出现这样的提示了,还好是在调试环境下显示出来的,在非调试状态就直接崩溃退出. 从上述汇编代码发现在取内存地址 eax+38h 的值时出错, 那说明这个地址非法呗, 不能访问, 一般 ...