day20 FORM补充(随时更新),F/Q操作,model之多对多,django中间件,缓存,信号
python-day20
1、FROM生成select标签的数据应该来源于数据库。
2、model 操作 F/Q (组合查询)
3、model 多对多操作。
4、中间件 :在请求到达url前先会经过中间件,(比如:中间件进行缓存操作,或者黑名单)
5、缓存,django提供缓存功能
6、信号(钩子,保存数据前先执行那些类或者函数)
7、分页(待上传... ...)
cookie:保存在客户端键值对
session:保存在服务器的一个key
一、form补充
class News_Type(models.Model):
caption = models.CharField(max_length=32)
#1、国内新闻 2、国际新闻 3、宇宙新闻 class New_Text(models.Model):
title = models.CharField(max_length=32)
content = models.CharField(max_length=32)
newstype = models.ForeignKey(News_Type)
之前我们使用form生成一个select标签是用的自己写在内存中的数据。
choice = {
(1,'国内新闻')
(2,'国际新闻')
(3,'宇宙新闻')
} 以后我们就可以从数据库中获取
choice = News_Type.objects.all().value_list ('id','name')
实例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>AddData</title>
</head>
<body>
<form action="/add_data/" method="POST">
<div>
{{ obj.name }} <!-- 这些值都是从后端传递过来的,自动生成相应标签,对应着model中数据库表中的字段 -->
</div>
<div>
{{ obj.age }}
</div>
<div>
{{ obj.user_type }}
</div>
<input type="submit" value="提交">
</form>
<form action="/add_data/" method="POST">
<div>
{{ type.caption }}
</div>
<input type="submit" value="提交">
</form>
</body>
</html>
前端
class add_Type(forms.Form):
caption = forms.CharField(required=True, widget=forms.widgets.Input(attrs={"name":"caption","placeholder":"caption"}))
#widget=forms.widgets.Input(attrs={"name":"caption","placeholder":"caption"} 给标签添加属性 class add_valide(forms.Form):
name = forms.CharField(max_length=12, widget=forms.widgets.Input(attrs={"name":"name","placeholder":"name"}))
age = forms.IntegerField(widget=forms.widgets.Input(attrs={"name":"age","placeholder":"age"}))
choise = model.User_Type.objects.all().values_list("id","caption")
# choise = { 这是内存模式的
# (1,'CTO')
# (2,'CEO')
# (3,'CFO')
# }
user_type = forms.IntegerField(widget=forms.widgets.Select(choices=choise,attrs={"name":"user_type"})) def add_data(request):
if request.method == 'POST':
objPost_type = add_Type(request.POST) #用户提交的类型数据
objPost_userinfo = add_valide(request.POST) #用户提交的用户信息数据
post_user = objPost_userinfo.is_valid() #form验证判断
post_tye = objPost_type.is_valid() #form验证判断
if post_user or post_tye: #如果这两个判断中有一个是真
if post_tye: #如果类型为真
cap = objPost_type.clean()['caption'] #objPost_type.clean()是获取到用户提交的数值{"caption":"CTO"}
model.User_Type.objects.create(caption=cap) #创建用户类型
return render(request, "add_data.html", {"obj": objPost_userinfo, "type": post_tye})
else: #用户数据为真
user_name = objPost_userinfo.clean()['name'] #获取用户输入的name
age = objPost_userinfo.clean()['age'] #获取用户输入的age
type = objPost_userinfo.clean()['user_type'] #获取用户输入的用户类型
model.UserInfo.objects.create(name=user_name,age=age,user_type_id=type) #插入数据库user_type_id直接使用到了user_type_id这个虚拟字段
return render(request, "add_data.html", {"obj": objPost_userinfo,"type":objPost_type})
else: #如果用户是get请求
objGet = add_valide() #获取form表单
typeGet = add_Type() #获取form表单
print(model.User_Type.objects.all().values("caption"))
print(model.UserInfo.objects.all().values("name","age","user_type__caption"))
return render(request, "add_data.html", {"obj": objGet,"type":typeGet}) #直接把表单传递到前段,前段就生成了相应的标签
views.py
这样就实现了后端从数据库中获取,并且form提供创建标签的功能
但是这么写use_type 的内容不会因为新插入数值而改变,需要重启程序
class add_valide(forms.Form):
name = forms.CharField(max_length=12, widget=forms.widgets.Input(attrs={"name":"name","placeholder":"name"}))
age = forms.IntegerField(widget=forms.widgets.Input(attrs={"name":"age","placeholder":"age"}))
choise = model.User_Type.objects.all().values_list("id","caption")
user_type = forms.IntegerField(widget=forms.widgets.Select(choices=choise,attrs={"name":"user_type"}))
注意:因为 choise = model.User_Type.objects.all().values_list("id","caption") 这一条是class add_valide的静态字段,在类加载之后就不会再变化了,及时数据库中有新值插入,也不会去重新加载。
所以针对add_valide进行改良
class add_valide(forms.Form):
name = forms.CharField(max_length=12, widget=forms.widgets.Input(attrs={"name":"name","placeholder":"name"}))
age = forms.IntegerField(widget=forms.widgets.Input(attrs={"name":"age","placeholder":"age"}))
choise = model.User_Type.objects.all().values_list("id","caption")
user_type = forms.IntegerField(widget=forms.widgets.Select(choices=choise,attrs={"name":"user_type"}))
def __init__(self,*arg, **kwargs): #init构造函数的特点就是每次请求来都会
super(add_valide, self).__init__(*arg, **kwargs)
self.fields['user_type'].widget.choices = model.User_Type.objects.all().values_list("id","caption")
#就是让 user_type = forms.IntegerField(widget=forms.widgets.Select(choices 重新赋值,赋值的内容是去数据库中获取
请求流程
else: #如果用户是get请求
objGet = add_valide() #获取form表单
typeGet = add_Type() #获取form表单
print(model.User_Type.objects.all().values("caption"))
print(model.UserInfo.objects.all().values("name","age","user_type__caption"))
return render(request, "add_data.html", {"obj": objGet,"type":typeGet}) #直接把表单传递到前段,前段就生成了相应的标签
每次请求来都会创建 add_valide()对象,创建对象的时候就会执行构造函数 init中的
self.fields['user_type'].widget.choices = model.User_Type.objects.all().values_list("id","caption")
二、Django数据操作之 F/Q
1、F 作用:找到某个值让这个值在自身基础上做操作(增加,减少或者字符串拼接)
需求,找到某一些人把他们的工资加500
在models中我们要实现这个需求用下面的方法是不成的
想法没有问题,但是实现不了,实现不了,实现不了
temp = salary + 500
models.UserINfo.objects.fileter().update(salary=temp)
在sql语句中:
update userinfo set salary=salary + 500
所以我们就要用F来实现
# F 使用查询条件的值 from django.db.models import F
models.Tb1.objects.update(num=F('num')+1) from django.db import connection
cursor = connection.cursor()
cursor.execute("""SELECT * from tb where name = %s""", ['Lennon'])
row = cursor.fetchone()
F的具体实现:
models.UserINfo.objects.fileter().update(salary=F('salary')+ 500)
2、Q作用:构造搜索条件
目前我们学到的搜索条件是:
models.IserInfo.objects.filter(id=123,name="alex")
或者:
d = {'id':123,"name":"alex"}
models.UserInfo.objects.filter(**d) 默认这样的方式就是and搜索
如果想使用or操作或者其他复杂的操作就需要使用Q对象。
1 CTO
2 CTO
3 CEO
4 CFO
5 CFO
6 CFO
想找到id是1或者2或者3的数据
con = Q()
q1 = Q()
q1.connector = 'OR'
q1.children.append(('id',1))
q1.children.append(('id',2))
q1.children.append(('id',3))
text = model.UserInfo.objects.filter(q1)
for i in text:
print(i.id,i.name)
想找到id是1或者2或者3的并且name=CEO的
con = Q()
#先找到id的范围
q1 = Q()
q1.connector = 'OR'
q1.children.append(('id',1))
q1.children.append(('id',2))
q1.children.append(('id',3)) #在指定name的要找的名字
q2 = Q()
q2.connector = "OR"
q2.children.append(('name',"CEO")) #把q1和q2再放到一起做一个AND
con.add(q1,'AND')
con.add(q2,'AND')
text = model.UserInfo.objects.filter(q1)
三、models 多对多
1、创建
- Django自动创建第三张表:
class UserInfo(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField(max_length=3)
user_type = models.ForeignKey(User_Type) class Dianzan(models.Model):
num = models.IntegerField(max_length=12)
U = models.ManyToManyField(UserInfo) #创建第三张表
- 自己创建第三项表
class UserInfo(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField(max_length=3)
user_type = models.ForeignKey(User_Type) class Dianzan(models.Model):
num = models.IntegerField(max_length=12) class D2U(models.Model):
D_id = models.ForeignKey('Dianzan')
U_id = models.ForeignKey('UserInfo')
- Django自动创建第三张表的处理:
class Boy(models.Model):
name = models.CharField(max_length=12)
g = models.ManyToManyField("Girl") class Girl(models.Model):
name = models.CharField(max_length=12)
表结构
b1 = model.Boy.objects.get(name="郭德纲") #获取男孩名字
g1 = model.Girl.objects.get(name="王钢蛋") #获取女孩名字
gs = model.Girl.objects.all()
因为上面表结构中我们在boy表中定义了第三张表的字段,g,所以我们就可以通过这个字段来操作第三种功能表了
b1.g.add(g1) #b1中有一个g的字段 这个g字段就代指的第三张表
# 添加数据
正向操作
#b1.g.add(g1)
#b1.g.add(*gs) #添加女孩对象的列表增加多条数据
因为增加到第三张表中的只是两张表的主键,也就是两张表的id,所以我们也可以只使用id作为add的参数,这样做就省去了上面再查询的过程
b1.g.add(1)
b1.g.add(*[1,2,3]) 反向操作:
在女孩字段中隐含着一个boy_set字段
g1.boy_set.valuse() #反向查询
# 删除数据
#b1.g.clear()与b1男孩有关系的女孩全部删除
#b1.g.remove(g1)
#b1.g.remove(*g1_obj)
#b1.g.remove(1)
#b1.g.remove(*[1,2,3]) # 添加数据(反向操作)
#g1.boy_set.add(b1)
#g1.boy_set.add(*bs)
#g1.boy_set.add(1)
#g1.boy_set.add(*[1,2,3]) # 删除数据(反向操作)
#g1.boy_set.remove(b1)
#g1.boy_set.remove(*bs)
#g1.boy_set.remove(1)
#g1.boy_set.remove(*[1,2,3])
#g1.boy_set.clean() #删除所有与g1有关系的男孩 # 获取数据
#b1.g.all()
#b1.g.all().filter(id=1) # 获取数据(反向操作隐含着_set字段)
#g1.boy_set.all()
#g1.boy_set.all().filter(name='郭德纲')
#all(),conten #跨表查询,从girl表中的一个对象,通过关联表查询到boy表中的数据
#models.Girl.objects.all().valuse('id','name','boy__name')
models.Girl.objects.filter(name='王钢蛋').values('id','name','boy__name')
#这样就查询到了王钢蛋的id name 还有和王钢蛋关联的男孩的名字
更新:django中没有提供更新,所以需要使用原生sql来实现
from django.db import connection
# cursor = connection.cursor()
# cursor.execute("""SELECT * from tb where name = %s""", ['Lennon'])
# row = cursor.fetchone()
四、Django中间件:
1.中间件存在的位置
a、MIDDLEWARE_CLASSES 流程:
MIDDLEWARE_CLASSES = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
#'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
django的中间件本身就是一个类,所以我们也可以自己定义一个类
类路径:class1. models.py
class M1:
def process_request(self,request):
print('我是中间件') 在setting中添加这个类
MIDDLEWARE_CLASSES = [
'class1.models.M1',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
#'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
此时我们重启系统然后访问页面
显示:
我是中间件 <-------- 这个是关键!!
[01/Oct/2016 16:06:33] "GET /boy_2_girl/ HTTP/1.1" 200 2
[{'boy__name': '郭德纲', 'name': '林志玲', 'id': 5}]
与mange.py在同一目录下的文件夹 wupeiqi/middleware下的auth.py文件中的Authentication类
2.中间件定义的方法名:
1、process_request(self,request) #请求时执行的方法
2、process_response(self,request,response) #返回时执行的方法
return response #返回时必须要return response 3、process_template_response(self,request,response) #在views.py 的url函数中,返回中如果有render,才会执行这个方法 4、process_exception(self, request, exception) #url函数中如果出现异常则会执行这个方法,并且执行的顺序是执行url函数前的方法,再执行url函数,
#如果url函数中有错误,则会执行在返回的函数中先执行后定义的中间件方法中的exception方法 5、process_view(self, request, callback, callback_args, callback_kwargs) #执行完所有的request后再执行这个方法
def middle(request):
print("views")
obj = HttpResponse("OK")
return obj # return 中有单独定义的redern方法才会触发process_template_response
以上方法的返回值可以是None和HttpResonse对象,如果是None,则继续按照django定义的规则向下执行,如果是HttpResonse对象,则直接将该对象返回给用户。
中间件执行的顺序
MIDDLEWARE_CLASSES = [
'class1.models.M1',
'class1.models.M2',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
#'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
settings
class M1:
def process_request(self,request):
print("M1.process_request") def process_response(self,request,response): #参数是django已经定义好的
print("M1.process_response")
return response class M2:
def process_request(self,request):
print("M2.process_request") def process_response(self, resqust, response):
print("M2.process_response")
return response
中间件
def middle(request):
print("views")
return HttpResponse("ok")
url 函数
访问这个url函数,因为定义了中间件,所以所有的访问会经过中间件,中间件中的request是负责接受请求时执行的,response是返回时执行的
访问后返回的结果:
M1.process_request
M2.process_request
views
M2.process_response
M1.process_response
顺序是先经过所有的resquest,然后执行url函数,最后返回时在执行response
3、更多方法使用:
class M1:
def process_request(self,request):
print("M1.process_request") def process_response(self,request,response):
print("M1.process_response")
return response def process_view(self, request, callback, callback_args, callback_kwargs):
print("M1.process_view") def process_exception(self, request, exception):
print("M1.exception ,url函数中出错了") class M2:
def process_request(self,request):
print("M2.process_request") def process_response(self, resqust, response):
print("M2.process_response")
return response def process_view(self, request, callback, callback_args, callback_kwargs):
print("M2.process_view") def process_exception(self, request, exception):
print("M2.exception ,url函数中出错了")
更多中间件的使用
M1.process_request #先执行request
M2.process_request
M1.process_view #再返回去执行vies
M2.process_view #然后就执行url函数,如果出错了就执行exception,没有出错则执行response
M2.exception ,url函数中出错了 #因为出错了,所以出去的时候先执行M2
M1.exception ,url函数中出错了
M2.process_response #执行完exception后再返回去执行response
M1.process_response
4、不同版本中间件使用的区别:
在1.10之前就是按照上面的方法去写,但是之后需要在定义中间件的时候做一些改变
from django.utils import deprecation #倒入这个类
class M1(deprecation.MiddlewareMixin): #继承这个方法
def process_request(self,request):
print("M1.process_request") def process_response(self,request,response):
print("M1.process_response")
return response class M2(deprecation.MiddlewareMixin):
def process_request(self,request):
print("M2.process_request") def process_response(self, resqust, response):
print("M2.process_response")
return response
新版本django 中间件写法
5、新版本如果其中一个process_requset中return了,则后面的request都不执行了,然后执行process_request对应类中的process_response方法
b、原版本的流程:
这个与新版本不同的地方是如果在process_request中 return了,后面的process_request都不执行了,然后依次执行所有的process_response.
五、django缓存
1、配置
由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者memcache中,5分钟内再有人来访问时,则不再去执行view中的操作,而是直接从内存或者Redis中之前缓存的内容拿到,并返回。
Django中提供了6种缓存方式:
- 开发调试
- 内存
- 文件
- 数据库
- Memcache缓存(python-memcached模块)
- Memcache缓存(pylibmc模块)
a、开发模式:
# 此为开始调试用,实际内部不做任何操作
# 配置:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.dummy.DummyCache', # 引擎
'TIMEOUT': 300, # 缓存超时时间(默认300,None表示永不过期,0表示立即过期)
'OPTIONS':{
'MAX_ENTRIES': 300, # 最大缓存个数(默认300)
'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)
},
'KEY_PREFIX': '', # 缓存key的前缀(默认空)
'VERSION': 1, # 缓存key的版本(默认1)
'KEY_FUNCTION' 函数名 # 生成key的函数(默认函数会生成为:【前缀:版本:key】)
}
} # 自定义key
def default_key_func(key, key_prefix, version):
"""
Default function to generate keys. Constructs the key used by all other methods. By default it prepends
the `key_prefix'. KEY_FUNCTION can be used to specify an alternate
function with custom key making behavior.
"""
return '%s:%s:%s' % (key_prefix, version, key) def get_key_func(key_func):
"""
Function to decide which key function to use. Defaults to ``default_key_func``.
"""
if key_func is not None:
if callable(key_func):
return key_func
else:
return import_string(key_func)
return default_key_func
b、内存
# 此缓存将内容保存至内存的变量中
# 配置:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'unique-snowflake',
}
} # 注:其他配置同开发调试版本
c、文件
# 此缓存将内容保存至文件
# 配置: CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': '/var/tmp/django_cache',
}
}
# 注:其他配置同开发调试版本
d、数据库
# 此缓存将内容保存至数据库 # 配置:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
'LOCATION': 'my_cache_table', # 数据库表
}
} # 注:执行创建表命令 python manage.py createcachetable
e、Memcache缓存(python-memcached模块)
# 此缓存使用python-memcached模块连接memcache CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': '127.0.0.1:11211',
}
} CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': 'unix:/tmp/memcached.sock',
}
} CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': [
'172.19.26.240:11211',
'172.19.26.242:11211',
]
}
}
f、Memcache缓存(pylibmc模块)
# 此缓存使用pylibmc模块连接memcache CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
'LOCATION': '127.0.0.1:11211',
}
} CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
'LOCATION': '/tmp/memcached.sock',
}
} CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
'LOCATION': [
'172.19.26.240:11211',
'172.19.26.242:11211',
]
}
}
2、应用
a. 全站使用
使用中间件,经过一系列的认证等操作,如果内容在缓存中存在,则使用FetchFromCacheMiddleware获取内容并返回给用户,当返回给用户之前,判断缓存中是否已经存在,
如果不存在则UpdateCacheMiddleware会将缓存保存至缓存,从而实现全站缓存 MIDDLEWARE = [
'django.middleware.cache.UpdateCacheMiddleware',
# 其他中间件...
'django.middleware.cache.FetchFromCacheMiddleware',
] CACHE_MIDDLEWARE_ALIAS = ""
CACHE_MIDDLEWARE_SECONDS = ""
CACHE_MIDDLEWARE_KEY_PREFIX = ""
b、单独视图缓存
方式一:
from django.views.decorators.cache import cache_page @cache_page(60 * 15) #括号里面是超时时间
def my_view(request):
...
方式二:
from django.views.decorators.cache import cache_page urlpatterns = [
url(r'^foo/([0-9]{1,2})/$', cache_page(60 * 15)(my_view)), #这个单独试图支持分页
]
方式一和方式二实现效果是一样的。
c、局部视图使用
第一步. 引入TemplateTag {% load cache %} 第二步. 使用缓存 {% cache 5000 缓存key %} #5000的秒, 缓存key就是 放在缓存中的名字
缓存内容
{% endcache %}
更多猛戳这里
六、信号
Django中提供了“信号调度”,用于在框架执行操作时解耦。通俗来讲,就是一些动作发生的时候,信号允许特定的发送者去提醒一些接受者。
1、Django内置信号
Model signals
pre_init # django的modal执行其构造方法前,自动触发
post_init # django的modal执行其构造方法后,自动触发
pre_save # django的modal对象保存前,自动触发
post_save # django的modal对象保存后,自动触发
pre_delete # django的modal对象删除前,自动触发
post_delete # django的modal对象删除后,自动触发
m2m_changed # django的modal中使用m2m字段操作第三张表(add,remove,clear)前后,自动触发
class_prepared # 程序启动时,检测已注册的app中modal类,对于每一个类,自动触发
Management signals
pre_migrate # 执行migrate命令前,自动触发
post_migrate # 执行migrate命令后,自动触发
Request/response signals
request_started # 请求到来前,自动触发
request_finished # 请求结束后,自动触发
got_request_exception # 请求异常后,自动触发
Test signals
setting_changed # 使用test测试修改配置文件时,自动触发
template_rendered # 使用test测试渲染模板时,自动触发
Database Wrappers
connection_created # 创建数据库连接时,自动触发
对于Django内置的信号,仅需注册指定信号,当程序执行相应操作时,自动触发注册函数,放置位置最好放在project同名目录的__init__.py文件中
from django.core.signals import request_finished
from django.core.signals import request_started
from django.core.signals import got_request_exception from django.db.models.signals import class_prepared
from django.db.models.signals import pre_init, post_init
from django.db.models.signals import pre_save, post_save
from django.db.models.signals import pre_delete, post_delete
from django.db.models.signals import m2m_changed
from django.db.models.signals import pre_migrate, post_migrate from django.test.signals import setting_changed
from django.test.signals import template_rendered from django.db.backends.signals import connection_created def callback(sender, **kwargs):
print("xxoo_callback")
print(sender,kwargs) xxoo.connect(callback)
# xxoo指上述导入的内容 如: pre_migrate
from django.core.signals import request_finished
from django.dispatch import receiver @receiver(request_finished)
def my_callback(sender, **kwargs):
print("Request finished!")
2、自定义信号
a. 定义信号
import django.dispatch
pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"])
b. 注册信号
def callback(sender, **kwargs):
print("callback")
print(sender,kwargs) pizza_done.connect(callback)
c. 触发信号
from 路径 import pizza_done pizza_done.send(sender='seven',toppings=123, size=456)
由于内置信号的触发者已经集成到Django中,所以其会自动调用,而对于自定义信号则需要开发者在任意位置触发。
更多内容:猛戳这里
小知识点:
以get方式传值:
url:127.0.0.1:8000/index/?q=123
后台:
def add_url(request):
q = request.GET.get("q",None)
print(q)
return HttpResponse(q)
def middle(request):
print("views")
obj = HttpResponse("OK")
return obj # return 中有单独定义的redern方法才会触发process_template_response
day20 FORM补充(随时更新),F/Q操作,model之多对多,django中间件,缓存,信号的更多相关文章
- Django数据操作F和Q、model多对多操作、Django中间件、信号、读数据库里的数据实现分页
models.tb.objects.all().using('default'),根据using来指定在哪个库里查询,default是settings中配置的数据库的连接名称. 外话:django中引 ...
- python自动化开发-[第二十一天]-form验证,中间件,缓存,信号,admin后台
今日概要: 1.form表单进阶 2.中间件 3.缓存 4.信号 5.admin后台 上节课回顾 FBV,CBV 序列化 - Django内置 - json.dumps(xxx,cls=) Form验 ...
- Django之model F/Q以及多对多操作
model之F/Q操作 F操作,使用查询条件的值 打个比方吧,有一张表,保存着公司员工的工资,公司普涨工资,如何在model中操作,这就用到了F,首先需要导入此模块: from django.db.m ...
- Django之ORM操作(聚合 分组、F Q)
Django之ORM操作(聚合 分组.F Q) 聚合 aggregate()是QuerySet的一个终止子句,也就是说,他返回一个包含一些键值对的字典,在它的后面不可以再进行点(.)操作. 键的名 ...
- Django---Django的ORM的一对多操作(外键操作),ORM的多对多操作(关系管理对象),ORM的分组聚合,ORM的F字段查询和Q字段条件查询,Django的事务操作,额外(Django的终端打印SQL语句,脚本调试)
Django---Django的ORM的一对多操作(外键操作),ORM的多对多操作(关系管理对象),ORM的分组聚合,ORM的F字段查询和Q字段条件查询,Django的事务操作,额外(Django的终 ...
- Django 数据库操作进阶F和Q操作
Model中的F F 的操作通常的应用场景在于:公司对于每个员工,都涨500的工资.这个时候F就可以作为查询条件 1 2 3 from django.db.models import F models ...
- Python菜鸟之路:Django 数据库操作进阶F和Q操作
Model中的F F 的操作通常的应用场景在于:公司对于每个员工,都涨500的工资.这个时候F就可以作为查询条件 from django.db.models import F models.UserI ...
- django操作数据库之查询F,Q操作 和 seach搜索功能
# F 使用查询条件的值 # # from django.db.models import F # models.Tb1.objects.update(num=F('num')+1) # Q 构建搜索 ...
- Django day08 多表操作 (五) 聚合,分组查询 和 F,Q查询
一:聚合,分组查询 二:F, Q查询
随机推荐
- tomcat启动startup.bat一闪而过 转
遇到很多次运行startup.bat后,一个窗口一闪而过的问题,但是从来没去纠正怎样修改配置才是正确的,现在从网上查阅的资料整理如下:tomcat在启动时,会读取环境变量的信息,需要一个CATALIN ...
- Android的init过程(二):初始化语言(init.rc)解析【转】
转自:http://www.cnblogs.com/nokiaguy/p/3164799.html Android的init过程(一) 本文使用的软件版本 Android:4.2.2 Linux内核: ...
- SQL中的连接可以分为内连接,外连接,以及交叉连接 。
SQL中的连接可以分为内连接,外连接,以及交叉连接 . 1. 交叉连接CROSS JOIN 如果不带WHERE条件子句,它将会返回被连接的两个表的笛卡尔积,返回结果的行数等于两个表行数的乘积: 举例, ...
- Qt实现停靠功能
- PHP多表取数据的代码优化
<?php header("Content-type: text/html; charset=utf-8"); //假设这里的$goods_arr 和 $shop_arr ...
- HDU 4315:Climbing the Hill(阶梯博弈)
http://acm.hdu.edu.cn/showproblem.php?pid=4315 题意:有n个人要往坐标为0的地方移动,他们分别有一个位置a[i],其中最靠近0的第k个人是king,移动的 ...
- HDU 5724:Chess(博弈 + 状压)
http://acm.hdu.edu.cn/showproblem.php?pid=5724 Chess Problem Description Alice and Bob are playing ...
- mysql高可用之PXC(Percona XtraDB Cluster)
简介 Percona XtraDB Cluster是MySQL高可用性和可扩展性的解决方案,Percona XtraDB Cluster提供的特性如下: 1).同步复制,事务要么在所有节点提交或不提交 ...
- coco2dx服务器简单例子
实现的单个socket例子,了解socket原理. 先创建一个win32的项目(命令行的),作为服务端 // SocketServer.cpp : 定义控制台应用程序的入口点.// #include ...
- JVM的classloader(转)
Java中一共有四个类加载器,之所以叫类加载器,是程序要用到某个类的时候,要用类加载器载入内存. 这四个类加载器分别为:Bootstrap ClassLoader.Extension Class ...