二十六、请介绍下Django框架的生命周期
Django是一个高级的Python Web框架,它遵循MVC设计模式(在Django中通常称为MTV,即模型(Model)、模板(Template)和视图(Views)),并且鼓励快速开发和干净、实用的设计。以下是一个简单的Django请求/响应生命周期:
- 用户发起请求:当用户通过Web浏览器访问一个网站时,会向服务器发送一个HTTP请求。
- Django Web服务器接收请求:请求首先被Django的Web服务器(如Gunicorn,Uwsgi或Django自带的开发服务器)接收,然后传递给Django框架进行处理。
- URL解析:Django框架接收到请求后,会根据URLconf(URL配置文件,通常是urls.py文件)找到与请求URL匹配的函数(称为视图)。
- 中间件处理:在Django中,还可以配置一些中间件(Middleware),这些中间件可以在请求被视图处理之前或之后进行一些处理,例如处理会话、验证用户等。
- 视图处理请求:找到匹配的视图函数后,Django会创建一个HttpRequest对象,并将这个对象作为参数传递给视图函数。视图函数会处理这个请求,并返回一个HttpResponse对象。
- 模板渲染:如果视图决定渲染一个模板,它会加载模板,然后将一个上下文(包含要在模板上显示的数据)传递给模板。模板会根据这个上下文生成HTML内容。
- 响应返回给用户:最后,Django将HttpResponse对象返回给Web服务器,Web服务器将响应转换为一个HTTP响应,然后发送给用户的Web浏览器。
二十七、请介绍下Django是怎么操作数据库的
Django通过它的ORM(Object-Relational Mapping,对象-关系映射)系统来操作数据库。ORM允许开发者用Python代码来操作数据库,而不需要写SQL语句。这样,我们就可以编写数据库独立的代码,而不用担心底层使用的是哪种数据库系统(MySQL,PostgreSQL,SQLite等)。
以下是Django操作数据库的基本步骤:
- 定义模型:在Django中,每个数据库表由一个Python类来表示,这个类继承自django.db.models.Model。每个类的属性就表示数据库表的字段。
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=200)
publication_date = models.DateField()
- 迁移:定义好模型之后,需要通过迁移来在数据库中创建对应的表。Django提供了makemigrations命令来创建迁移,然后用migrate命令来应用迁移。
python manage.py makemigrations
python manage.py migrate
- 使用模型:现在,我们可以使用定义的模型来进行数据库操作了。例如,创建一个新的记录:
from datetime import date
book = Book(title='The Pragmatic Programmer', publication_date=date(1999, 10, 30))
book.save()
也可以查询现有的记录:
books = Book.objects.filter(title__contains='Django')
- 修改和删除记录:我们也可以修改或删除数据库中的记录。例如:
# 修改记录
book = Book.objects.get(id=1)
book.title = 'New Title'
book.save()
# 删除记录
book.delete()
二十八、如何使用Django中间件
在Django中,中间件是一个轻量级、底层的“插件”系统,用来全局改变Django的输入或输出。每次一个请求被处理,Django首先会根据你的MIDDLEWARE设置来应用每个中间件类的方法。
以下是一个使用中间件的基本步骤:
- 创建中间件:中间件是一个Python类,需要实现特定的方法。例如,下面是一个简单的中间件,它会在每个请求被处理前打印一条消息:
class SimpleMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
print('在处理视图前')
response = self.get_response(request)
print('在处理视图后')
return response
上面的代码中,init方法接收一个get_response参数,并将其存储为实例变量。get_response是一个回调函数,用来获取视图的响应。
call方法是真正处理请求和响应的地方。在调用get_response之前的代码会在请求被处理前执行,调用get_response之后的代码会在请求被处理后(视图函数被调用后)执行。
- 激活中间件:要启用中间件,需要将其添加到MIDDLEWARE设置中。MIDDLEWARE是一个Python列表,包含了所有激活的中间件的字符串路径。例如:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'myapp.middleware.SimpleMiddleware', # 你的自定义中间件
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
注意,中间件的顺序很重要。在请求阶段,Django会从上到下应用每个中间件,但在响应阶段,则会从下到上应用中间件。这意味着在请求列表中,越是在上面的中间件,它的响应处理代码会越后执行。
二十九、Django开发中如何优化数据库
- 优化查询:使用ORM时,要注意避免生成不必要的查询。例如,如果你需要访问一个外键关联的对象的某个属性,最好使用select_related或prefetch_related方法,这样可以在一次查询中获取所有必要的信息,避免“N+1查询”问题。
# 优化前
books = Book.objects.all()
for book in books:
print(book.author.name)
# 优化后
books = Book.objects.select_related('author').all()
for book in books:
print(book.author.name)
- 只获取必要的字段:如果你只需要模型的某几个字段,可以使用values或values_list方法,只获取这些字段的数据,这样可以减少数据库的I/O负担。
titles = Book.objects.values_list('title', flat=True)
- 使用索引:在经常需要查询的字段上创建索引,可以大大提高查询效率。在Django的模型字段中,可以设置db_index=True来创建索引。
class Book(models.Model):
title = models.CharField(max_length=200, db_index=True)
publication_date = models.DateField()
- 分页:如果你需要显示大量的数据,最好使用分页来减少每次查询的数据量。Django提供了Paginator类来帮助实现分页。
- 缓存:对于那些不经常变化但是读取频繁的数据,可以使用缓存来提高性能。Django提供了非常完善的缓存系统,可以缓存视图的结果,也可以手动缓存数据。
三十、什么是Django中间件
Django中间件是一个轻量级、底层的“插件”系统,用来全局改变Django的输入或输出。在请求被处理的过程中,中间件是第一个处理HTTP请求或视图返回的HTTP响应的组件。它可以看作是处理请求和响应的钩子。
中间件的主要功能包括:
- 处理全局请求:例如,可以在一个中间件中检查是否有session的存在,如果没有就创建一个。
- 处理全局响应:例如,可以在一个中间件中统一添加某个HTTP头部。
- 在视图处理之前或之后改变请求或响应。
- 将某些任务钩子到请求/响应的处理过程中,例如数据缓存、数据压缩等。
一个中间件基本上就是一个Python类,它定义了以下一个或多个方法:
- init(self, get_response):在中间件实例化时调用一次,其中get_response是一个用于获取视图响应的回调函数。
- call(self, request):处理每个请求时都会调用,你可以在这里改变请求或响应。
中间件的执行顺序在Django设置中的MIDDLEWARE列表中定义,这个列表的顺序非常重要。在处理请求时,Django会按照MIDDLEWARE列表从上到下的顺序应用每个中间件,然后在处理响应时,Django会按照从下到上的顺序应用每个中间件。