一:项目中每个类的作用

    • StarkSite
      • 对照admin中的AdminSite,相当于一个容器,用来存放类与类之间的关系。
        • 先实例化对象,然后执行该对象的register方法。将注册类添加到_register = {}中。
        • {

          models.UserInfo:StarkConfig(models.UserInfo,self),

          models.Role:StarkConfig(models.Role,self)

          }

  • StarkConfig
    • 用来处理增删改查的基类。
    • 以后每个自定义的类都需要继承的基类。
    • 页面上有请求过来时,先到该类下的视图函数。
      • Add_view下,要区分是否是popup添加。
  • ChangeList
    • 封装列表页面的功能的类。
  • 以下俩类都是关于组合搜索用。
    • 组合搜索时,先用到在ChangeList里面生成器函数gen_comb_filter中返回的row对象,然后在FilterRow创建__iter__方法,yield生成每个组合搜索需要的url。
    • FilterRow
      • 它的迭代对象为,页面上组合搜索的一行条件。
    • FilterOption
      • 自定义Config中,配置组合搜索的字段。(是否是多选,单选,choices。
    • 看代码
      1. class FilterOption(object):
      2. def __init__(self,field_name,multi=False,condition=None,is_choice=False,text_func_name=None,val_func_name=None):
      3. """
      4. :param field_name: 字段
      5. :param multi: 是否多选
      6. :param condition: 显示数据的筛选条件
      7. :param is_choice: 是否是choice
      8. :param text_func_name: 在Model中定义函数,显示文本名称,默认使用str(对象)
      9. :param val_func_name: 在Model中定义函数,页面生成的a标签中对应的值的函数. 默认使用 对象.pk
      10. """
      11. self.field_name = field_name
      12. self.multi = multi
      13. self.is_choice = is_choice
      14.  
      15. self.condition = condition
      16.  
      17. self.text_func_name = text_func_name
      18. self.val_func_name = val_func_name
      19.  
      20. def get_queryset(self,_field):
      21. if self.condition:
      22. return _field.rel.to.objects.filter(**self.condition)
      23. return _field.rel.to.objects.all()
      24.  
      25. def get_choices(self,_field):
      26. return _field.choices
      27.  
      28. class FilterRow(object):
      29. def __init__(self,option, data, request):
      30. self.data = data
      31. self.option = option # option: 要配置的对象 v1.FilterOption('depart',text_func_name=None,val_func_name=None)
      32. self.request = request
      33.  
      34. def __iter__(self):
      35. params = copy.deepcopy(self.request.GET)
      36. params._mutable = True
      37. current_id = params.get(self.option.field_name) # 3
      38. current_id_list = params.getlist(self.option.field_name) # [1,2,3]
      39.  
      40. if self.option.field_name in params:
      41. # del params[self.option.field_name]
      42. origin_list = params.pop(self.option.field_name)
      43. url = "{0}?{1}".format(self.request.path_info, params.urlencode())
      44. yield mark_safe('<a href="{0}">全部</a>'.format(url))
      45. params.setlist(self.option.field_name,origin_list)
      46. else:
      47. url = "{0}?{1}".format(self.request.path_info, params.urlencode())
      48. yield mark_safe('<a class="active" href="{0}">全部</a>'.format(url))
      49. # ( (1,男),(2,女) )
      50. for val in self.data:
      51. print('val---',val)
      52. if self.option.is_choice:
      53. pk,text = str(val[0]),val[1]
      54. else:
      55. # 如果你设置了这个函数就走你设置的函数,否则 str(val) str(val.pk)
      56. text = self.option.text_func_name(val) if self.option.text_func_name else str(val)
      57. pk = str(self.option.val_func_name(val)) if self.option.val_func_name else str(val.pk)
      58. # pk = str(self.option.val_func_name(val)) if self.option.val_func_name else str(val.pk)
      59. # pk,text = str(val.pk), str(val)
      60. # 当前URL?option.field_name
      61. # 当前URL?gender=pk
      62. # self.request.path_info # http://127.0.0.1:8005/arya/crm/customer/?gender=1&id=2
      63. # self.request.GET['gender'] = 1 # &id=2gender=1
      64. if not self.option.multi:
      65. # 单选
      66. params[self.option.field_name] = pk
      67. url = "{0}?{1}".format(self.request.path_info,params.urlencode())
      68. if current_id == pk:
      69. yield mark_safe("<a class='active' href='{0}'>{1}</a>".format(url,text))
      70. else:
      71. yield mark_safe("<a href='{0}'>{1}</a>".format(url, text))
      72. else:
      73. # 多选 current_id_list = ["1","2"]
      74. _params = copy.deepcopy(params)
      75. id_list = _params.getlist(self.option.field_name)
      76.  
      77. if pk in current_id_list:
      78. id_list.remove(pk)
      79. _params.setlist(self.option.field_name, id_list)
      80. url = "{0}?{1}".format(self.request.path_info, _params.urlencode())
      81. yield mark_safe("<a class='active' href='{0}'>{1}</a>".format(url, text))
      82. else:
      83. id_list.append(pk)
      84. # params中被重新赋值
      85. _params.setlist(self.option.field_name,id_list)
      86. # 创建URL
      87. url = "{0}?{1}".format(self.request.path_info, _params.urlencode())
      88. yield mark_safe("<a href='{0}'>{1}</a>".format(url, text))

      组合搜索相关

  • 二:单例模式
  • 第一种:文件导入

    第二种:

    •   自定义类方法(有代价,告知所有人,以后实例化时,不要再 类(),使用 类.instance() )

    •   代码:

      1. class Foo(object):
      2. _instance = None
      3.  
      4. def __init__(self, name):
      5. self.name = name
      6.  
      7. @classmethod
      8. def instance(cls, *args, **kwargs):
      9. if not Foo._instance:
      10. obj = Foo(*args, **kwargs)
      11. Foo._instance = obj
      12. return Foo._instance
      13.  
      14. obj1 = Foo.instance('ff')
      15. obj2 = Foo.instance('ff')
      16. print(id(obj1), id(obj2))

      单例

      什么时候用单例模式?

    • 我们希望当程序运行起来,只需要创建一份时:例如 site=StarkSite()
      • 全局变量在这也可以用(全局变量+类)
      • 单例模式
    • 使用(在哪里用到过程序运行只需要一份?):
      • stark注册时—文件导入       stark组件
      • redis连接(crm自动分配订单)
      • 数据库连接 + 数据库连接池

三:销售中的公共资源:Q查询,3天 15天

  1. def public_view(self,request):
  2. """
  3. 公共客户资源, 未报名 & (15天未接单 or 三天未跟进)
  4. """
  5.  
  6. current_user_id = 9
  7.  
  8. # 当前日期
  9. current_date = datetime.datetime.now().date()
  10. # 最后接单时间
  11. no_deal = current_date - datetime.timedelta(days=15)
  12. # 最后跟进日期
  13. no_follow_date = current_date - datetime.timedelta(days=3)
  14.  
  15. """公共客户"""
  16. # 方法一:
  17. # customer_list = models.Customer.objects.filter(Q(recv_date__lt=no_deal)|Q(last_consult_date__lt=no_follow),status=2)
  18. # customer_list = models.Customer.objects.filter(Q(recv_date__lt=no_deal)|Q(last_consult_date__lt=no_follow_date),status=2)
  19. # print('9999999999',customer_list)
  20. # 方法二:
  21. con = Q()
  22. q1 = Q(status=2)
  23. q2 = Q()
  24. q2.connector = 'OR'
  25. q2.children.append(('recv_date__lt', no_deal))
  26. q2.children.append(('last_consult_date__lt', no_follow_date))
  27. con.add(q1,'AND')
  28. con.add(q2,'AND')
  29. customer_list = models.Customer.objects.filter(con)
  30.  
  31. return render(request, 'public_view.html', {'customer_list':customer_list, "current_user_id":current_user_id})

public_view

四:使用yield实现

- 生成器函数,对数据进行加工处理

  - FilterRow里面,yield生成前端组合搜索中的每一行搜索条件。

- __iter__和yield配合

五:获取Model类中的字段对应的对象

  1. 1. def(request):
  2. 2. a=models.UserInfo._meta.get_field('name')
  3.  
  4. 3. #app01.UserInfo.name
  5.  
  6. 4. b=models.UserInfo._meta.fields
  7.  
  8. 5. #(<django.db.models.fields.AutoField:id>,
  9. 6. #<django.db.models.fields.CharField:name>,
  10. 7. #<django.db.models.fields.CharField:username>,
  11. 8. #<django.db.models.fields.CharField:password>,
  12. 9. #<django.db.models.fields.EmailField:email>,
  13. 10. #<django.db.models.fields.related.ForeignKey:depart>)
  14.  
  15. 1. c=models.UserInfo._meta._get_fields()
  16.  
  17. 2. #(<ManyToOneRel:app01.classlist>,
  18. 3. #<ManyToManyRel:app01.classlist>,
  19. 4. #<ManyToOneRel:app01.customer>,
  20. 5. #<ManyToOneRel:app01.customerdistribution>,
  21. 6. #<ManyToOneRel:app01.salerank>,
  22. 7. #<ManyToOneRel:app01.consultrecord>,
  23. 8. #<ManyToOneRel:app01.paymentrecord>,
  24. 9. #<ManyToOneRel:app01.courserecord>,
  25. 10. #<django.db.models.fields.AutoField:id>,
  26. 11. #<django.db.models.fields.CharField:name>,
  27. 12. #<django.db.models.fields.CharField:username>,
  28. 13. #<django.db.models.fields.CharField:password>,
  29. 14. #<django.db.models.fields.EmailField:email>,
  30. 15. #<django.db.models.fields.related.ForeignKey:depart>)
  31.  
  32. 1. d=models.UserInfo._meta.many_to_many#()

1

  1. # 根据类名获取响应字段
  2.  
  3. model.UserInfo
  4. model.UserInfo._meta.app_label#获取当前app的名称
  5. model.UserInfo._meta.model_name#获取当前类名小写
  6. model.UserInfo._meta.get_field('username')#获取字段
  7.  
  8. model.UserInfo._meta.get_field('username').verbose_name#获取verbose_name
  9. model.UserInfo._meta.get_field('外键或多对多字段').rel.to #得到关联的model类
  10.  
  11. - models.UserInfo._meta.get_field('name') # 根据字段名称,获取字段对象
  12. - models.UserInfo._meta.fields # 获取类中所有的字段
  13. - models.UserInfo._meta._get_fields() # 获取类中所有的字段(包含反向关联的字段)
  14. - models.UserInfo._meta.many_to_many # 获取m2m字段

2

  1. # 获取当前类的对象,所反向关联的字段
  2.  
  3. related_fileds=obj._meta.related_objects #得到当前对象的反向关联的所有字段
  4. for related_field in fileds
  5. _model_name=related_field.field.model._meta.model_name#获取当前关联字段所属的类名
  6. _related_name=related_field.related_name#获取当前字段中的_related_name(反向查找的别名)
  7. _field_name=related_field.field_name#获取当前字段跟其他表所关联的字段(to_field='')
  8. _limit_choices_to=related_obj.limit_choices_to

3

六:模糊搜索功能

知识:

  - contains

  - Q查询

    - 示例:

  1. Q
  2. con = Q()
  3.  
  4. q1 = Q()
  5. q1.connector = 'or'
  6. q1.children.append( ('name','ff1') )
  7. q1.children.append( ('name','ff2') )
  8.  
  9. q2 = Q()
  10. q2.children.append( ('age__gt',18))
  11. q2.children.append( ('id__gt',18))
  12.  
  13. con.add(q1,'OR')
  14. con.add(q2,'OR')
  15. # (name='ff' or name=='ff2') or (age>18 and id > 18)
  16.  
  17. queryset = self.model_class.objects.filter(con)

Q

代码:

  1. show_search_form = False # 是否显示搜索框
  2. def get_show_search_form(self):
  3. return self.show_search_form
  4.  
  5. search_fields = [] # 搜索的字段
  6. def get_search_fields(self):
  7. result = []
  8. if self.search_fields:
  9. result.extend(self.search_fields)
  10.  
  11. return result
  12.  
  13. def get_search_condition(self):
  14. key_word = self.request.GET.get(self.search_key)
  15. search_fields = self.get_search_fields()
  16. condition = Q()
  17. condition.connector = 'or'
  18. if key_word and self.get_show_search_form():
  19. for field_name in search_fields:
  20. condition.children.append((field_name, key_word))
  21. return condition

后台相关

  1. # 显示搜索并支持模糊搜索
  2. show_search_form = True
  3. search_fields = ['name__contains']

配置代码

  1. {% if cl.show_search_form %}
  2. <div class="form-group pull-right">
  3. <form method="get">
  4. <input name="{{ cl.config.search_key }}" value="{{ cl.search_form_val }}" class="form-control"
  5. placeholder="请输入搜索条件" type="text" style="display:inline-block;width: 200px;"/>
  6. <button class="btn btn-primary"><span class="glyphicon glyphicon-search"></span></button>
  7. </form>
  8. </div>
  9. {% endif %}

前端代码

七:Type创建类

看图:

内置的type()函数带有三个参数,

  • Type(name,bases,dict)
    • 它会返回一个新的type对象,类似于class语句的动态形式.
  • 参数 :
    • name 参数指的是你的类名.赋给新对象__name__属性
    •   bases 一个tuple,指定新类型的所有基类,赋给新对象__bases__属性
    • 父类, 因为支持多重继承,所以用tuple
    •   dict 字典类型,作为新类的命名空间,赋给新对象__dict__属性

      •   类的初始化元素

三个参数: 第一个参数为类名,第二个参数是要继承的类,第三个参数就是字段了。

本项目中的应用:

  在录入成绩的时候,动态创建类。根据自定义字段,获取到自己想要的数据。

八:自动派单

- 原来在内存中实现,问题:重启和多进程时,都有问题。

- redis

- 状态

- 原来数据(权重表 权重和个数)

- pop数据

九:reverse反向生成URL

  根据url中name字段。使用reverse来反向生成url。如果有namespace字段,则需要使用 :号来分隔爱。 前面是namespace,后面是name。  

十:模版继承

母版: 在页面最上方加上{% block content %}...{% endblock %}

基板:如何继承?

  页面最上方:{% extend '模板路径' %}

  页面内容中:{% block content %}...{% endblock %}

懂了没?  不懂的话... 看图:

十一:ready方法定制起始文件

- 文件导入实现单例模式

  1. from django.apps import AppConfig
  2.  
  3. class StarkConfig(AppConfig):
  4. name = 'stark'
  5.  
  6. def ready(self):
  7. from django.utils.module_loading import autodiscover_modules
  8. autodiscover_modules('stark')

stark/apps

 十三:inclusion_tag

  • 用于popup生成,之前的代码里有。
    • 友情链接:popUp
    •   我们通过对一个 Library 对象使用 inclusion_tag() 方法来创建并注册这个包含标签。
    • 将当前所装饰的函数得到的值,传入到inclusion_tag()的html中,如果有模板需要用到这个html模板(将此作为基板),则需要在当前模板中
      1. {% inclusion_tag所修饰的函数名 参数一 参数二....%}
    • 看图吧还是。  那个load change_form是一个py文件,里面放的就是图一的东西。

十四:中间件的使用

  • 用户登录来一个
  • 登陆后用户权限来一个

15. importlib + getattr

16. FilterOption,lambda表达式

17. QueryDict

- 原条件的保留

- filter

18. ModelForm

19. 面向对象的 @property  @classmethod

20. mark_safe

21. 抽象方法抽象类+raise Im...

22. 组件中的装饰器,实现self.request = request

23. 自执行函数

(function(arg){

})('sf')

24. URL的钩子函数

def extra_url(self):

pass

25. 多继承

26. 批量导入,xlrd

27. redis连接池

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方法

?????????????????????????

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. 深浅拷贝(http://blog.csdn.net/jerry_1126/article/details/41852591)

  1. 深浅拷贝都是对源对象的复制,占用不同的内存空间
  2. 如果源对象只有一级目录的话,源做任何改动,不影响深浅拷贝对象
  3. 如果源对象不止一级目录的话,源做任何改动,都要影响浅拷贝,但不影响深拷贝
  4. 序列对象的切片其实是浅拷贝,即只拷贝顶级的对象

CRM知识点汇总(未完💩💩💩💩💩)的更多相关文章

  1. ASP.NET MVC 系列随笔汇总[未完待续……]

    ASP.NET MVC 系列随笔汇总[未完待续……] 为了方便大家浏览所以整理一下,有的系列篇幅中不是很全面以后会慢慢的补全的. 学前篇之: ASP.NET MVC学前篇之扩展方法.链式编程 ASP. ...

  2. CareerCup All in One 题目汇总 (未完待续...)

    Chapter 1. Arrays and Strings 1.1 Unique Characters of a String 1.2 Reverse String 1.3 Permutation S ...

  3. 清华大学OS操作系统实验lab1练习知识点汇总

    lab1知识点汇总 还是有很多问题,但是我觉得我需要在查看更多资料后回来再理解,学这个也学了一周了,看了大量的资料...还是它们自己的80386手册和lab的指导手册觉得最准确,现在我就把这部分知识做 ...

  4. ECMAScript版本知识点汇总

    ECMAScript版本知识点汇总 ES5 btoa.atob 对参数进行base64格式编码.解码 /** * btoa() * base64编码 * @param {string} str * @ ...

  5. 前端开发 JavaScript 干货知识点汇总

    很多初学的朋友经常问我,前端JavaScript都需要学习哪些东西呀?哪些是JavaScript的重点知识啊? 其实做前端开发工程师,所有的知识点都是我们学习必备的东西,只有扎实的技术基础才是高薪的关 ...

  6. javascript有用小功能总结(未完待续)

    1)javascript让页面标题滚动效果 代码如下: <title>您好,欢迎访问我的博客</title> <script type="text/javasc ...

  7. 关于DOM的一些总结(未完待续......)

    DOM 实例1:购物车实例(数量,小计和总计的变化) 这里主要是如何获取页面元素的节点: document.getElementById("...") cocument.query ...

  8. 我的SQL总结---未完待续

    我的SQL总结---未完待续 版权声明:本文为博主原创文章,未经博主允许不得转载. 总结: 主要的SQL 语句: 数据操作(select, insert, delete, update) 访问控制(g ...

  9. virtualbox搭建ubuntu server nginx+mysql+tomcat web服务器1 (未完待续)

    virtualbox搭建ubuntu server nginx+mysql+tomcat web服务器1 (未完待续) 第一次接触到 linux,不知道linux的确很强大,然后用virtualbox ...

随机推荐

  1. arcgis jsapi接口入门系列(0):总览

    开发环境: arcgis jsapi版本4.9 由于我们这套代码是基于vue,webpack开发的,会有少数vue代码,但总体不影响 里面还有些我们公司的js库和html css,给出的代码不能百分百 ...

  2. deb软件安装

    deb是debian linux的安装格式,跟red hat的rpm非常相似,最基本的安装命令是:dpkg -i file.deb dpkg 是Debian Package的简写,是为Debian 专 ...

  3. 剑指offer课外两道习题解法

         1.定义一个函数,删除字符串中所有重复出现的字符,例如输入“google”,删除重复的字符之后的结果为“gole”. 解题思路:像这种求字符串的重复字符,并且去掉重复字符,我们一般可以用哈希 ...

  4. 小目标 | Power BI新人快速上手手册

    · 适用人群:数据分析专业人士,在数据分析方向需求发展人士 · 应用场景:数据汇报.数据可视化展现.数据建模分析 · 掌握难度:★★★★☆ 本期讲师 『PowerPivot工坊』公众号提供Power ...

  5. MySQL查询优化方法总结

    1.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描. 2.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉 ...

  6. Jquery 事件 DOM操作

    常规事件: 把JS的事件  on去掉即可 例如:js    document.getElementById("id").onclinck=function(){} Jquery   ...

  7. github的pull Request使用

    场景: teamA要一起做一个项目,选择用github管理自己的代码仓库,这时userA在github上新建了一个远程仓库,其他人需要通过pull request来实现提交.那么,问题来了,pull ...

  8. pycharm使用秘籍 和 pip命令

    python使用requirements.txt批量安装包 requirements.txt文件格式: requests==1.2.0  Flask==0.10.1 等等一系列包 cd 到requir ...

  9. DDOS介绍

    DDOS: Data Domain Operating System(DD OS),即数据域操作系统----管理EMC的数据域拷贝存储系统(powers EMC Data Domain dedupli ...

  10. UVA 1613 K-Graph Oddity K度图着色 (构造)

    题意:在一个n个点的无向连通图中,n是奇数,k是使得所有点的度数不超过k的最小奇数,询问一种染色方案,使得相邻点的颜色不同. 题解:一个点和周围的点的颜色数加起来最大为它的度数+1:如果最大度数是偶数 ...