CRM项目问答总结
1. 通过ChangeList封装好多数据
DA:
在stark组件中,有五个封装的大类:
class FilterOption(object): ----用于封装组合搜索的配置信息(数据库字段,是否多选,是否是choice)
class FilterRow(object):----生成按钮以及一系列的<a>标签
class ChangeList(object):----将列表页面的功能封装到此类中
class StarkConfig(object):----用于为每个类生成url的对应关系,并处理用户请求,处理增删改查的基类
class StarkSite(object):----是一个容器,用于放置处理请求的对应关系 2. 销售中公共资源:Q查询,3天 15天
DA:如果有新用户引进,对于销售来说,必须得跟进,但是跟进的过程中会有3天未跟进,15天未成单的限制。
如果该客户成为了公共资源,那么就会有抢单这一功能。在实现抢单时,一般的数据查询在这里不太适用,所有这里引用到Q查询,更高效的查出结果
Q:查询函数可以混合使用 Q 对象参数和关键字参数. 所有提供给查询函数的参数(不管是关键字参数还是Q对象)都被 "AND" 到一起.
如果提供了 Q 对象作为参数,它就必须在其它关键字参数(如果有的话)的前面 3. 使用yield实现
- 生成器函数,对数据进行加工处理
DA:在ChangeList中,def gen_comb_filter(self): 给前端进行循环显示数据用(生成器函数),
在生成器中返回可迭代对象,FilterRow对象(FilterRow对象是自己创建的)
- __iter__和yield配合 4. 获取Model类中的字段对应的对象
class Foo(model.Model):
xx = models.CharField() Foo.get_field('xx') 5. 模糊搜索功能
DA:模糊搜索就是在列表页面中,增加模糊关键字搜索功能,和是否显示添加按钮,actions定制,组合搜索都封装在了StarkConfig类中。
if key_word and self.get_show_search_form():
for field_name in search_fields:
condition.children.append((field_name, key_word))
return condition 6. Type创建类
DA:
用type创建动态的form如:
TempForm = type('TempForm',(Form,),{
'score_%s' %obj.pk :fields.ChoiceField(choices=models.StudyRecord.score_choices),
'homework_note_%s' %obj.pk : fields.CharField(widget=widgets.Textarea())
}) 7. 自动派单
DA:
-自动派单:
在处理自动派单问题时应该考虑到当前用户是否为公司的公共资源,在判断公共资源这个问题上就要根据当前用户是否为已经属于公共客户:
a:公共客户
所谓的公共的客户就是销售在规定的某个时间段内没有把客户转化为用户,或者没有在允许的时间内跟进,就会被转为公共用户。而成为公共用户之后,该销售则无权跟进(利用Q对象的方法进行排除),
但是也不排除,有的客户冥顽不灵,转化不了,其他的销售都不喜欢或者不愿意跟进,该销售也可以跟进。
b:自己的客户
所谓我的客户就是已经成单或者在规定时间内正在跟进的客户,而且在这里将会有一个客户跟进表中记录销售的跟进内容,生成一条跟进内容如果是一个新的客户的话,就设置一个定时的一个检查的脚本
,以用于查看销售的跟进记录。在新建的表里选出没有报名的用户,在没有报名的用户上加抢单功能,获取用户的ID,修改客户表中的客户,把接单时间修改为当前时间,跟进时间也是当前时间,修改客户顾问为现在的。 c:自动抢单
单条录入,创建url,进入用modelform写的页面,新增客户表中的数据,获取自动分配的课程顾问的ID,当前时间,在客户分配表中新增数据,获取新创建的客户ID,课程顾问ID,
而给课程顾问分配是跟据权重进行分配的 - 原来在内存中实现,问题:重启和多进程时,都有问题。
- redis
- 状态
- 原来数据(权重表 权重和个数) - pop数据
DA:在多选或者单选,后面必须添加popup按钮,因为如果是field是ModelChoiceField 则是Fk, 如果是ModelMultipChoice 则是M2M。编辑和增加弹出的子页面都用到了popup代码
需要重写一次,所以引入templatetags 8. 使用 list_diplay配置
DA:因为已经在v1.py中的的class StarkConfig类中封装了封装了前端列表定制列表页面显示的列,所有在使用时,只写数据库字段名即可
list_display = ['title','code'] 9. reverse反向生成URL
DA:
def index(request):
from django.urls import reverse
test_url = reverse('xxx')
return HttpResponse("index")
def back(requext):
return HttpResponse("back")
urlpatterns = [
url(r'^index/', index,),
url(r'^back/dd/nn/', back,name='xxx'),
] 10. 母版
DA:
在最外层的templates:stark>layout.html作为模板,让其他的相关页面去继承layout.html。大大 降低了代码重复 11. ready方法定制起始文件
DA:
就是在启动项目的同时,运用ready方法加载出来运行。 - 文件导入实现单例模式 12. inclusion_tag 13. 中间件的使用
-什么是中间件:
django中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。在django项目的settings模块中,
有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件 DA:-用户登录
- 日志记录
- csrf
- session
- 权限管理 15. importlib + getattr 16. FilterOption,lambda表达式
DA:
lanmbda是一个匿名函数它可以通过传给reduce中的函数,依次对数据集中的数据进行操作。 17. QueryDict
- 原条件的保留
- filter 18. ModelForm
DA:没有用Form,但是这里运用ModelForm创建自动生成的列表页面以及input框的错误提示信息 19. 面向对象的 @property @classmethod
DA:
@property是把一个方法变成属性可调用的
eg:把一个getter方法变成属性,只需要加上@property就可以了,此时,@property本身又创建了另一个装饰器@score.setter,负责把一个setter方法变成属性赋值,于是,
我们就拥有一个可控的属性操作(百度搜索到的说法)
@staticmethod可以不需要实例化,直接用 类名.方法名来调用
即:(两者的区别)
@staticmethod不需要表示自身对象的self和自身类的cla参数,就跟使用函数一样
@classmethod也不需要self参数,但第一个参数需要表示自身类的cls参数 20. mark_safe
DA:
后端解析前端代码,可在前端展示成前端页面,否则是字符串形式展示 21. 抽象方法抽象类+raise Im...
DA:
在base.py文件中运用了抽象方法
方法一:
from abc import ABCMeta
from abc import abstractmethod class BaseMessage(metaclass=ABCMeta):
@abstractmethod
def send(self,subject,body,to,name):
pass 方法二:
class BaseMessage(object):
def send(self, subject, body, to, name):
raise NotImplementedError('未实现send方法')
我们在dingding.py文件中用了抽象类
from .base import BaseMessage
class DingDing(BaseMessage):
def __init__(self):
pass
def send(self,subject,body,to,name):
print('钉钉消息发送成功') 22. 组件中的装饰器,实现self.request = request 23. 自执行函数
(function(arg){ })('sf') 24. URL的钩子函数
DA:
get_show_add_btn(self):
....
对于页面添加等按钮是否显示做出更细致的判断 25. 多继承
从左到右继承(钻石继承)
新式类:python3:广度优先
经典类:python2:深度优先 26. 批量导入,xlrd import xlrd
file_obj = request.FILES.get('exfile')
with open('xxxxxx.xlsx', mode='wb') as f:
for chunk in file_obj:
f.write(chunk) workbook = xlrd.open_workbook('xxxxxx.xlsx')
sheet = workbook.sheet_by_index(0)
maps = {
0: 'name',
1: 'qq',
}
for index in range(1, sheet.nrows):
row = sheet.row(index)
# {'name':"把几个",'qq':123456789}
# print(row,type(row))
row_dict = {}
for i in range(len(maps)):
key = maps[i]
cell = row[i]
row_dict[key] = cell.value 27. redis连接池
DA:
插入单条数据
import redis
conn = redis.Redis(host='10.0.0.10',port=6379)
conn.set('k1','v1') 向远程redis中写入了一个键值对
val = conn.get('k1') 获取键值对
print(val)
插入多条数据
conn = redis.Redis(host='10.0.0.10',port=6379) conn.lpush('names_list',*['把几个','鲁宁'])
v = conn.llen('names_list')
for i in range(v):
val = conn.rpop('names_list')
从右边第一条开始pop数据
val = conn.lpop('names_list')
从左边第一条开始pop数据
print(val.decode('utf-8'))
v = conn.llen('namessssss_list')
print(v) 28. 工厂模式
settings.py
MSG_PATH = "path.Email" class XXFactory(object):
@classmethod
def get_obj(cls):
settings.MSG_PATH
# rsplit
# importlib
# getattr
return obj class Email(object):
def send ... class WeChat(object):
def send ... class Msg(object):
def send ... 29. Models类中自定义save方法
# 创建客户表
#事物,如果一条失败,则全体失败
#通过form.instance.field_name添加其它字段数据
form.instance.consultant_id = sale_id
form.instance.recv_date = ctime
form.instance.last_consult_date = ctime
new_customer = form.save() 30. django admin中注册models时候
from django.contrib import admin from . import models # 方式一
class UserConfig(admin.ModelAdmin):
pass admin.site.register(models.UserInfo,UserConfig) # 方式二
@admin.register(models.UserInfo)
class UserConfig(admin.ModelAdmin):
pass 31. 深浅拷贝
DA:
浅拷贝copy:不管多么复杂的数据结构,浅拷贝都只会copy一层。
深拷贝deepcopy:其实深拷贝就是在内存中重新开辟一块空间,不管数据结构多么复杂,只要遇到可能发生改变的数据类型,
就重新开辟一块内存空间把内容复制下来,直到最后一层,不再有复杂的数据类型,就保持其
原引用。这样不管数据结构多么的复杂,数据之间的修改都不会相互影响。这就是深拷贝
深拷贝在哪里使用过:分页
CRM项目问答总结的更多相关文章
- 某CRM项目招投标工作的感悟
最近参与了某公司的CRM项目招标工作, 由于此项目涉及到的二级单位比较多,以及项目金额比较大,所以此招标工作从准备到宣布中标一直持续了大概3个月时间,中间过程发生了一些颇有意思的事情,因为保密的原因无 ...
- CRM项目总结
CRM项目总结 一:开发背景 在公司日益扩大的过程中,不可避免的会伴随着更多问题出现. 对外 : 如何更好的管理客户与公司的关系?如何更及时的了解客户日益发展的需求变 ...
- CRM项目之RBAC权限组件-day26
写在前面 上课第26天,打卡: 世间安得双全法 不负如来不负卿 s17day26 CRM项目 项目概要:XX公司CRM - 权限管理,公共组件,app ***** - 熟悉增删改查,Low *** - ...
- 读《31天学会CRM项目开发》记录2 - 企业信息管理系统
在信息技术的快速推动下,企业如果依然利用传统的管理方式,以人为主,那效率便会大打折扣.在此背景下,企业信息化系统得 到了高速发展.如我们常见的ERP系统.MES系统,都是提高公司运行效率,降低运营以及 ...
- 读《31天学会CRM项目开发》记录1 - 认识软件开发
今天闲来无事,心中又对软件开发充满了向往和憧憬.一直认为实践是检验真知的唯一标准,也是快速提升的绝密方法,是巩固基础加深基础的好去处.故在JD上搜了下软件开发,看到了这本<31天学会CRM项目开 ...
- crm项目整理
crm项目整理 一.开发背景 由于公司人员的增多,原来通过excel表格存取方式过于繁琐,而且对于公司人员的调配和绩效考核等不能做到精确处理,所以开发crm系统,开始开发只是针对销售人员和客户,后 ...
- Linux下运行crm项目
虚拟环境运行crm项目 1.进入虚拟环境 2.解决crm项目运行所需的依赖环境 1.手动解决 pip3 install django==1.11.14 pip3 install pymysql pip ...
- Django - CRM项目(2)Q查询(模糊查询)
一.CRM项目(2) 利用Q查询中的q对象完成条件筛选功能. 批量删除.公户转私户功能. 新增一张跟进记录表ConsultRecord,迁移数据库并添加测试数据,实现跟进记录列表页面. 客户列表新增跟 ...
- crm项目整理概要
一.开发背景 由于公司人员的增多,原来通过excel表格存取方式过于繁琐,而且对于公司人员的调配和绩效考核等不能做到精确处理,所以开发crm系统,开始开发只是针对销售人员和客户,后面陆续加上一些操作, ...
随机推荐
- socket编程头文件分析
在socket网络编程中经常用到一些宏定义.结构和函数,这些经常包含在相关的头文件中,使用时直接include相关头文件即可.下面简单描述下相关的一些结构及头文件. 1. sockaddr / bi ...
- poj 3246 Balanced Lineup(线段树)
Balanced Lineup Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 38942 Accepted: 18247 ...
- 数据库I/O:CMP、Hibernate
★什么是“Persistence” 用过VMWare的朋友大概都知道当一个guest OS正在运行的时候点击“Suspend”将虚拟OS挂起,它会把整个虚拟内存的内容保存到磁盘上,譬如你为虚拟OS分配 ...
- 多媒体开发之rtsp 打包发流---rtsp发送
http://blog.csdn.net/ttxk/article/details/5279889 http://www.cnblogs.com/haibindev/p/3434922.html rt ...
- 【BZOJ】3396: [Usaco2009 Jan]Total flow 水流 (最大流)
http://www.lydsy.com/JudgeOnline/problem.php?id=3396 裸的最大流跑过.. #include <cstdio> #include < ...
- 在Intellij IDEA下用X-debug调试PHP
用Intellij IDEA使用X-debug来调试PHP,主要需要配置的部分有三个地方,分别为php.ini的配置,IDEA的配置和浏览器的配置,主要如下: php.ini(wamp修改的是phpF ...
- 根本上解决npm install 报错“ajv-keywords@3.4.0 requires a peer of ajv@^6.9.1 but none is installed. You must install peer dependencies yourself.“
每次项目npm install 的时候都报这个错误, 然后网上找的方法就把这个 ajv重新安装下,感觉有点麻烦, 后来有次我把npm更新了一下(我的版本是: 6.1.0),更新到了最新版本,这个问题就 ...
- IOS控件:计算文字长度(UITextField,UILabel对象 和 IBAction)
#import <UIKit/UIKit.h> // UIViewController类为程序提供了基本的视图管理模块 @interface NavControllerViewContro ...
- python 的时间复杂度
Python内置方法的时间复杂度 本文翻译自Python Wiki 本文基于GPL v2协议,转载请保留此协议. 本页面涵盖了Python中若干方法的时间复杂度(或者叫“大欧”,“Big O”).该时 ...
- OpenvSwitch2.4.0源码解读
原文发表在我的博客主页,转载请注明出处! 一.前言 OpenvSwitch,虚拟交换机,以下简称OVS,是云计算和SDN领域非常重要的一个开源交换机,如果需要深入研究云计算和SDN的数据平面,读懂OV ...