一:项目中每个类的作用

    • 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. 用户登录保存数据实例(慕课笔记 使用SharedPreferences保存用户名)

    学习视频之后自己操作时的笔记. 0.视频地址:http://www.imooc.com/video/3265 1.功能预览: 说明:1)输入错误用户名和密码,点击登录,弹出提示框“禁止登录”: 2)输 ...

  2. window对象的几个重要方法

    <!DOCTYPE html><html><head><meta charset="UTF-8"><title>Java ...

  3. POJ Charlie's Change 查理之转换(多重背包,变形)

    题意: 给定身上的4种硬币,分别是1 ,5 ,10, 25面额各有多张,要求组成面额p的硬币尽可能多.输出组成p的4种硬币各自的数量. 思路: 多重背包,300+ms.用01背包+二进制的方法.记录下 ...

  4. Oracle CRS/GI 进程介绍

    在10g和11.1,Oracle的集群称为CRS(Oracle Cluster Ready Service), 在11.2,Oracle的集群称为GI(Grid Infrastructure). 对于 ...

  5. cookie存验证码时间,时间没走完不能再次点击

    <script> var balanceSeconds=getcookie('Num'); console.log(balanceSeconds) var timer; var isCli ...

  6. AJAX不能访问MVC后台程序的问题

    AJAX不能访问后台的MVC有可能是MVC的后台程序加入了身份验证[Authorize]标记,这样前台的AJAX虽然结果显示的是4和200但是responsetext的值可以看到是返回了一个配置文件中 ...

  7. stixel 理解

    在车辆所处平面建立极坐标占位网格(polar occupancy grid),将视差图所代表的三维世界(3D world) 正交投影到该平面中. occupancy:每个网格被赋予一个占位数,代表了该 ...

  8. key directories in the linux file system

    Key directories in the file system: */: Root directory (base of file system) /bin: Executable progra ...

  9. SCOPE_IDENTITY和@@IDENTITY[转]

    本文转自:http://www.cnblogs.com/daydayupanan/archive/2008/09/04/1283648.html SCOPE_IDENTITY和@@IDENTITY的作 ...

  10. 记住密码功能 JS结合JQuery 操作 Cookie 实现记住密码和用户名!

    // 记住密码功能 JS结合JQuery 操作 Cookie 实现记住密码和用户名! var username = document.getElementById("username&quo ...