stark组件
设计一个快速生成增删改查的框架
django在运行的时候有两个线程,一个是运行项目,一个是检测代码有没有改变。
如果不想让其检测代码是否改变可以使用该命令:
python manage.py runserver 127.0.0.1 8000 —noreload
知识储备
- django在项目启动前,先自定义的执行某个文件
在任意app的 apps文件下的类里定义ready方法就可以实现。
from django.utils.module_loading import autodiscover_modules
class App01Config(AppConfig):
name = 'app01'
def ready(self):
autodiscover_modules("start_init")
ready方法可以帮助我们在路由加载前根据app的注册的顺序去所有app的目录下找start_init.py的文件并执行,必须注册了app才会执行该app下的start_init文件
如果在start_init.py执行的时候向某个地方放入了一些值,之后路由加载的时候,可以去这个地方读取值。
2.单例模式
单:一个
例:实例化对象
单例模式:对于一个类永远实例化出一个对象
class Foo(object):
pass
obj1 = Foo()
obj2 = Foo()
这是实例化了两个对象
01.py
class Adminsite(object):
pass
site = Adminsite() 这是实例化一个对象
02.py
import o1
在导入文件的时候,该文件里的代码就会执行一次,所以就实例化出来site对象
print(01.site)
此时显示的是引入文件的时候,所实例化出来的对象
import 01
当再次引入的时候,代码就不会再执行一次了,而是去内存中找原来的值
print(01.site)
此时显示的对象和上一次导入的是同一个对象。
已经导入的文件再次被重新导入的时候,python不会重新解释一遍。而是选择从内存中直接将原来导入的值直接拿过来用。
多个py文件,同时导入一个文件的时候,都会是使用内存中的值。也就是只被解释一遍,其他文件导入的时候去内存中查找有就拿过来用。
3.django的路由分发 include本质
正常路由分发配置:
urlpatterns = [ path('txt/',include("app01.urls",namespace='01'))]
所以include的位置也可以直接放一个元组 (urls模块,app名称,名称空间)
urlpatterns = [ path('txt/',(urls模块,app名称,名称空间))]
include源码如下:
def include(arg, namespace=None):
# arg接受字符串形式的模块路径
app_name = None
# 如果arg是元组的形式进入分支,此时arg并不是元组,而是字符串"app01.urls"
if isinstance(arg, tuple):
# Callable returning a namespace hint.
try:
urlconf_module, app_name = arg
except ValueError:
if namespace:
raise ImproperlyConfigured(
'Cannot override the namespace for a dynamic module that '
'provides a namespace.'
)
raise ImproperlyConfigured(
'Passing a %d-tuple to include() is not supported. Pass a '
'2-tuple containing the list of patterns and app_name, and '
'provide the namespace argument to include() instead.' % len(arg)
)
#此时的情况要进入此分支:
else:
# 就是 urlconf_module = "app01.urls"
urlconf_module = arg
#判断 urlconf_module 是否是字符串的实例,此处是,将"app01.urls"引入进来并赋值给urlconf_module
if isinstance(urlconf_module, str):
urlconf_module = import_module(urlconf_module)
# 如果 urlconf_module 下有urlpatterns属性则获取并赋值给patterns,没有的话就将urlconf_module赋值给patterns
patterns = getattr(urlconf_module, 'urlpatterns', urlconf_module)
app_name = getattr(urlconf_module, 'app_name', app_name)
#如果有namespace 没 appname 报错,或者有appname没namespace 报错
if namespace and not app_name:
raise ImproperlyConfigured(
'Specifying a namespace in include() without providing an app_name '
'is not supported. Set the app_name attribute in the included '
'module, or pass a 2-tuple containing the list of patterns and '
'app_name instead.',
)
# namespace 有值则 namespace = namespace 没值则 namespace = app_name
namespace = namespace or app_name
if isinstance(patterns, (list, tuple)):
for url_pattern in patterns:
pattern = getattr(url_pattern, 'pattern', None)
if isinstance(pattern, LocalePrefixPattern):
raise ImproperlyConfigured(
'Using i18n_patterns in an included URLconf is not allowed.'
)
#最终return 一个元组 ("app01.urls",appname,namespace)
return (urlconf_module, app_name, namespace)
include本质是返回一个元组(urlconf_module,appname,名称空间)
urlconf_module = import_module(‘app01.urls’) #根据字符串导入模块
本质就是 include里传入的字符串给导入进来
urlconf_module 是 一个urls文件对象,通过此对象可以获取urls.patterns获取分发的路由 也就是urlpatterns列表
根据include本质,所以路由分发应该有3种方式如下:
方式一:
from django.conf.urls import url,include
urlpatterns = [
url(r'^web/', include("app01.urls")),
]
方式二:
include函数主要返回有三个元素的元组。
from django.conf.urls import url,include
from app01 import urls
urlpatterns = [
url(r'^web/', (urls, app_name, namespace)), # 第一个参数是urls文件对象,通过此对象可以获取urls.patterns获取分发的路由列表。
]
方式三:
urlpatterns = [
url(r'^web/', ([
url(r'^index/', views.index),
url(r'^home/', views.home),
], app_name, namespace)), # 既然第一个参数获取的是urlpatterns列表那直接可以将列表写在此处
]
stark组件 对表做增删改查
分析
- 创建django项目
- 创建基础业务表
- app01/models/用户表&部门表
- app02/models/主机表
- 对以上的3张表做增删改查
- 为每张表创建4个视图函数
- 单例模式
- 为每张表创建4个url
- 路由分发本质
- 格式是app名称/表名称/增删改查
- app01/userinfo/list
- app01/userinfo/add
- app01/userinfo/del(\d+)
- app01/userinfo/edit(\d+)
- 路由器前缀的定制
- 路由name的定制
- 为每张表创建4个视图函数
- 提取公共的视图函数
- xx
- 列表页面的显示
- 生成表的表头和显示的数据,可以自定义
- 不定义表头的时候默认显示的样式
- 给显示的字段预留一个方法,可以让不同的权限显示不同的字段
- 对于choices字段可以显示中文的实现
- 编辑和删除按钮的生成,也应该保留原来的搜索条件
- 添加按钮的生成
- 用户可以自定义添加按钮是否显示
- 预留一个钩子方法 用户可以重新该方法
- 分页器的实现:见笔记
- 添加页面的显示
- 前端页面
- 使用form生成效果,预留钩子,使用户可以使用自定义的form
- 在form校验完成后,数据保存前,可以自定义的对某些字段加默认值
- 添加完成返回list页面的时候应该使用反向生成url并拿到原来的搜索条件
- 前端页面
- 编辑页面的显示
- 使用model form 实现
- 预留钩子,使用户可以使用自定义的form 和 添加是一样的
- 在form校验完成后,数据保存前,可以自定义的对某些字段加默认值
- 添加完成返回list页面的时候应该使用反向生成url并拿到原来的搜索条件
- 删除页面的显示
- 删除的实现显示确认删除按钮和取消按钮
- 点击删除按钮进行删除,点击取消返回list页面
- 删除完成后返回list页面
- 其他常用功能
- 排序
- 模糊搜索 django的Q
- 要有一个搜索框 是 form表单,get提交,后台进行筛选 ?search=liu
- 后端获取到关键字后,根据定义的列进行查找(多列可以按照 或进行查询)
- 如果根据关键字搜索了,前端需要显示这个值
- 批量操作
- 在每行数据的前面生成一列check_box
- 生成批量删除的按钮
- 如按钮和check box 关联起来
- 生成的按钮应该是下拉框的样式,因为按钮如果多了就放不下了
- 下拉框的按钮应该是可以自己定制的
- 函数名.text = ‘XXX’ 可以给函数加键值,
- 函数名.name 可以得到函数名
- 使用getattr()
- 组合搜索
1.数据库的哪些字段要做搜索条件,给展示出来
1.如果是choices字段要显示choices里的元组的数据展示出来
3.如果是外键 应该显示的是外键所关联表里的字段
4.根据字段找到关联的数据给展示出来
5.用户可以自己定制 哪些数据库字段作为搜索条件,不写有默认值
6.根据配置的字段,去获取所关联的数据
7.根据字符串取 models 类中的字段对象。model._meta.get_filesd(“字段名”)
8.组合搜索的展示
知识储备
数据库对象._meta.get_field(‘数据库字段’).verbose_name #可以拿到该数据库对象中的指定字段对象,该对象可以.verbose_name等操作
数据库对象._meta.app_label #可以获取该对象所在app的app名称 数据库对象也可以换成models表的名称
数据库对象._meta.model_name #可以获取该对象所在modle类的models类名称 数据库对象也可以换成models表的名称
判断一个数据是不是函数:
from types import FunctionType
isinstance(‘sd’,FunctionType)
django在渲染数据的时候让数据显示是安全的
from django.utils.safestring import make_safe
@functools 是干嘛的
函数名传递给前端的时候是会自动加括号执行的接受的是返回值
判断model类的字段是什么类型的:
from django.db.models import ForeignKey
isinstance(字段,ForeignKey)
根据字符串类型的字段名 去models类中获取 字段对象:
modls_class._meta.get_field(“字符串类型的字段名”)
根据字符串类型的字段名 去models类中获取 所关联的表外键 多对多 一对多类型的时候用的:
字段对象.related_model #就可以拿到外键等 所关联的表
得到表后 ,后面跟objects 就可以进行查询等操作了
实例化的对象是不可以被迭代的就是不可以被循环的,如果该类中定义了iter方法,且该方法返回一个迭代器,就称这个类实例化的对象为可迭代对象,该对象是可以被循环的