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 |
| |
| |
| def view(request): |
| if request.method == 'GET': |
| """获取多个学生信息""" |
| |
| students_list = list(Student.objects.values()) |
| |
| |
| return JsonResponse(data=students_list, status=200, safe=False) |
| elif request.method == 'POST': |
| """添加一个学生信息""" |
| |
| 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") |
| |
| |
| instance = Student.objects.create( |
| name=name, |
| sex=sex, |
| age=age, |
| classmate=classmate, |
| description=description, |
| ) |
| |
| |
| return JsonResponse(data={ |
| "id": instance.pk, |
| "name": instance.name, |
| "sex": instance.sex, |
| "age": instance.age, |
| "classmate": instance.classmate, |
| "description": instance.description, |
| }, status=201) |
| |
| |
| 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': |
| """更新一个学生信息""" |
| |
| 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") |
| |
| |
| 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) |
| |
| |
| 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) |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| 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查询有什么区别?
语法:
| |
| query = Q(field1='value1') & Q(field2='value2') |
| results = query.all() |
| |
| |
| record = results.get() |
| |
查询返回结果
| Q查询结果是: |
| <class |
| <QuerySet [<Student: Student object (7)>, <Student: Student object (8)>]> |
| 返回的是一个模型类对象列表 |
| get查询结果是: |
| <class |
| 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子句对列表中的元素进行筛选,只在结果列表中保留符合条件的元素。下面的代码可以列出当前文件夹下所有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] |
| [6, 7.5, 9] |
| 123 |
| >>> from random import randint |
| >>> x = [randint(1, 10) for i in range(20)] |
| |
| >>> 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)] |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步