一:项目中每个类的作用

    • 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。
    • 看代码
    • class FilterOption(object):
          def __init__(self,field_name,multi=False,condition=None,is_choice=False,text_func_name=None,val_func_name=None):
              """
              :param field_name: 字段
              :param multi:  是否多选
              :param condition: 显示数据的筛选条件
              :param is_choice: 是否是choice
              :param text_func_name: 在Model中定义函数,显示文本名称,默认使用str(对象)
              :param val_func_name: 在Model中定义函数,页面生成的a标签中对应的值的函数.  默认使用 对象.pk
              """
              self.field_name = field_name
              self.multi = multi
              self.is_choice = is_choice
      
              self.condition = condition
      
              self.text_func_name = text_func_name
              self.val_func_name = val_func_name
      
          def get_queryset(self,_field):
              if self.condition:
                  return _field.rel.to.objects.filter(**self.condition)
              return _field.rel.to.objects.all()
      
          def get_choices(self,_field):
              return _field.choices
      
      class FilterRow(object):
          def __init__(self,option, data, request):
              self.data = data
              self.option = option # option: 要配置的对象  v1.FilterOption('depart',text_func_name=None,val_func_name=None)
              self.request = request
      
          def __iter__(self):
              params = copy.deepcopy(self.request.GET)
              params._mutable = True
              current_id = params.get(self.option.field_name) # 3
              current_id_list = params.getlist(self.option.field_name) # [1,2,3]
      
              if self.option.field_name in params:
                  # del params[self.option.field_name]
                  origin_list = params.pop(self.option.field_name)
                  url = "{0}?{1}".format(self.request.path_info, params.urlencode())
                  yield mark_safe('<a href="{0}">全部</a>'.format(url))
                  params.setlist(self.option.field_name,origin_list)
              else:
                  url = "{0}?{1}".format(self.request.path_info, params.urlencode())
                  yield mark_safe('<a class="active" href="{0}">全部</a>'.format(url))
              # ( (1,男),(2,女)  )
              for val in self.data:
                  print('val---',val)
                  if self.option.is_choice:
                      pk,text = str(val[0]),val[1]
                  else:
                      # 如果你设置了这个函数就走你设置的函数,否则 str(val) str(val.pk)
                      text = self.option.text_func_name(val) if self.option.text_func_name else str(val)
                      pk = str(self.option.val_func_name(val)) if self.option.val_func_name else str(val.pk)
                      # pk = str(self.option.val_func_name(val)) if self.option.val_func_name else str(val.pk)
                      # pk,text = str(val.pk), str(val)
                  # 当前URL?option.field_name
                  # 当前URL?gender=pk
                  # self.request.path_info # http://127.0.0.1:8005/arya/crm/customer/?gender=1&id=2
                  # self.request.GET['gender'] = 1 # &id=2gender=1
                  if not self.option.multi:
                      # 单选
                      params[self.option.field_name] = pk
                      url = "{0}?{1}".format(self.request.path_info,params.urlencode())
                      if current_id == pk:
                          yield mark_safe("<a class='active' href='{0}'>{1}</a>".format(url,text))
                      else:
                          yield mark_safe("<a href='{0}'>{1}</a>".format(url, text))
                  else:
                      # 多选 current_id_list = ["1","2"]
                      _params = copy.deepcopy(params)
                      id_list = _params.getlist(self.option.field_name)
      
                      if pk in current_id_list:
                          id_list.remove(pk)
                          _params.setlist(self.option.field_name, id_list)
                          url = "{0}?{1}".format(self.request.path_info, _params.urlencode())
                          yield mark_safe("<a class='active' href='{0}'>{1}</a>".format(url, text))
                      else:
                          id_list.append(pk)
                          # params中被重新赋值
                          _params.setlist(self.option.field_name,id_list)
                          # 创建URL
                          url = "{0}?{1}".format(self.request.path_info, _params.urlencode())
                          yield mark_safe("<a href='{0}'>{1}</a>".format(url, text))

      组合搜索相关

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

    第二种:

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

    •   代码:

      class Foo(object):
          _instance = None
      
          def __init__(self, name):
              self.name = name
      
          @classmethod
          def instance(cls, *args, **kwargs):
              if not Foo._instance:
                  obj = Foo(*args, **kwargs)
                  Foo._instance = obj
              return Foo._instance
      
      obj1 = Foo.instance('ff')
      obj2 = Foo.instance('ff')
      print(id(obj1), id(obj2))

      单例

      什么时候用单例模式?

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

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

    def public_view(self,request):
        """
        公共客户资源, 未报名 & (15天未接单 or 三天未跟进)
        """

        current_user_id = 9

        # 当前日期
        current_date = datetime.datetime.now().date()
        # 最后接单时间
        no_deal = current_date - datetime.timedelta(days=15)
        # 最后跟进日期
        no_follow_date = current_date - datetime.timedelta(days=3)

        """公共客户"""
        # 方法一:
        # customer_list = models.Customer.objects.filter(Q(recv_date__lt=no_deal)|Q(last_consult_date__lt=no_follow),status=2)
        # customer_list = models.Customer.objects.filter(Q(recv_date__lt=no_deal)|Q(last_consult_date__lt=no_follow_date),status=2)
        # print('9999999999',customer_list)
        # 方法二:
        con = Q()
        q1 = Q(status=2)
        q2 = Q()
        q2.connector = 'OR'
        q2.children.append(('recv_date__lt', no_deal))
        q2.children.append(('last_consult_date__lt', no_follow_date))
        con.add(q1,'AND')
        con.add(q2,'AND')
        customer_list = models.Customer.objects.filter(con)

        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. def(request):
    2. a=models.UserInfo._meta.get_field('name')

    3. #app01.UserInfo.name

    4. b=models.UserInfo._meta.fields

    5. #(<django.db.models.fields.AutoField:id>,
    6. #<django.db.models.fields.CharField:name>,
    7. #<django.db.models.fields.CharField:username>,
    8. #<django.db.models.fields.CharField:password>,
    9. #<django.db.models.fields.EmailField:email>,
    10. #<django.db.models.fields.related.ForeignKey:depart>)

    1. c=models.UserInfo._meta._get_fields()

    2. #(<ManyToOneRel:app01.classlist>,
    3. #<ManyToManyRel:app01.classlist>,
    4. #<ManyToOneRel:app01.customer>,
    5. #<ManyToOneRel:app01.customerdistribution>,
    6. #<ManyToOneRel:app01.salerank>,
    7. #<ManyToOneRel:app01.consultrecord>,
    8. #<ManyToOneRel:app01.paymentrecord>,
    9. #<ManyToOneRel:app01.courserecord>,
    10. #<django.db.models.fields.AutoField:id>,
    11. #<django.db.models.fields.CharField:name>,
    12. #<django.db.models.fields.CharField:username>,
    13. #<django.db.models.fields.CharField:password>,
    14. #<django.db.models.fields.EmailField:email>,
    15. #<django.db.models.fields.related.ForeignKey:depart>)

    1. d=models.UserInfo._meta.many_to_many#()

1

# 根据类名获取响应字段

model.UserInfo
        model.UserInfo._meta.app_label#获取当前app的名称
        model.UserInfo._meta.model_name#获取当前类名小写
        model.UserInfo._meta.get_field('username')#获取字段

        model.UserInfo._meta.get_field('username').verbose_name#获取verbose_name
        model.UserInfo._meta.get_field('外键或多对多字段').rel.to #得到关联的model类

        - models.UserInfo._meta.get_field('name') # 根据字段名称,获取字段对象
        - models.UserInfo._meta.fields # 获取类中所有的字段
        - models.UserInfo._meta._get_fields() # 获取类中所有的字段(包含反向关联的字段)
        - models.UserInfo._meta.many_to_many # 获取m2m字段

2

# 获取当前类的对象,所反向关联的字段

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

3

六:模糊搜索功能

知识:

  - contains

  - Q查询

    - 示例:

Q
    con = Q()

            q1 = Q()
            q1.connector = 'or'
            q1.children.append( ('name','ff1') )
            q1.children.append( ('name','ff2') )

            q2 = Q()
            q2.children.append( ('age__gt',18))
            q2.children.append( ('id__gt',18))

            con.add(q1,'OR')
            con.add(q2,'OR')
            # (name='ff' or name=='ff2') or (age>18 and id > 18)

        queryset = self.model_class.objects.filter(con)

Q

代码:

show_search_form = False # 是否显示搜索框
    def get_show_search_form(self):
        return self.show_search_form

    search_fields = []          # 搜索的字段
    def get_search_fields(self):
        result = []
        if self.search_fields:
            result.extend(self.search_fields)

        return result

    def get_search_condition(self):
        key_word = self.request.GET.get(self.search_key)
        search_fields = self.get_search_fields()
        condition = Q()
        condition.connector = 'or'
        if key_word and self.get_show_search_form():
            for field_name in search_fields:
                condition.children.append((field_name, key_word))
        return condition

后台相关

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

配置代码

{% if cl.show_search_form %}
        <div class="form-group pull-right">
            <form method="get">
                <input name="{{ cl.config.search_key }}" value="{{ cl.search_form_val }}" class="form-control"
                       placeholder="请输入搜索条件" type="text" style="display:inline-block;width: 200px;"/>
                <button class="btn btn-primary"><span class="glyphicon glyphicon-search"></span></button>
            </form>
        </div>
    {% 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方法定制起始文件

- 文件导入实现单例模式

from django.apps import AppConfig

class StarkConfig(AppConfig):
    name = 'stark'

    def ready(self):
        from django.utils.module_loading import autodiscover_modules
        autodiscover_modules('stark')

stark/apps

 十三:inclusion_tag

  • 用于popup生成,之前的代码里有。
    • 友情链接:popUp
    •   我们通过对一个 Library 对象使用 inclusion_tag() 方法来创建并注册这个包含标签。
    • 将当前所装饰的函数得到的值,传入到inclusion_tag()的html中,如果有模板需要用到这个html模板(将此作为基板),则需要在当前模板中
      {% 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. Kendo DataSource 概述

    Kendo DataSource 概述 Kendo 的数据源支持本地数据源( JavaScript 对象数组),或者远程数据源(XML, JSON, JSONP),支持 CRUD 操作(创建,读取,更 ...

  2. Log Structured Merge Trees(LSM) 算法

    十年前,谷歌发表了 “BigTable” 的论文,论文中很多很酷的方面之一就是它所使用的文件组织方式,这个方法更一般的名字叫 Log Structured-Merge Tree. LSM是当前被用在许 ...

  3. specrate 与specspeed 的区别

    What is the difference between a "rate" and a "speed" metric?There are several d ...

  4. 对fgets末尾'\0'的处理

    之所以要对fgets自动添加的字符进行处理的原因之一是:当你想比较输入的字符时,你会发现输入的字符和源码用来进行对比的字符一模一样,但是使用strcmp比较时就是不一样,原因就是fgets对输入字符添 ...

  5. Docker搭建

    环境基于CentOS64位,内核最好3.10. 1.下载安装 docker      dockersudo yum install docker-io (假如内核版本太低的话,会在下载安装Docker ...

  6. 一点对Promise的理解与总结

    全手打原创,转载请标明出处:https://www.cnblogs.com/dreamsqin/p/10959411.html,多谢,=.=~ axios用多了就开始疑惑它里面到底是个啥,虽然总被告知 ...

  7. 洛谷 P2383 狗哥玩木棒

    题目背景 狗哥又趁着语文课干些无聊的事了... 题目描述 现给出一些木棒长度,那么狗哥能否用给出的木棒(木棒全用完)组成一个正方形呢? 输入输出格式 输入格式: 输入文件中的第一行是一个整数n表示测试 ...

  8. xwork-conversion.properties 目前没有解决方案

    它没法变成.xml 这意味着项目里就只能这样

  9. jquery的uploadify插件实现的批量上传V3.2.1版

    你需要如下配置(包括引入文件)HTML: <html xmlns="http://www.w3.org/1999/xhtml"> <head runat=&quo ...

  10. tpcc-mysql 实践

    一.TPCC 介绍 TPC:全称Transaction Processing Performance Council (事务处理性能委员会),是一家非盈利性组织,该组织制定各种商业应用的基准测试规范, ...