django原生FBV
1,django原生FBV
urls.py
# 1,django原生FBV
path('origin/',FBV.view),
path('origin2/<str:id>/',FBV.view_detail)
view.py
import json
from django.db.models import Q
from django.views.decorators.csrf import csrf_exempt,csrf_protect
from mysystem.models import Student
from django.http import JsonResponse
# 关闭验证
# @csrf_exempt
def view(request):
if request.method == 'GET':
"""获取多个学生信息"""
# 1. 读取数据库
students_list = list(Student.objects.values())
# 2. 返回数据
return JsonResponse(data=students_list, status=200, safe=False)
elif request.method == 'POST':
"""添加一个学生信息"""
# 1. 接收客户单提交的数据,验证客户端的数据
data = json.loads(request.body)
name = data.get("name")
sex = data.get("sex")
age = data.get("age")
classmate = data.get("classmate")
description = data.get("description")
# 2. 操作数据库,保存数据
instance = Student.objects.create(
name=name,
sex=sex,
age=age,
classmate=classmate,
description=description,
)
# 3. 返回结果
return JsonResponse(data={
"id": instance.pk,
"name": instance.name,
"sex": instance.sex,
"age": instance.age,
"classmate": instance.classmate,
"description": instance.description,
}, status=201)
# 开启验证
# @csrf_protect
def view_detail(request, id):
if request.method == 'DELETE':
"""删除一个学生信息"""
try:
Student.objects.filter(pk=id).delete()
except:
pass
return JsonResponse(data={}, status=204)
elif request.method == 'PUT':
"""更新一个学生信息"""
# 1. 接收客户单提交的数据,验证客户端的数据
data = json.loads(request.body)
name = data.get("name") # alt+j 选中多个一样的
sex = data.get("sex")
age = data.get("age")
classmate = data.get("classmate")
description = data.get("description")
# 2. 操作数据库,保存数据
try:
instance = Student.objects.get(pk=id)
instance.name = name
instance.sex = sex
instance.age = age
instance.classmate = classmate
instance.description = description
instance.save()
except Student.DoesNotExist:
return JsonResponse(data={}, status=404) # 没有内容
# 3. 返回结果
return JsonResponse(data={
"id": instance.id,
"name": instance.name,
"sex": instance.sex,
"age": instance.age,
"classmate": instance.classmate,
"description": instance.description,
}, status=201)
elif request.method == 'GET':
"""获取一条数据"""
try:
print(id)
instance = Student.objects.filter(
Q(name__icontains=id) | Q(description__icontains=id)
)
results = [
{
'name': item.name,
'description': item.description
}
for item in instance
]
return JsonResponse({'res': results},status=200)
# return JsonResponse(data={
# "id": instance.id,
# "name": instance.name,
# "sex": instance.sex,
# "age": instance.age,
# "classmate": instance.classmate,
# "description": instance.description,
# }, status=200)
except Student.DoesNotExist:
return JsonResponse(data=None, status=404) # 没有内容
几个问题:
1,Django的csrf验证怎么关闭取消?
作用:
Django框架中的CSRF(跨站请求伪造)保护是一种安全措施,它的作用是防止攻击者通过伪造请求在用户已经登录的Web应用中执行恶意操作。具体来说,CSRF保护确保了以下几点:
保护用户状态:在用户通过Web应用与服务器交互时,CSRF保护防止了用户在不知情的情况下,由第三方网站操作用户的Web应用会话。
同源策略:默认情况下,Web浏览器遵循同源策略(SOP),它限制了一个源(域名、协议和端口)的文档或脚本与另一个源的资源进行交互。CSRF利用了这一策略,因为浏览器允许跨域请求,但只有当响应中包含特定措施(如CSRF令牌)时,才会信任这些请求。
令牌验证:Django通过在视图函数中添加一个名为get_response的装饰器来实施CSRF保护。这个装饰器会检查请求中是否包含一个有效的CSRF令牌,该令牌在用户与网站交互时由网站生成,并保存在用户的会话中。
非GET请求:对于不是GET、HEAD或OPTIONS的HTTP请求,Django默认会验证CSRF令牌。这意味着任何表单提交、AJAX请求或其他类型的POST请求都需要包含CSRF令牌。
模板中的自动生成:Django模板系统会自动在表单中添加CSRF令牌,开发者在设计表单时无需手动添加。
自定义处理:开发者可以通过设置django.middleware.csrf.CsrfViewMiddleware来自定义CSRF保护的行为,例如,可以创建自己的CSRF保护策略或禁用CSRF保护。
总结来说,Django的CSRF保护是为了确保Web应用的安全性,防止攻击者利用用户的会话执行未授权的操作。
通常可利用装饰器:
from django.views.decorators.csrf import csrf_protect, csrf_exempt
@ csrf_exempt关闭验证
@ csrf_protect开启验证
目标:
Django的CSRF保护默认针对所有非GET、非HEAD、非OPTIONS的HTTP请求。这意味着,任何形式的表单提交(使用method="post"的HTML表单)、AJAX请求、或其他类型的POST、PUT、DELETE等请求都会受到CSRF保护。
具体来说,CSRF保护会检查以下几点:
POST请求:当用户通过表单提交数据时,Django会检查请求中是否包含正确的CSRF令牌。
AJAX请求:在使用JavaScript发起的AJAX请求中,需要在请求的头部添加一个名为X-CSRFToken的HTTP头来携带CSRF令牌。
PUT、DELETE等HTTP方法:对于使用这些HTTP方法的请求,Django同样会验证CSRF令牌。
非浏览器请求:对于非浏览器发起的请求(例如,由Python脚本直接发起的请求),Django不会实施CSRF保护,因为这些请求通常不受同源策略的限制。
OPTIONS预检请求:对于CORS(跨源资源共享)的OPTIONS预检请求,Django不会验证CSRF令牌,因为这些请求通常不携带任何有效载荷。
开发者可以自定义CSRF保护的行为,例如,可以通过设置django.middleware.csrf.CsrfViewMiddleware的process_view方法来改变默认的CSRF保护策略。此外,也可以通过设置django.middleware.csrf.CsrfViewMiddleware的exempt属性来豁免某些视图或URL路径的CSRF保护。
总之,Django的CSRF保护是为了确保Web应用在面对跨站请求伪造攻击时能够保持安全,它通过验证请求中的CSRF令牌来确保请求是由用户预期的来源发出的。
2,Student模型Q查询和普通get查询有什么区别?
语法:
# 假设有一个使用Q对象构建查询的场景
query = Q(field1='value1') & Q(field2='value2')
results = query.all() # 这里返回的是一个结果集的抽象表示
# 然后你可以使用get方法来获取一个具体的记录,如果存在的话
record = results.get() # 这会返回一个具体的记录或者None
查询返回结果
Q查询结果是:
<class 'django.db.models.query.QuerySet'>
<QuerySet [<Student: Student object (7)>, <Student: Student object (8)>]>
返回的是一个模型类对象列表
get查询结果是:
<class 'mysystem.models.Student'>
Student object (3)
返回的是一个模型类对象
方式:
get通常是查询指定字段
Q查询可以构建复杂的查询,
Q对象通常是指一个查询构造器或者查询对象,它允许开发者构建复杂的查询语句。这样的对象提供了链式调用的方法来指定查询条件、排序、限制等。而get方法通常是在查询构造完成后用来执行查询并获取结果的。
具体来说,Q对象构建的查询返回的是一个查询结果集的抽象表示,也就是一个包含了一系列符合条件的记录的集合。这个集合可能包含了很多记录,但是并没有实际从数据库中检索出数据。
而get方法返回的是查询结果集中的一个单独的记录。当你使用get方法时,通常指定了查询返回的记录的类型(例如,对于一个用户表的查询,你可能想要获取一个User对象),然后查询执行并返回该类型的一个实例。如果查询结果集中有多个记录,get方法通常会返回第一个记录。
需要了解链式和非链式查询区别,以及使用多条件和使用‘与或非’,
或: | 多个条件,一个为真全为真
与: &
非: 没有直接的非,可以使用~取反
Student.objects.get(pk=id)
等效SELECT * FROM Student WHERE pk = id;
Student.objects.filter(Q(name=id) | Q(des=id))
等效SELECT * FROM Student WHERE name LIKE id OR des LIKE id;
建议:需要什么就用什么字段,少用*,like查询在没有索引的情况下,可能效率较低
3,列表推导式怎么用
[值对象,值范围,判断条件]
值对象:Python数据类型,包含int,str,list,(),{}等,需要插入构造列表的值
值范围:相当于循环次数
判断条件:符合则插入值对象中
results = [
{
'name': item.name,
'description': item.description
}
for item in instance
if item.age > 24
]
把可迭代对象instance中的item取出,当item.age > 24时,把另外两个值写入值对象 集合中
相当于下面伪代码:
results = [{'name','description'}]
for item in instance:
if item.age > 24:
results.append(item)
提供几种常见的用法
- 列表推导式的执行顺序:各语句之间是嵌套关系,左边第二个语句是最外层,依次往右进一层,左边第一条语句是最后一层。
>>> aList = [x*x for x in range(10)]
#相当于
>>> aList = []
>>> for x in range(10):
aList.append(x*x)
>>> freshfruit = [' banana', ' loganberry ', 'passion fruit ']
>>> aList = [w.strip() for w in freshfruit]
#等价于下面的代码
>>> aList = []
>>> for item in freshfruit:
aList.append(item.strip())
123456789101112
- 使用列表推导式实现嵌套列表的平铺。
>>> vec = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> [num for elem in vec for num in elem]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
123
在这个列表推导式中有2个循环,其中第一个循环可以看作是外循环,执行的慢;而第二个循环可以看作是内循环,执行的快。上面代码的执行过程等价于下面的写法:
>>> vec = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> result = []
>>> for elem in vec:
for num in elem:
result.append(num)
>>> result
[1, 2, 3, 4, 5, 6, 7, 8, 9]
1234567
- 在列表推导式中使用if过滤不符合条件的元素。
在列表推导式中可以使用if子句对列表中的元素进行筛选,只在结果列表中保留符合条件的元素。下面的代码可以列出当前文件夹下所有Python源文件:
>>> import os
>>> [filename for filename in os.listdir('.') if filename.endswith(('.py', '.pyw'))]
12
从列表中选择符合条件的元素组成新的列表:
>>> aList = [-1, -4, 6, 7.5, -2.3, 9, -11]
>>> [i for i in aList if i>0] #所有大于0的数字
[6, 7.5, 9]
123
- 查找列表中最大元素的所有位置。
>>> from random import randint
>>> x = [randint(1, 10) for i in range(20)]
#20个介于[1, 10]的整数
>>> x
[10, 2, 3, 4, 5, 10, 10, 9, 2, 4, 10, 8, 2, 2, 9, 7, 6, 2, 5, 6]
>>> m = max(x)
>>> [index for index, value in enumerate(x) if value == m]
#最大整数的所有出现位置
[0, 5, 6, 10]
123456789
- 在列表推导式中同时遍历多个列表或可迭代对象。
>>> [(x, y) for x in [1, 2, 3] for y in [3, 1, 4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
12
对于包含多个循环的列表推导式,一定要清楚多个循环的执行顺序或“嵌套关系”。例如,上面第一个列表推导式等价于
>>> result = []
>>> for x in [1, 2, 3]:
for y in [3, 1, 4]:
if x != y:
result.append((x,y))
>>> result
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]