前戏
Django给我们提供了一个后台管理系统,方便我们进行数据表的管理
创建超级用户
python manage.py createsuperuser
配置
默认我们登录到后台不显示任何一张表,如果需要显示,我们需要在我们创建的app下的admin下进行配置
from django.contrib import admin from crm import models # Register your models here. ''' 固定写法,只有点后面的是model里的表名 ''' admin.site.register(models.UserProfile) admin.site.register(models.Customer) admin.site.register(models.ClassList) admin.site.register(models.Campuses)
这样配置好之后我们重新启动项目,在登录后台查看,Django会在我们的表名后面加个s显示在页面上
如果我们想自定义显示内容,我们可以在model里面加个class Meta
class Customer(models.Model): """ 客户表 """ qq = models.CharField('QQ', max_length=64, unique=True, help_text='QQ号必须唯一') # help_textAdmin中该字段的提示信息 unique唯一索引 qq_name = models.CharField('QQ昵称', max_length=64, blank=True, null=True) # blank Admin中是否允许用户输入为空 null数据库中字段是否可以为空 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) # default数据库中字段的默认值 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) # verbose_name Admin中显示的字段名称 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, ) # related_name反向查找 class_list = models.ManyToManyField('ClassList', verbose_name="已报班级", ) class Meta: verbose_name = '客户列表' # 如果只加这句,后面的s还是显示的,需要在加下面的一句 verbose_name_plural = '客户列表'
我们把上面的几个都加上Meta类,就能正常显示了
使用__str__在后台显示具体的内容
登录后台系统添加已报班级之后,页面显示的是一个对象,我们要把它转化为能看懂的,需要加上__str__方法
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) contract = models.ForeignKey('ContractTemplate', verbose_name="选择合同模版", 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) def __str__(self): return '{}{}({})'.format(self.get_course_display(),self.semester,self.campuses)
说明:
因为我们的course是选择的,数据来源为choise=course_choices
course_choices = (('LinuxL', 'Linux中高级'), # 选择课程 ('PythonFullStack', 'Python高级全栈开发'),)
self.get_course的结果为LinuxL或者PythonFullStack,如果使用 self.get_course_display() 结果就是后面的值,Linux中高级或者Python高级全栈开发
模版语言相关
把数据库里的数据查询出来展示在页面上,如果数据表里某一个字段值为空,则在页面上显示的是None,我们也可以使用filter给个默认值
<td>{{ customer.qq_name|default:'暂无' }}</td>
如果是选择的,我们也可以使用get_字段名_display来获取对应的值
<td>{{ customer.get_source_display }}</td>
注意:在模版中是不需要()的,在models.py里是需要()的
我们可以在model里定义一个方法,在模版里使用
from django.utils.safestring import mark_safe
class Customer(models.Model): """ 客户表 """ qq = models.CharField('QQ', max_length=64, unique=True, help_text='QQ号必须唯一') # help_textAdmin中该字段的提示信息 unique唯一索引 定义了一个方法,用来根据状态显示不同的颜色 def show_status(self): color_dict = { "signed": 'green', "unregistered": 'red', "studying": 'pink', "paid_in_full": 'blue', } return mark_safe( '<span style="background-color: {};color: white;padding: 4px">{}</span>'.format(color_dict[self.status], self.get_status_display()))
模版里使用
<td> {{ customer.show_status }} 调用的show_status方法 </td>
如果不使用mark_safe,也可以在模版里使用
<td> {{ customer.show_status|safe }} </td>
因为我们的data字段和last_consult_data是使用下面的字段来定义的
date = models.DateTimeField("咨询日期", auto_now_add=True) last_consult_date = models.DateField("最后跟进日期", auto_now_add=True)
所以在页面显示效果如下
这时我们有两种方法来显示成我们需要的格式,第一种是使用filter,第二种是在settings.py里增加两行代码并修改一行代码
这时候刷新页面就能正常显示了
因为我们的 Customer 表和 ClassList 表是多对多的关系
class_list = models.ManyToManyField('ClassList', verbose_name="已报班级", )
所以如果要查询所有的书我们可以写一个方法
def show_classes(self): return ' | '.join([str(i) for i in self.class_list.all()])
模版中使用
<td>{{ customer.show_classes }}</td>