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)]
posted @ 2024-04-03 15:34  腿哥123  阅读(16)  评论(0编辑  收藏  举报