Django知识点

Tornado

是一个Python web框架和异步网络库,它使用非阻塞网络I/O。使得Tornado成为构建实时ewb应用(如聊天应用,实时通知系统等)的理想选择。Tornado提供了异步的Http服务器和客户端,以及WebSocket支持。

Tornado与Django的关系

虽然 Django 和 Tornado 都可以用于构建 web 应用,但它们的设计哲学和用途有所不同。Django 提供了丰富的功能和快速的开发体验,适用于构建复杂的 web 应用。而 Tornado 则专注于性能和异步处理,适用于需要处理大量并发连接的应用。

然而,在某些情况下,开发者可能会选择将 Django 和 Tornado 结合使用,以利用两者的优势。例如,可以使用 Django 构建应用的主体部分,处理业务逻辑和数据库交互,同时使用 Tornado 作为后端的一部分,处理实时通信或高并发的 API 请求。

这种结合使用的方式通常通过 Django Channels 实现,Django Channels 是一个 Django 扩展,它允许 Django 应用处理 WebSocket 和其他异步通信协议。通过这种方式,开发者可以在同一个项目中同时利用 Django 的强大功能和 Tornado 的异步处理能力。

WSGI

定义与概述

  • 定义

    WSGI是一个Python应用程序接口,用于在web服务器和Python web应用程序或框架之间建立通信标准

  • 作用

    定义了web服务器和Python web应用程之间如何交换信息,使得web应用程序能够以统一的方式响应Http请求

  • 特点

    WSGI的主要作用是提供一个简单的接口,让Web服务器能够与任何遵循WSGI规范的Python Web应用程序进行交互。这样,开发者可以专注于编写应用程序逻辑,而不必担心底层的通信细节。

工作原理

  • 核心思想:WSGI接口的核心思想是将Web服务器和应用程序分离开来,通过一个统一的接口实现它们之间的通信。

  • 组件角色:

    • Web服务器:被称为“服务器网关”(Server Gateway),负责接收HTTP请求并将其转发给应用程序。

    • 应用程序:被称为“应用程序对象”(Application Object),负责处理请求并生成响应。

  • 信息交换:WSGI接口规定了服务器网关和应用程序对象之间的约定和规则,使得它们能够通过一种统一的方式进行通信和交互。

特点与优势

  • 简单通用:WSGI是一种简单、通用的接口规范,不依赖于特定的Web服务器或框架。任何符合WSGI规范的服务器和应用程序都可以通过WSGI接口进行通信。

  • 可移植性和可扩展性:开发人员可以在一个服务器上编写和调试应用程序,并将其无缝地迁移到另一个服务器上运行。此外,WSGI还支持中间件的概念,使开发人员能够将各种功能和组件添加到应用程序中,如日志记录、错误处理、会话管理等。

  • 支持多线程和多进程:WSGI接口支持多线程和多进程的部署方式,以提高Web应用程序的并发性能。

应用场景

  • Web应用程序开发:无论是使用原生的WSGI接口还是使用基于WSGI的框架(如Flask、Django等),都能够使用WSGI提供的统一接口进行开发。
  • 中间件和服务器网关开发:WSGI接口还可以用于构建中间件和服务器网关,以实现更高级的功能和扩展性。

Django请求的生命周期

  1. 客户端发起请求

    • 用户在浏览器中输入URL并发送HTTP请求。这个请求包含了请求方法(如GET,POST等)、请求头(如User-Agent,cookie等)以及请求体(对应POST请求,请求体会包含表单数据或json数据等)
  2. 视图处理阶段

    在这个阶段,Django会调用与请求url匹配的视图函数,视图函数可以使用Django的ORM来查询数据库,并生成响应。

  3. 响应生成阶段

    这个阶段,Django会处理视图函数返回的响应,并将响应发送给客户端。在这个阶段,也可以使用中间件来对响应进行处理

  4. 请求处理完成阶段

    • 视图函数/视图类返回的Http响应对象会再次经过中间件处理(这次是响应处理)
    • 中间件可以对响应进行进一步的修改或添加额外的响应头等信息
    • 最后,WSGI服务器会将处理后的响应发送给客户端浏览器,用户看到最终的网页内容

Django的内置组件

  1. Admin: 对model中对应的数据表进行增删改查提供的组件

  2. model:负责操作数据库

  3. form:1.生成HTML代码 2.数据有效性校验 3校验信息返回并展示

  4. ModelForm: 即用于数据库操作,也可用于用户请求的验证

中间件

Django中间件的5个方法

Django中间件是Django请求/响应处理的钩子框架,是一个轻量级的插件系统,用于在请求到达视图之前或响应返回给客户端之前执行特定的操作。以下是Django中间件的五个主要方法:

  1. process_request(self,request)
    • 在请求到达视图函数之前被调用
    • 请求对象作为参数传递给该方法
    • 可以返回None或者HttpResponse对象,
    • 如果返回HttpResponse对象,则Django不会继续执行其他中间件的process_request方法,也不会执行对应的视图函数,而是直接将该HttpResponse对象返回给客户端。
  2. process_view(self, request, view_func, view_args, view_kwargs)
    • 在请求到达视图函数之前,但在URL路由解析之后被调用
    • 参数包括HttpRequest对象、视图函数(实际的函数对象,而非字符串)、将传递给视图的位置参数列表以及将传递给视图的关键字参数字典。
    • 可以返回None或HttpResponse对象。如果返回HttpResponse对象,则Django不会调用视图函数,而是直接返回该HttpResponse对象。
  3. process_response(self, request, response)
    • 在所有视图执行完毕后,但在响应返回给客户端之前被调用
    • 参数包括HttpRequest对象和HttpResponse对象
    • 必须返回一个HttpResponse对象,可以对返回的响应进行修改后再返回
  4. process_exception(self, request,exception)
    • 当视图函数出现异常是调用
    • 参数包括HttpRequest对象和异常对象
    • 可以返回None或HttpResponse对象,如果返回HttpResponse对象,则Django会使用该响应对象替换原来 的异常响应。如果返回None,则Django会继续执行其他中间件的Process_exception方法。
  5. process_template_response(self,request,response)
    • 在视图函数执行完毕且视图返回的对象包含render方法时被调用
    • 允许中间件修改模板响应对象的内容
    • 需要返回实现了render方法的响应对象

Django中间件的应用场景

  1. 用户认证:在请求到达视图前,通过中间件进行用户身份验证,确保只有经过授权的用户才能访问特定的视图或资源
  2. 日志记录:记录用户请求和响应的详细信息,以便故障排查,性能分析或审计
  3. 请求和响应处理:在请求到达视图之前或响应返回给客户端之前,对请求和响应进行预处理或后处理,如添加HTTP头、修改请求或响应内容等。
  4. 性能优化:通过中间件设置缓存头,减少数据库的访问次数,提高应用程序的性能和响应速度
  5. 安全性控制:防止CSRF(跨站请求伪造)攻击,XSS(跨站脚本)攻击等安全威胁
  6. 异常处理:捕获并处理未处理的异常,避免应用程序因异常而崩溃,提高应用程序的健壮性
  7. 跨域请求处理:对于需要处理跨域请求的应用程序,可以编写中间件来添加适当的响应头,以允许来自其他域的请求
  8. 请求频率限制:通过中间件实现请求频率限制,如限制某个IP地址在一定时间内只能访问一定次数的特定视图或资源。

FBV与CBV

  • FBV:适合处理简单的视图和临时的需求,因为它快速且直接。
  • CBV:适合处理复杂的视图逻辑和需要重用的代码,因为它提供了更高的灵活性和可扩展性。

Django的request对象是在什么时候创建的

Django的request对象是在用户请求到达Django服务器时,由Django根据WSGI或者其他服务器接口传递的原始请求数据自动创建的,并在整个请求处理流程中传递和使用,这个过程确保了Django能够以一种结构化和有序的方式处理HTTP请求,并为开发者提供了丰富的接口来访问操作请求数据。

MVC与MTV

MVC

基本概念: MVC是一种广泛使用的软件架构模式,用于组织应用程序的代码结构,使其更加模块化、可维护和可扩展。MVC将应用程序分为三个主要组件:模型(Model)、视图(View)和控制器(Controller)。

组成部分及职责

  • 模型(Model):负责处理应用程序的数据和业务逻辑。它通常与数据库或其他数据源进行交互,执行数据的创建、读取、更新和删除(CRUD)操作,并包含验证逻辑以确保数据的一致性和有效性。

  • 视图(View):负责显示数据和用户界面。它从控制器接收数据,并以用户友好的方式呈现给用户。视图层可以包含HTML、CSS和JavaScript等前端技术,用于创建丰富的用户界面。

  • 控制器(Controller):作为模型和视图之间的桥梁,负责处理用户输入和业务逻辑。当用户与应用程序交互时(如点击按钮或提交表单),控制器接收这些输入,调用模型层进行数据处理,并将结果传递给视图层进行展示。

特点

  • 职责分离:MVC模式通过明确的职责分离,使得开发者可以专注于各自的领域,提高开发效率。

  • 灵活性:由于各组件之间的低耦合性,MVC模式使得应用程序更加灵活,易于维护和扩展。

  • 测试友好:MVC模式促进了单元测试的发展,因为各个组件可以独立进行测试。

MVT

基本概念: MTV是Django框架特有的一个架构模式,它基于MVC模式但进行了一定的调整。在MTV中,控制器(Controller)的角色被视图(Views)所替代,而视图(View)在MVC中的角色则被模板(Template)所承担。

组成部分及职责

  • 模型(Model):与MVC中的模型相同,负责处理应用程序的数据和业务逻辑。

  • 模板(Template):相当于MVC中的视图(View),负责数据的展示。它使用Django模板引擎来生成HTML页面,并可以包含静态文件和动态内容。

  • 视图(Views):在MTV中,视图(Views)扮演了MVC中控制器的角色。它负责接收用户请求、调用模型层进行数据处理,并将结果传递给模板进行展示。此外,视图还可以处理用户输入和业务逻辑。

特点

  • Django特有:MTV是Django框架特有的架构模式,与MVC模式有一定的相似性但也有所不同。

  • 简化开发:通过调整MVC中的组件角色,MTV模式使得Django框架的开发更加直观和简单。

  • 灵活性:尽管MTV在某些方面与MVC有所不同,但它同样提供了灵活的应用程序架构,支持复杂的业务逻辑和用户界面。

Django中CSRF的实现机制

CSRF Token 的生成

每次用户访问服务器时(尤其是表单页面),Django会生成一个随机的CSRF Token,并将其存储在用户的会话(session)中。同时,这个Token也会被包含在响应的页面中,通常是通过一个隐藏的表单字段(...)或者作为Cookie的一部分发送给客户端。

CSRF Token验证

  • CSRF Token的验证:当用户提交表单或发送请求时,Django会检查请求中是否包含了正确的CSRF Token。这个Token可以是通过隐藏的表单字段提交的,也可以是作为Cookie的一部分发送的(这取决于Django的配置)。

  • 中间件处理:Django的CsrfViewMiddleware中间件会自动处理CSRF Token的验证。它会在每个POST请求到达视图之前,检查请求中是否包含正确的CSRF Token。

  • Token的验证逻辑:中间件会检查请求中是否有CSRF Token(可能是表单字段或Cookie),并且与会话(session)中存储的Token进行比较。如果Token不匹配或不存在,Django会拒绝请求,并返回403 Forbidden错误。

CSRF Token的传递

  • 在表单中使用:对于HTML表单,Django模板系统提供了一个{% csrf_token %}模板标签,它会自动生成包含CSRF Token的隐藏表单字段。

  • Ajax请求:对于Ajax请求,Django要求你手动从DOM中获取CSRF Token,并将其作为请求的一部分发送给服务器。这通常是通过读取Cookie中的csrftoken值,并将其作为请求头(如X-CSRFToken)发送来实现的。

排除CSRF保护

  • 装饰器:虽然Django默认对所有POST请求进行CSRF保护,但你可以使用@csrf_exempt装饰器来排除某个视图或视图函数的CSRF保护。然而,出于安全考虑,这种做法应该谨慎使用。

  • 全局设置:你也可以在Django的设置中全局禁用CSRF保护(不推荐),但这将使你的网站更容易受到CSRF攻击。

CSRF Token的存储位置

  • 会话(Session):Django默认将CSRF Token存储在用户的会话中,这意味着它依赖于会话的存储机制(如数据库、缓存等)。

  • Cookie:虽然CSRF Token通常不是直接存储在Cookie中的,但Django可能会使用Cookie来辅助传递CSRF Token(例如,通过Cookie将Token发送给客户端,并在后续的Ajax请求中作为请求头返回)。

Django的Model中的ForeignKey字段中的on_delete参数作用

ForeignKey 字段用于表示两个模型之间的多对一关系。当你定义一个 ForeignKey 时,你经常需要指定当被关联的对象(即外键指向的对象)被删除时,应该如何处理关联到这个对象的其他记录。这就是 on_delete 参数的作用。

on_delete 参数是一个重要的安全特性,它帮助开发者定义数据库层面的约束,以确保数据的完整性和一致性。Django 提供了几种不同的选项来指定 on_delete 的行为:

  1. CASCADE:默认值。当外键指向的对象被删除时,所有关联到这个对象的外键记录也会被级联删除。这通常用于数据之间具有强依赖关系的情况。
  2. PROTECT:当尝试删除外键指向的对象时,如果还存在其他对象关联到这个对象,则抛出 ProtectedError 异常,阻止删除操作。这可以作为一种保护机制,防止意外删除重要数据。
  3. SET_NULL:仅当外键字段允许 NULL 值时有效。当外键指向的对象被删除时,所有关联到这个对象的外键字段会被设置为 NULL。这通常用于数据之间具有较弱依赖关系的情况。
  4. SET_DEFAULT:当外键指向的对象被删除时,所有关联到这个对象的外键字段会被设置为指定的默认值。这要求外键字段有默认值,并且这个默认值在逻辑上是合理的。
  5. SET(value):这是一个更灵活的选项,允许你指定一个可调用的对象(通常是函数或lambda表达式),当外键指向的对象被删除时,这个可调用的对象会被调用,并返回一个值来更新所有关联到这个对象的外键字段。这提供了最大的灵活性,但也需要你确保这个可调用的对象能够正确处理各种情况。
  6. DO_NOTHING:在数据库中,这个选项实际上不会做任何操作。如果数据库支持外键约束,并且你试图删除一个被其他记录引用的对象,那么数据库会抛出错误。如果数据库不支持外键约束(例如,在使用SQLite时),Django不会执行任何操作,也不会阻止删除操作。这通常不推荐使用,因为它依赖于数据库的具体实现。

Django中实现单元测试

假设我们有一个名为myapp的应用,其中包含一个myModel模型和一个对应的My_view

  1. 模型(Model)

    from django.db import models  
      
    class MyModel(models.Model):  
        name = models.CharField(max_length=100)
    
  2. 视图

    from django.shortcuts import render  
    from .models import MyModel  
      
    def my_view(request):  
        obj = MyModel.objects.get(name="Test")  
        return render(request, 'myapp/my_template.html', {'obj': obj})
    
  3. 单元测试

    from django.test import TestCase, Client  
    from django.urls import reverse  
    from .models import MyModel  
      
    class MyModelTestCase(TestCase):  
        def setUp(self):  
            # 在每个测试方法之前创建测试数据  
            MyModel.objects.create(name="Test")  
      
        def test_model_creation(self):  
            # 测试模型是否成功创建  
            obj = MyModel.objects.get(name="Test")  
            self.assertEqual(obj.name, 'Test')  
      
    class MyViewTestCase(TestCase):  
        def setUp(self):  
            # 创建一个测试客户端  
            self.client = Client()  
            # 在每个测试方法之前创建测试数据  
            MyModel.objects.create(name="Test")  
      
        def test_view_response(self):  
            # 测试视图的HTTP响应  
            response = self.client.get(reverse('myapp:my_view_url'))  # 假设你的URLconf中有对应的name='my_view_url'  
            self.assertEqual(response.status_code, 200)  
            self.assertContains(response, 'Test')  # 假设模板中会显示obj.name  
      
    # 注意:上面的reverse('myapp:my_view_url')需要你在urls.py中定义对应的URL,并给它一个name  
    # 例如:  
    # from django.urls import path  
    # from . import views  
    #  
    # urlpatterns = [  
    #     path('my-view/', views.my_view, name='my_view_url'),  
    # ]
    
  4. 运行测试

    python manage.py test myapp
    

    这个命令会执行myapp应用中所有测试,并报告测试结果

Django rest framework框架中的组件

DRF是一个强大且灵活的web api工具包,它基于Django构建,提供了许多用于构建API的组件和工具。以下是DRF中的一些常用组件:

  • 序列化组件 Serializers :
    • 序列化组件负责将复杂的数据类型(如Django模型实例或查询集)转换为可以被渲染成JSON、XML等格式的Python数据类型。
    • 同时,它们也负责在数据接收时完成反序列化的工作,将接收的数据转换为Python数据类型或Django模型实例。
  • 视图组件 Views
    • 视图组件用于处理HTTP请求。DRF提供了多种视图组件,包括基于类的视图(如APIViewViewSet等)和函数视图。
    • 这些视图组件提供了丰富的RESTful功能,如GET、POST、PUT、PATCH和DELETE等方法。
  • 路由组件 Routers
    • 路由组件负责将视图与URL进行映射。DRF提供了自动路由功能,可以根据视图集中的方法自动生成对应的URL路由。
    • 这使得开发者可以更加专注于业务逻辑的实现,而无需手动编写大量的URL配置。
  • 认证组件 Authentication
    • 认证组件用于用户认证,确保只有经过认证的用户才能访问受保护的资源。
    • DRF内置了多种认证方式,如TokenAuthentication、SessionAuthentication等,同时也支持自定义认证方式。
  • 权限组件 Permissions
    • 权限组件用于控制用户权限,确保用户只能访问他们被授权的资源。
    • DRF提供了灵活的权限控制机制,允许开发者根据业务需求自定义权限类。
  • 分页组件 Pagination
    • 分页组件用于数据的分页显示,以减轻服务器压力并提高用户体验。
    • DRF提供了多种分页方式,如PageNumberPagination、LimitOffsetPagination等,同时也支持自定义分页方式。
  • 解析器组件(Parsers)
    • 解析器组件用于解析HTTP请求中的数据。DRF支持多种数据格式,如JSON、XML等,并提供了相应的解析器来解析这些数据。
  • 渲染器组件(Renderers)
    • 渲染器组件用于渲染HTTP响应。DRF支持多种响应格式,如JSON、XML等,并提供了相应的渲染器来生成这些格式的响应。
  • 版本组件(Versioning)
    • 版本组件用于支持API的版本管理,允许不同版本的API共存。
    • DRF提供了多种版本控制策略,如基于URL的、基于请求头的等。
  • 其他组件:
    • 除了上述主要组件外,DRF还提供了许多其他有用的组件和工具,如过滤器(Filtering)、排序(Ordering)、异常处理(Exception Handling)等,这些组件和工具共同构成了DRF强大的功能体系。

Django 中哪里用到了线程?哪里用到了协程?哪里用到了进程 ?

在Django中,线程、协程和进程的使用并不是Django框架本身直接提供的,而是依赖于其运行环境、部署方式以及可能使用的第三方库。以下是对Django中线程、协程和进程使用情况的简述:

线程

  1. web服务器层面
    • Django通常部署在WSGI(Web Server Gateway Interface)服务器上,如Gunicorn或uWSGI。这些服务器在处理并发请求时,可能会使用线程来优化性能。例如,Gunicorn可以通过配置工作进程和工作线程的数量来管理并发请求。
    • Django自带的开发服务器(manage.py runserver)在默认情况下是单线程的,但可以通过--nothreading--noreload选项来控制其行为。然而,在生产环境中,通常会使用能够处理多线程或多进程的WSGI服务器。
  2. Django代码内部
    • 在Django代码中直接使用线程(通过Python的threading模块)来执行后台任务或处理耗时操作的情况并不常见,因为Django的设计通常是同步的。但在某些特定场景下,开发者可能会选择使用线程来实现某些功能。
  3. 数据库连接
    • Django的数据库连接通常是线程安全的,这意味着每个线程可以有自己的数据库连接。Django的ORM提供了数据库连接池的概念,以支持高效的线程间数据库访问。

协程

  1. 异步视图和中间件
    • 从Django 3.1开始,Django支持异步视图和中间件,这允许开发者使用async和await关键字编写异步代码。这些异步视图和中间件通常与ASGI(Asynchronous Server Gateway Interface)服务器(如Daphne或Uvicorn)一起使用,这些服务器支持基于协程的并发模型。
  2. Channels
    • Channels是一个Django的第三方库,它为Django添加了实时、双向通信的能力。Channels基于ASGI,并使用协程来处理WebSocket、HTTP2和其他协议。
  3. 异步数据库操作
    • 虽然Django的默认ORM是同步的,但有一些第三方库(如databases)提供了异步的数据库操作支持,这些操作可以与协程一起使用。

进程

  1. Web服务器和部署
    • 像Gunicorn这样的WSGI服务器通常使用多个进程来处理请求,每个进程可以有自己的线程池。这种方式有助于隔离不同请求之间的状态,并提供了更高的稳定性。
  2. 后台任务
    • Django通常与Celery这样的任务队列一起使用来处理后台任务。Celery可以配置为使用不同的并发模型,包括多进程,来执行异步任务。
  3. Django内部代码
    • 在某些情况下,开发者可能会选择使用Python的multiprocessing模块在Django应用中直接创建和管理进程。这通常用于执行CPU密集型任务或需要隔离状态的操作。
posted @ 2025-07-01 22:49  小郑[努力版]  阅读(17)  评论(0)    收藏  举报