statrc部分
1. 如何使用
#- 在app中编写 stark.py #- 在stark.py中进行定制 #- 默认配置: #site.register(models.UserInfo) #- 自定义配置: #class UserConfig(StarkConfig): #list_display = [] # 表格式列表上显示的字段 #def get_list_display(): #order_by = [] # 排序 #action_list=[] # 批量操作 #search_list = [] # 模糊搜索 #list_filter = [] # 组合搜索 #add_btn # 是否显示添加按钮 #model_form_class # 自定义ModelForm #def extra_url(self): # 自定义扩展 URL #def get_urls(self): # 自定义URL #def changelist_view(self,request): #def add_view(self,request): #def change_view(self,request): #def del_view(self,request): #site.register(models.UserInfo,UserConfig)
1. 类当做key
2. django中的model所在app名称、以及小写类名。
#def index(request): # #print(m1.UserInfo,m1.UserInfo._meta.app_label,m1.UserInfo._meta.model_name) # #print(m2.Role,m2.Role._meta.app_label,m2.Role._meta.model_name) # 获取当前models类所在app名称、以及小写类名。 _registry = { m1.UserInfo:'1', m2.Role:'2', } for k,v in _registry.items(): print(k._meta.app_label,k._meta.model_name) return HttpResponse('...')
1. stark介绍
快速完成对N张表增删改查+自定义复杂操作。
2. 单例模式
我们这么写: zhaosen.py class AdminSite(object): pass obj1 = AdminSite() 调用实例: import zhaosen zhaosen.obj1 zhaosen.obj1
3. 路由系统
- include - namespace - 补充: 项目/urls.py from django.conf.urls import url,include from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^rbac/', ([ url(r'^login/', views.login), url(r'^logout/', views.logout), url(r'^x1/', ([ url(r'^add/', views.add,name='n1'), url(r'^change/', views.change,name='n2'), ],None,'xxx')), ],None,'rbac')), ] app01/views.py from django.shortcuts import render from django.shortcuts import HttpResponse from django.urls import reverse def login(request): url1 = reverse('rbac:xxx:n1') url2 = reverse('rbac:xxx:n2') print(url1) print(url2) return HttpResponse('login') def logout(request): return HttpResponse('logout') def add(request): return HttpResponse('add') def change(request): return HttpResponse('change')
4. 启动后、路由加载前定制一段代码。
a. 创建一个stark app 组件 b. 编写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') 程序启动时,会先去每个app中找stark.py文件并加载。 c. 其他app中创建stark.py d. 程序启东时便会自动加载 stark.py
1. 继承关系
class StarkConfig(object): list_display = [] def __init__(self,model_class): self.model_class = model_class def changelist_view(self,request): print(self.list_display) return 123 class RoleConfig(StarkConfig): list_display = ['id','name'] obj1 = StarkConfig('alex') obj2 = RoleConfig('oldboy') obj1.changelist_view(1) # [] obj2.changelist_view(2) # [id,name]
1. 方法和函数的区别?
from types import MethodType,FunctionType def check(arg): """ 判断arg是函数则打印1,arg是方法则打印2 :param arg: :return: """ if isinstance(arg,MethodType): print(2) elif isinstance(arg,FunctionType): print(1) else: print('不认识') def func(): pass class Foo(object): def display(self): pass check(func) check(Foo.display) check(Foo().display)
yield
def get_result(data_list): for row in data_list: temp = "%s%s" (row.name,row.pwd,) yield temp def func(request): data_list = models.Users.objects.all() result = get_result(data_list) return render(request,'xxx.html',{'result':result}) xxx.html {% for row in result %} {{row}} {% endfor%}
3. getattr
def test(request): from app01 import models list_display = ['id','title'] user_queryset = models.UserInfo.objects.all() for item in user_queryset: row = [] for field in list_display: row.append(getattr(item,field)) print(row) return HttpResponse('...') 补充:自定义页面显示列 def test(request): from app01 import models list_display = ['id','title'] header_list = [] for name in list_display: header_list.append(models.UserInfo._meta.get_field(name).verbose_name) print(header_list) user_queryset = models.UserInfo.objects.all() for item in user_queryset: row = [] for field in list_display: row.append(getattr(item,field)) print(row) return HttpResponse('...')
3.5 装饰器
import functools def wrapper(func): @functools.wraps(func) def inner(*args, **kwargs): return func(*args, **kwargs) return inner @wrapper def f1(): print('f1') @wrapper def f2(): print('f1') print(f1.__name__) print(f2.__name__)
1. 静态字段和字段
class Foo: x = 1 # 类变量、静态字段、静态属性 def __init__(self): y = 6 # 实例变量、字段、对象属性 # 实例方法 def func(self): pass # 静态方法 @staticmethod def func(): pass # 类方法 @classmethod def func(): pass @property def start(self) pass
2. 函数
#获取函数的名字,可通过 函数.__name__
3. urlencode
info = {'k1':'v1','k2':'v2'} from urllib.parse import urlencode info = {'k1':'v1','k2':'v2','k3':'v3'} v = urlencode(info) print(v)
4.django中使用 request.GET --> QueryDict
import copy def test(request): from django.http.request import QueryDict print(request.GET) # <QueryDict: {'k2': ['v2', 'v3'], 'k1': ['v1']}> # params = copy.deepcopy(request.GET) params = request.GET.copy() params._mutable = True params['k1'] = 666 params['k3'] = 78 params.setlist('k4',[10,12]) print(params['k2']) # request.GET.get('xx') old = params.getlist('k2') old.append('v4') params.setlist('k2',old) # v1 = params.urlencode() # print(v1) # k1=v1&k2=v2&k2=v3 print(params) return HttpResponse('...')
5. 保留原来搜索条件
def test(request): from django.http.request import QueryDict url_params_str = request.GET.urlencode() # _filter = k1=v1&k2=v2&k2=v3 query_dict = QueryDict(mutable=True) query_dict['_filter'] = url_params_str new_params = query_dict.urlencode() target_url = "/add_stu/?%s" %new_params return redirect(target_url) def add_stu(request): if request.method == "GET": return render(request,'add_stu.html') # 接收到数据,保存到数据库 origin_params = request.GET.get('_filter') back_url = "/test/?%s" %origin_params return redirect(back_url)
6. name包含 ‘大’ 或 email包含 “大”
q = Q() q.connecter = "OR" q.children.append(('name__contains', '大')) q.children.append(('email__contains', '大'))
1. 批量操作[扩展]
- 反射 - __name__ - 一切皆对象 def multi_delete(self,request): """ 批量删除的action :param request: :return: """ pk_list = request.POST.getlist('pk') self.model_class.objects.filter(pk__in=pk_list).delete() # return HttpResponse('删除成功') multi_delete.text = "批量删除"
2. 搜索[扩展]
# - Q # - __contains
3. 保留原搜索条件
- QueryDict,request.GET/request.POST - urlencode() - _mutable = True - 深拷贝 - urllib.parse.urlencode
4. 分页
#- 分页组件 #- 保留原条件
5. 拆分
#- ChangeList类封装 #- inclusion_tag #- 生成器
1. 三个类
#ChangeList,封装列表页面需要的所有数据。 #StarkConfig,生成URL和视图对应关系 + 默认配置 #AdminSite,用于保存 数据库类 和 处理该类的对象 的对应关系 + 路由分发 _registry = { }
2. 知识点
inclusion_tag yield urlencode _meta.model_name _meta.app_label 深浅拷贝 QueryDict对象默认不可改 _mutable=True 生成器 路由分发: - include - ([],None,None) 函数和方法的区别? Q的作用?构造复杂的查询条件 models.User.object.filter(name__contains='李') models.User.object.filter(name__contains='李',email__contains='李') 构造 or c1 = Q() c1.connector = 'OR' c1.children.append( ('name__contains','李') ) c1.children.append( ('email__contains','李') ) c2 = Q() c2.connector = 'ADN' c2.children.append( ('id__gt',2) ) c3.children.append( ('age__lte',5) ) c3 = Q() c3.connector = 'ADN' c3.add(c1,"ADN") c3.add(c2,"ADN") (name=li or email = li) AND ( id>2 and age<=5) models.User.object.filter(con) 反射 list_display: row.name getattr(row,'name') action: pass 继承 class RoleConfig(StarkConfig): pass self到底是谁? 反向生成URL reverse('xxx') reverse('namespace:xxx') 分页(保留原搜索条件) ModelForm组件 functools - wraps,用于保留原函数的元信息(函数名/函数注释等信息) - partial,偏函数为函数默认传参。 import functools def func(a1,a2): print(a1+a2) new_func = functools.partial(func,8) new_func(7) new_func(2) new_func(8) 预留可扩展位置 request.GET request.GET.get('x') request.GET['x'] request.GET.getlist('xxx') request.GET._mutable = True request.GET.copy() request.GET.urlencode() mark_safe xss攻击是什么? 单例模式 获取函数名 __name__ autodiscover_module 装饰器 order_by __str__
3. QueryDict对象
#params = request.GET.copy() #params._mutable = True #params['k1'] = 'v1' #params.setlist('k2',[11,22])
1. 可迭代对象?
class Row(object): def __init__(self,data): self.data = data def __iter__(self): yield "<div>" yield '全部' for item in self.data: yield "<a href='/index/?p1=1.0'>%s</a>" %item yield "</div>" data_list= [ Row(['1.0以下','1.1-1.6']), Row(['汽油','柴油','混合动力','电动']), ] for row in data_list: for field in row: print(field)
2.封装
list_filter = [ '董方方', '黄晓雪', '李贝贝', ] # ############################ 老封装思想 ############################ list_filter = [ {'text':'董方方','gender':'男','color':'xx'}, # 字典对象做封装 {'text':'黄晓雪','gender':'男','color':'xx'}, {'text':'李贝贝','gender':'男','color':'xx'}, ] for item in list_filter: print(item['text'] + item['gender']) # ############################ 老封装思想 ############################ class Option(object): def __init__(self,text,gender,color): self.text = text self.gender = gender self.color = color def get_t_g(self): return self.text +self.gender list_filter = [ Option(text='董方方',gender='男',color = 'xx'), # 字典对象做封装 Option(text='黄晓雪',gender='男',color = 'xx'), # 字典对象做封装 Option(text='李贝贝',gender='男',color = 'xx'), # 字典对象做封装 ] for item in list_filter: print(item.get_t_g())
3. 获取FK/M2M/O2O对应的表中所有的数据
class UserInfo(models.Model): title = models.CharField(verbose_name='标题',max_length=32) def __str__(self): return self.title class Depart(models.Model): name = models.CharField(verbose_name='部门名称',max_length=32) tel = models.CharField(verbose_name='联系电话',max_length=32) user = models.ForeignKey(verbose_name='负责人',to='UserInfo') def __str__(self): return self.name def get_fk_queryset(request): from app01 import models fk_obj = models.Depart._meta.get_field("user") user_info_queryset = fk_obj.rel.model.objects.all() print(user_info_queryset) return HttpResponse('...')
4. 组合搜索的功能
1. 字段配置 list_filter=['name','tel'] 内部: _field = self.config.model_class._meta.get_field('name') if isinstance(_field, ForeignKey) or isinstance(_field, ManyToManyField): _field.rel.model.objects.all() else: model_class.objects.all() 2. list_filter=[Option(),Option()] 内部: 字段 自定义条件 3. list_filter=[Option(),Option()] 内部: Row对象 (可迭代对象) yield 低级 4. list_filter=[Option(),Option()] 内部: 处理单选 5. list_filter=[Option(),Option()] 内部: 处理多选 6. 数据搜索 7. 组合搜索应用: 使用情况: - FK - Choice - M2M Option参数: Option(field=数据库字段名,is_choice=是否是choice,text_func=显示文本的函数,value_func=URL中对应值的函数,condition=筛选条件,is_multi=是否支持多选), 示例: list_filter = [ # DistinctNameOption('name',condition={'id__gt':9},value_func=lambda x:x[0],text_func=lambda x:x[0],), Option('level',is_choice=True,text_func=lambda x:x[1]), Option('user',text_func=lambda x:x.title,is_multi=True), # Option('tel',text_func=lambda x:x.tel), Option('proj',is_multi=True) ] # 配置项多
1. 闭包
def f1(a1,a2): def inner(): ret = a1 + a3 return ret return inner n1 = f1('寒舍','滤清瑶') # 内存 a1=寒舍,a2=滤清瑶 n2 = f1('国舅','小鲜肉') # 内存 a1=国舅,a2=小鲜肉 n3 = f1('渣渣辉','万鹏程') # 内存 a1=渣渣辉,a2=万鹏程 n1() # 帮助开发者维护一个“私密”空间,用于为以后执行提供数据。
2. Form和ModelForm的区别?
Form -> formset
ModelForm -> modelformset
3. 反射
import importlib from django.utils.module_loading import import_string # 自定义 """ path = "x1.xx.Foo" module_path,class_name = path.rsplit('.',maxsplit=1) # 根据字符串的形式导入模块 m = importlib.import_module(module_path) # Foo类 cls = getattr(m,class_name) print(cls) """ # 基于django内置模块 """ v = import_string("x1.xx.Foo") print(v) """ 开放封闭原则; 每次操作都要去修改源码: def email(arg): pass def msg(arg): pass def wechat(arg): pass def dingding(arg): pass def execute(): user_list = ['韩射','吕轻咬'] email('xx') # msg('xx') wechat('xx') dingding('xx') 丁丁示例 注意:扩展
1. 相关知识点
#- 闭包+反射 #- bug
2. 客户管理
a. 公户客户/私户客户/所有客户 管理已完成 - 所有客户进行操作:销售主管 CustomerConfig - 公户客户进行操作:/推广/渠道/销售 PublicCustomerConfig - 私户客户进行操作:销售 PrivateCustomerConfig b. 公户和私户之间的操作: - 申请 - 移除 c. 跟进记录 - 所有跟进记录操作 - 私户跟进记录 d. 缴费 + 分班 - 缴费记录 - 财务审核 - 审核通过后分班(在student表中添加一条数据)
3. 教学管理
a. 直接操作学生表,伪造信息。 b. 上课记录 - 创建上课记录 - 初始化学生的学习记录 - 查看当天的学习记录 - 点名和作业信息的录入
第一部分:权限管理
第二部分:stark组件
第三部分:crm业务
1. crm系统主要用于做什么?
#客户关系管理。
2. 主要给谁用?
- 销售 - 客户分类,销售底薪+业绩 - 公户:申请(锁) - 行锁:innodb -> 行锁+表锁+事务 - 表锁:Mysiam -> 表锁 - 私户:150人+自己客户 - 全户 - 客户跟进 - 缴费申请 - 推广 - 在公户中录入有效数据 - 渠道 - 在公户中录入有效数据 - 教学,老师 - 上课 - 作业 - 成绩 - 教质 - 考勤 - 问卷 - 学生 - 交作业 - 查成绩 - 查看个人信息 - 问卷
3. 技术点
- Form的作用? - 对用户提交的一组表单数据进行校验。 - ModelForm的作用? - 对用户提交的一组表单数据进行校验。 - 快速实现增加、修改 - FormSet的作用? - 对用户提交的多组表单数据进行校验。 - ModelFormSet的作用? - 对用户提交的多组表单数据进行校验。 - 快速实现增加、修改
CRM结束:
1. 课程100% = 3年 2. 学习阶段 初级阶段:增删改查 + Linux 阶段升级:做项目增加熟练度 + 开发组件 + Linux 阶段升级:看源码(Flask+Django) + Linux 阶段升级:架构(Linux硬件+代码(设计模式+领域驱动模型)) + Linux 合伙人搞创业 3. 如何让简历漂亮 a. 项目+技术点 b. 热点 c. 自学能力 源码 4. 设计+讲话能力 建议: 1. 上午+下午搞定全天知识点;晚上stark开始+新项目; 2. 时间: - 内容回顾 - 周一~周四:上一天。 - 周五:全周 - 10:00~10:30 晚上:相互提问 3. 时间控制小时