orm 小结
- 用户表
2.销售添加客户信息,成为销售的私户
- 客户表
3. 销售固定时间跟进客户
- 跟进记录表
4. 客户报名
- 报名记录表
- 班级表(必须有)
- 校区表
- 合同表
5. 销售审核报名,学生进行缴费。
- 报名记录表 更改审核状态
- 缴费记录表 销售收到钱
6. 销售将钱交给财务,财务对缴费记录进行审核
- 缴费记录 更改审核状态
7. 自动修改学生状态
- 客户表 状态改成缴费成功
2. 班主任
1. 每天创建课程记录,记录每天上课的情况。
- 用户表
- 班级表
- 课程记录表
2. 再根据课程记录,生成学生的学习记录,修改考勤情况。
- 学习记录表
3. modelform
1. 定义
from django import froms
from crm import models
class RegForm(forms.ModelForm):
re_password = forms.CharField(
label='确认密码',
widget=forms.widgets.PasswordInput()
)
class Meta:
model = models.UserProfile
# fields = '__all__' # 所有字段
# exclude = [''] # 排除的字典
fields = ['username', 'password', 're_password', 'name', 'department'] # 指定需要的字段
widgets = {'password':forms.widgets.PasswordInput(attrs={'class':'form-control'}} # 插件
labels = {'username':'用户名'} # 显示中文名 等同models给字段加verbose_name
error_messages = {username' : {'required':'必填'} # 字段的错误信息
form_obj.is_valid() # 校验数据
obj = form_obj.save() # 创建新的数据 create方法
2.内容显示
普通字段 {{ customer.qq }}
choices {{ customer.get_class_type_display }}
多对多 定义方法 返回字符串 def show_teacher(self):
return '|'.join([str(i) for i in self.teachers.all()])
显示状态 定义方法 返回HTML代码段 mark_safe
from django.utils.safestring import mark_safe
2. 增加客户
2. 编辑客户
form_obj = CustomerForm(instance=obj)
form_obj带着原有的数据,根据数据生成input的值
form_obj = CustomerForm(request.POST,instance=obj)
将提交的数据和要修改的实例交给form对象
form_obj.save() 对要修改的实例进行修改
3. 公户变私户
CBV
self.request
反射
orm操作:
models.Customer.objects.filter(id__in=ids).update(consultant=self.request.user)
self.request.user.customers.add(*models.Customer.objects.filter(id__in=ids))
4. 私户变公户
# 注意 外键 null=True 一对多的管理对象才有remove和clear方法
orm操作:
models.Customer.objects.filter(id__in=ids).update(consultant=None)
self.request.user.customers.remove(*models.Customer.objects.filter(id__in=ids))
5. 模糊查询
all_customer = models.Customer.objects.filter(Q(qq__contains=query) | Q(name__contains=query),
consultant__isnull=True)
all_customer = models.Customer.objects.filter(Q(('qq__contains',query)) | Q(('name__contains',query)),
consultant__isnull=True)
def get_search_contion(self,query_list):
query = self.request.GET.get('query', '')
q = Q()
q.connector = 'OR'
for i in query_list:
q.children.append(Q(('{}__contains'.format(i), query)))
return q
6. 保留搜索条件
from django.http import QueryDict
print('query',request.GET) # <QueryDict: {'query': ['alex']}>
print(request.GET.urlencode()) query=alex
request.GET.copy() 深拷贝
QueryDict对象._mutable = True # 对字典进行修改
QueryDict对象['page'] = 页码数 # 多个值
QueryDict对象.urlencode() # query=alex&page=1 ?query=alex&page=1
1. 添加和编辑后跳转回源页面
qd =QueryDict()
qd._mutable = True
qd['next'] = request.get_full_path()
qd.urlencode()
2. 展示客户的跟进记录、增加和编辑
obj = models.ConsultRecord.objects.filter(id=edit_id).first() or models.ConsultRecord(consultant=request.user)
form_obj = ConsultRecordForm(instance=obj)
# 限制客户是当前销售的私户
self.fields['customer'].widget.choices = customer_choice
# 限制跟进人是当前的用户(销售)
self.fields['consultant'].widget.choices = [(self.instance.consultant_id, self.instance.consultant), ]
3. 报名记录
# 限制当前的客户只能是传的id对应的客户
self.fields['customer'].widget.choices = [(self.instance.customer_id, self.instance.customer), ]
# 限制当前可报名的班级是当前客户的意向班级
self.fields['enrolment_class'].widget.choices = [(i.id, i) for i in self.instance.customer.class_list.all()]
# 在客户列表中显示不同a标签
def enroll_link(self):
if not self.enrollment_set.exists():
return mark_safe('<a href="{}">添加报名表</a>'.format(reverse('add_enrollment',args=(self.id,))))
else:
return mark_safe('<a href="{}">添加</a> | <a href="{}">查看</a>'.format(reverse('add_enrollment',
1. 公户变私户的问题解决
- 多个销售同时申请一个客户
谁先申请就是谁的
mysql数据中加行级锁
开始事务:begin;
加锁 for update : select * from student where id=1 for update;
结束事务:commit;
2. 班主任的功能
- 班级的管理
- 班级的展示
- 添加班级
- 编辑班级
- 课程的管理
-
- 学习记录的管理
- 批量添加
student_list = []
for student in all_students:
student_list.append(models.StudyRecord(course_record=course_obj, student=student))
models.StudyRecord.objects.bulk_create(student_list)
- 展示编辑学习记录
FormSet = modelformset_factory(models.StudyRecord, StudyRecordForm, extra=0)
queryset = models.StudyRecord.objects.filter(course_record_id=course_id)
form_set = FormSet(queryset=queryset)
{% for form in form_set %}
{{ form.instance.student.name }} form.instance ——》 学习记录
{{ form.attendance }} ————》对应的input
{{ form.score }}
{{ form.homework_note }}
提交编辑
{{ form_set.management_form }}
{{ form.id }}
{{ form.student }}
form_set = FormSet(request.POST)
if form_set.is_valid():
form_set.save()
orm 小结的更多相关文章
- ORM小结
最近看园子里 @李林峰的园子 关于ORM的介绍,真的很好.自己看了也有一点点小心的,记录一下. ORM即为一种数据模型和数据库中关系映射的一种方式. 学过“三层架构”,知道怎么把表 示层(UI)--& ...
- 关于Django ORM filter方法小结
django filter是一个过滤器,相当于SQL的select * from where. filter返回一个QuerySet对象,还可以在该对象上继续进行django orm 该有的操作. 有 ...
- 从零开始编写自己的C#框架(26)——小结
一直想写个总结,不过实在太忙了,所以一直拖啊拖啊,拖到现在,不过也好,有了这段时间的沉淀,发现自己又有了小小的进步.哈哈...... 原想框架开发的相关开发步骤.文档.代码.功能.部署等都简单的讲过了 ...
- ORM查询语言(OQL)简介--高级篇(续):庐山真貌
相关文章内容索引: ORM查询语言(OQL)简介--概念篇 ORM查询语言(OQL)简介--实例篇 ORM查询语言(OQL)简介--高级篇:脱胎换骨 ORM查询语言(OQL)简介--高级篇(续):庐山 ...
- 用事实说话,成熟的ORM性能不是瓶颈,灵活性不是问题:EF5.0、PDF.NET5.0、Dapper原理分析与测试手记
[本文篇幅较长,可以通过目录查看您感兴趣的内容,或者下载格式良好的PDF版本文件查看] 目录 一.ORM的"三国志" 2 1,PDF.NET诞生历程 2 2,Linq2 ...
- WCF Data Service 使用小结(二) —— 使用WCF Data Service 创建OData服务
在 上一章 中,介绍了如何通过 OData 协议来访问 OData 服务提供的资源.下面来介绍如何创建一个 OData 服务.在这篇文章中,主要说明在.NET的环境下,如何使用 WCF Data Se ...
- IbatisNet开发使用小结
一. 介绍 平常做企业级应用,需求变化是经常的事,而很多基础代码重复也是很让人头疼的问题.所以很多人会使用一些ORM框架来增强项目的可维护性.可扩展性.IBatis.Net就是一个比较易用的ORM ...
- 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(28)-系统小结
原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(28)-系统小结 我们从第一节搭建框架开始直到二十七节,权限管理已经告一段落,相信很多有跟上来的园友,已经 ...
- 自定义ORM框架(转转)
ORM背景 在数据库界,主流的数据库都是关系型数据库,其采用的关系型数据结构模型,无论从数学上还是实践中都相当的成熟,得到非常广泛的应用.在关系型数据结构理 论中,所有的数据都组织成一个个相互独立的二 ...
随机推荐
- IISExpress 开放局域网访问
1. 设置 IISExpress 配置文件 applicationhost.config VS2015 :这个配置文件 在工程目录下的 .vs/config 隐藏目录 其他版本 :在用户目录中的 II ...
- stm32 定时器TIM时钟步骤
1)TIM3 时钟使能 . RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIMx, ENABLE); //时钟使能 2) 初始化定时器参数,设置自动重装值, 分频系数, ...
- Unity3D-常用小功能详解,例子(得分变动效果、倒计时)
Unity3D-Demo多个功能方法 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 1 Score Ind ...
- EasyTouch中多种QuickGesture手势检测
EasyTouch中QuickGesture的用法 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 1 Qu ...
- CTF-练习平台-Misc之 妹子的陌陌
二十五.妹子的陌陌 该图片后缀名为rar,发现里面有一个文本 但是解压需要密码,应为不知道是几位的没法爆破,观察图片后发现红色字体:“喜欢我吗.”尝试一下,居然是密码,将文本解压出来 内容如下: 嘟嘟 ...
- (研) int(*p)[10]; int *p[10]; int(*)[10]; 之间的区别
int *p[10]; 从这个最简单的说起 p先与后面的[4]结合,说明他本质是一个数组 ,“[]”的优先级比“*”要高.p先与“[]”结合,构成一个数组的定义,数组名为p,int *修饰的是数组的内 ...
- knowledge-repo 知识管理简单试用
knowledge-repo 是airbnb 开源的知识管理工具,只集成git 数据库等类型的存储 安装 pip install --upgrade "knowledge-repo[all] ...
- svn分支开发注意事项
1.切换的时候最好查看本文件的是主干上的还是分支上的, 单击右键,点击属性,可以看到以下图片,其中"URL"就可以 看到是主干还是分支 2.切换到分支 点击切换后就选择要切换到的路 ...
- php重新整理数组索引
语法 array_merge(array1,array2,array3...) 参数 描述 array1 必需.输入的第一个数组. array2 必需.输入的第二个数组. array3 可选.可指定的 ...
- 看懂Class文件的装载流程
Class文件的加载过程 ClassLoader的工作模式 类的热加载 1 Class文件的装载流程 只有被java虚拟机装载的Class类型才能在程序中使用(注意装载和加载的区别) 1.1 类装载的 ...