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请求的生命周期
-
客户端发起请求
- 用户在浏览器中输入URL并发送HTTP请求。这个请求包含了请求方法(如GET,POST等)、请求头(如User-Agent,cookie等)以及请求体(对应POST请求,请求体会包含表单数据或json数据等)
-
视图处理阶段
在这个阶段,Django会调用与请求url匹配的视图函数,视图函数可以使用Django的ORM来查询数据库,并生成响应。
-
响应生成阶段
这个阶段,Django会处理视图函数返回的响应,并将响应发送给客户端。在这个阶段,也可以使用中间件来对响应进行处理
-
请求处理完成阶段
- 视图函数/视图类返回的Http响应对象会再次经过中间件处理(这次是响应处理)
- 中间件可以对响应进行进一步的修改或添加额外的响应头等信息
- 最后,WSGI服务器会将处理后的响应发送给客户端浏览器,用户看到最终的网页内容
Django的内置组件
-
Admin: 对model中对应的数据表进行增删改查提供的组件
-
model:负责操作数据库
-
form:1.生成HTML代码 2.数据有效性校验 3校验信息返回并展示
-
ModelForm: 即用于数据库操作,也可用于用户请求的验证
中间件
Django中间件的5个方法
Django中间件是Django请求/响应处理的钩子框架,是一个轻量级的插件系统,用于在请求到达视图之前或响应返回给客户端之前执行特定的操作。以下是Django中间件的五个主要方法:
- process_request(self,request)
- 在请求到达视图函数之前被调用
- 请求对象作为参数传递给该方法
- 可以返回None或者HttpResponse对象,
- 如果返回HttpResponse对象,则Django不会继续执行其他中间件的process_request方法,也不会执行对应的视图函数,而是直接将该HttpResponse对象返回给客户端。
- process_view(self, request, view_func, view_args, view_kwargs)
- 在请求到达视图函数之前,但在URL路由解析之后被调用
- 参数包括HttpRequest对象、视图函数(实际的函数对象,而非字符串)、将传递给视图的位置参数列表以及将传递给视图的关键字参数字典。
- 可以返回None或HttpResponse对象。如果返回HttpResponse对象,则Django不会调用视图函数,而是直接返回该HttpResponse对象。
- process_response(self, request, response)
- 在所有视图执行完毕后,但在响应返回给客户端之前被调用
- 参数包括HttpRequest对象和HttpResponse对象
- 必须返回一个HttpResponse对象,可以对返回的响应进行修改后再返回
- process_exception(self, request,exception)
- 当视图函数出现异常是调用
- 参数包括HttpRequest对象和异常对象
- 可以返回None或HttpResponse对象,如果返回HttpResponse对象,则Django会使用该响应对象替换原来 的异常响应。如果返回None,则Django会继续执行其他中间件的Process_exception方法。
- process_template_response(self,request,response)
- 在视图函数执行完毕且视图返回的对象包含render方法时被调用
- 允许中间件修改模板响应对象的内容
- 需要返回实现了render方法的响应对象
Django中间件的应用场景
- 用户认证:在请求到达视图前,通过中间件进行用户身份验证,确保只有经过授权的用户才能访问特定的视图或资源
- 日志记录:记录用户请求和响应的详细信息,以便故障排查,性能分析或审计
- 请求和响应处理:在请求到达视图之前或响应返回给客户端之前,对请求和响应进行预处理或后处理,如添加HTTP头、修改请求或响应内容等。
- 性能优化:通过中间件设置缓存头,减少数据库的访问次数,提高应用程序的性能和响应速度
- 安全性控制:防止CSRF(跨站请求伪造)攻击,XSS(跨站脚本)攻击等安全威胁
- 异常处理:捕获并处理未处理的异常,避免应用程序因异常而崩溃,提高应用程序的健壮性
- 跨域请求处理:对于需要处理跨域请求的应用程序,可以编写中间件来添加适当的响应头,以允许来自其他域的请求
- 请求频率限制:通过中间件实现请求频率限制,如限制某个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
的行为:
- CASCADE:默认值。当外键指向的对象被删除时,所有关联到这个对象的外键记录也会被级联删除。这通常用于数据之间具有强依赖关系的情况。
- PROTECT:当尝试删除外键指向的对象时,如果还存在其他对象关联到这个对象,则抛出 ProtectedError 异常,阻止删除操作。这可以作为一种保护机制,防止意外删除重要数据。
- SET_NULL:仅当外键字段允许 NULL 值时有效。当外键指向的对象被删除时,所有关联到这个对象的外键字段会被设置为 NULL。这通常用于数据之间具有较弱依赖关系的情况。
- SET_DEFAULT:当外键指向的对象被删除时,所有关联到这个对象的外键字段会被设置为指定的默认值。这要求外键字段有默认值,并且这个默认值在逻辑上是合理的。
- SET(value):这是一个更灵活的选项,允许你指定一个可调用的对象(通常是函数或lambda表达式),当外键指向的对象被删除时,这个可调用的对象会被调用,并返回一个值来更新所有关联到这个对象的外键字段。这提供了最大的灵活性,但也需要你确保这个可调用的对象能够正确处理各种情况。
- DO_NOTHING:在数据库中,这个选项实际上不会做任何操作。如果数据库支持外键约束,并且你试图删除一个被其他记录引用的对象,那么数据库会抛出错误。如果数据库不支持外键约束(例如,在使用SQLite时),Django不会执行任何操作,也不会阻止删除操作。这通常不推荐使用,因为它依赖于数据库的具体实现。
Django中实现单元测试
假设我们有一个名为myapp的应用,其中包含一个myModel模型和一个对应的My_view
-
模型(Model)
from django.db import models class MyModel(models.Model): name = models.CharField(max_length=100)
-
视图
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})
-
单元测试
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'), # ]
-
运行测试
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提供了多种视图组件,包括基于类的视图(如
APIView
、ViewSet
等)和函数视图。 - 这些视图组件提供了丰富的RESTful功能,如GET、POST、PUT、PATCH和DELETE等方法。
- 视图组件用于处理HTTP请求。DRF提供了多种视图组件,包括基于类的视图(如
- 路由组件 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中线程、协程和进程使用情况的简述:
线程
- web服务器层面
- Django通常部署在WSGI(Web Server Gateway Interface)服务器上,如Gunicorn或uWSGI。这些服务器在处理并发请求时,可能会使用线程来优化性能。例如,Gunicorn可以通过配置工作进程和工作线程的数量来管理并发请求。
- Django自带的开发服务器(
manage.py runserver
)在默认情况下是单线程的,但可以通过--nothreading
和--noreload
选项来控制其行为。然而,在生产环境中,通常会使用能够处理多线程或多进程的WSGI服务器。
- Django代码内部
- 在Django代码中直接使用线程(通过Python的
threading
模块)来执行后台任务或处理耗时操作的情况并不常见,因为Django的设计通常是同步的。但在某些特定场景下,开发者可能会选择使用线程来实现某些功能。
- 在Django代码中直接使用线程(通过Python的
- 数据库连接
- Django的数据库连接通常是线程安全的,这意味着每个线程可以有自己的数据库连接。Django的ORM提供了数据库连接池的概念,以支持高效的线程间数据库访问。
协程
- 异步视图和中间件
- 从Django 3.1开始,Django支持异步视图和中间件,这允许开发者使用async和await关键字编写异步代码。这些异步视图和中间件通常与ASGI(Asynchronous Server Gateway Interface)服务器(如Daphne或Uvicorn)一起使用,这些服务器支持基于协程的并发模型。
- Channels
- Channels是一个Django的第三方库,它为Django添加了实时、双向通信的能力。Channels基于ASGI,并使用协程来处理WebSocket、HTTP2和其他协议。
- 异步数据库操作
- 虽然Django的默认ORM是同步的,但有一些第三方库(如databases)提供了异步的数据库操作支持,这些操作可以与协程一起使用。
进程
- Web服务器和部署
- 像Gunicorn这样的WSGI服务器通常使用多个进程来处理请求,每个进程可以有自己的线程池。这种方式有助于隔离不同请求之间的状态,并提供了更高的稳定性。
- 后台任务
- Django通常与Celery这样的任务队列一起使用来处理后台任务。Celery可以配置为使用不同的并发模型,包括多进程,来执行异步任务。
- Django内部代码
- 在某些情况下,开发者可能会选择使用Python的
multiprocessing
模块在Django应用中直接创建和管理进程。这通常用于执行CPU密集型任务或需要隔离状态的操作。
- 在某些情况下,开发者可能会选择使用Python的