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) #Q 构建搜索条件 from django.db.models import Q con = Q() q1 = Q() q1.connector = ‘OR‘ q1.children.append((‘id‘, 1)) q1.children.append((‘id‘, 10)) q1.children.append((‘id‘, 9)) q2 = Q() q2.connector = ‘OR‘ q2.children.append((‘c1‘, 1)) q2.children.append((‘c1‘, 10)) q2.children.append((‘c1‘, 9)) con.add(q1, ‘AND‘) con.add(q2, ‘AND‘) models.Tb1.objects.filter(con) from django.db import connection cursor = connection.cursor() cursor.execute("""SELECT * from tb where name = %s""", [‘Lennon‘]) row = cursor.fetchone()
F的具体实现:
想法没有问题,但是实现不了,实现不了,实现不了 temp = salary + 500 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搜索
小知识点:
以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)