super_curd组件技术点总结

1.基于包的导入的方式实现单例模式

# test1.py
class AdminSite(object):
	def __init__(self):
		self.registry = {}
		self.app_name = 'super_curd'
		self.namespace = 'super_curd'
	def register(self, model_class, stark_config):
		if not stark_config:
			stark_config = StarkConfig
		self.registry[self.model_class] = stark_config[self.model_class]
		
site = AdminSite()
# test2.py
from test1 import site
site.register(model.UserInfo)

2.django中路由分发的原理

# 一般的
urlpatterns = [
	url(r'^test/', views.test)
]
# 路由分发
urlpatterns = [
	url(r'^test/', include('app_name.urls'))
]
# include原理:元组里面包含三个参数,[url],app_name,namespace
urlpatterns = [
	url(r'^test/', (['这里面放url'], app_name, namespace))
]

3.钩子函数

class StarkConfig(object):
	
	list_display = []
	
	def __init__(self, model_class):
		self.model_class = model_class
	# 第一种钩子 - 在获取静态字段时,通过一个函数来间接获取,这样就能在获取字段之前进行自定义操作
	def get_list_display(self):
		return self.list_display
	
	# 第二种钩子 - 组件中包含了很多已经设置好的url,在获取url时,自定义额外的url,
	def extral_url(self):
		pass
	# 第三种钩子函数 - 利用装饰器,在生成url时,将request参数传递到当前类当中
	import functools
	def wrapper(func):
		@functools.wraps(func)
		def inner(request, *args, **kwargs):
			self.request = request
			return func(request, *args, **kwargs)

4.inclusion_tag对change_view功能进行拆分

  • 实现方式:在app下新建一个名为templatetags文件夹,在里面新建一个py文件,里面写如下内容
# 具体代码
# stark.py
from template import Library

register = Library()

@register.inclusion_tag('stark/test.html')
def test(request):
	pass

5.基于类的封装对chang_view功能进行拆分

  • 以前的我们
# 在进行数据的存取时,通常使用[],{}等等,然后通过遍历的方法
data_list = [11,22,33]
for data in data_list:
	print(data)
  • 现在的我们
# 将数据存到类当中的字段中,这样在取数据时,我们只需要实例化一个对象,然后通过对象.的方式取数据
class Test(object):
	def __init__(self, data_list):
		self.data_list = data_list

t1 = Test()
t1.data_list

6.基于反射,通过传递进来的字符串动态调用函数

name_list = ['multi_delete', 'multi_init']
class Test(object):
	name_list = ['multi_delete', 'multi_init']
	def multi_delete(self):
		pass
	def multi_init(self):
		pass
	def get_name_list(self):
		return self.name_list
	def run(self):
		name_list = self.get_name_list()
		for name in name_list:
			getattr(self, name)

7.通过_meta获取模型类的类名小写,以及对应的app名称

model.UserInfo._meta.model_name
model.UserInfo._meta.app_label

8.urlencode - 会将字典转换为字符串的方法

  • 在python中有两种方式可以使用urlencode方法
# 第一种
from urllib.path import urlencode
# 第二种
from django.http import QueryDict
# 在django的请求中的QueryDict中
request.GET.urlencode  # QueryDict中的数据会以`x1=1&x2=3&x3=5`的形式转换
request.POST.urlencode

9.make_safe

  • 在后端我们想往前端传递含有前端格式的数据时,我们想让页面去渲染出我们的想要的效果
  • 前端为什么不会直接渲染我们传递的字符串类型的前端代码,因为前端这样做事为了预防网站被恶意的进行xss攻击
  • xss攻击 - 例子:我们在博客评论时,直接评论一段js代码,如果网站没有xss防护,那么网站就会执行这段js代码,我们就可以利用这个对网站进行恶意破坏,让网站无线弹窗之类的

10.autodiscover_module - 这个方法存在于django的admin源码当中

# 只要我们在某一个app下的apps.py中AppnameConfig类中实现这样一个方法,那么django每次启动之前,都会去app中找对应的py文件,然后将它运行
class StarkConfig(AppConfig):
    name = 'stark'

    def ready(self):
        from django.utils.module_loading import autodiscover_modules
        # 当程序启动时,去每个app目录下找stark.py并加载。
        autodiscover_modules('stark')

11.基于类的继承,订制自己的config类,

  • 当功能不能满足我们的需求时,我们可以继承原来的类,然后重写相关的方法对功能进行扩展

12.保留原来的筛选条件

  • 当我们在页面上分页功能时,如果跳转到下一页,那么我们应该将搜索条件也要加入到下一页的数据中,这样对用户来说更加友好
  • 当我们从筛选页面跳转到添加数据页面时,我们把条件一起给到我们跳转的页面。这样添加的页面在返回时,也要带上我们的筛选条件,这样我们就可以回到我们原来的带上筛选条件页面上。
  • 基于QueryDict、urlencode来实现

13.深浅拷贝

  • 在对QueryDict进行修改时,我们希望我们只修改自己的数据,保存到自己创建的一份QueryDict中,这时候就要用到深拷贝,这样做是为了不影响其他人使用QueryDict

14.QueryDict

  • 在HttpRequest对象中,GET和POST属性都是一个django.http.QueryDict的实例。也就是说你可以按本文下面提供的方法操作request.POST和request.GET。
# 默认的情况下我们不能修改QueryDict中的内容,但是只要配置一下就可以修改了
request.GET._mutable = True
  • request.POST或request.GET的QueryDict都是不可变,只读的。如果要修改它,需要使用QueryDict.copy()方法,获取它的一个拷贝,然后在这个拷贝上进行修改操作。

15.yield

  • 在大量的数据需要我们去传递时,我们可以一点一点的将数据传递出去,这样我们的内存当中存在的数据就不会过多,从而提升服务器的性能

16.Q对象

  • 在django中,默认的filter并不能处理or这种情况,一旦我们需要构造复杂一点的查询语句时,就需要用到Q对象。
  • 在Q对象中我们可以用or来包含and
con = Q()
con.connector = "OR"
if q:
	for field in search_list:
		con.children.append(('%s__contains' % field, q))

17.可迭代对象

  • 什么是可迭代对象
- 实现了__inter__方法的对象就叫做可迭代对象。
- __inter__方法的作用就是返回一个迭代器对象。直观理解就是能用for循环进行迭代的对象就是可迭代对象。比如:字符串,列表,元祖,字典,集合等等,都是可迭代对象。

18.orm查询 - left join(左表查询) - inner join(内连接)

model.UserInfo.object.filter(id='lucas') -- inner join
model.UserInfo.object.filter(permission__is_null=Ture).values('id', 'title')  -- left join
posted @ 2021-03-10 15:23  kingdoms  阅读(70)  评论(0)    收藏  举报