Django - 快速指南
Django - 快速指南
Section titled “Django - 快速指南”--- Django 基础 ---
Section titled “--- Django 基础 ---”Django 是一个高级的 Python Web 框架,旨在快速开发安全且可维护的网站。它鼓励清晰、实用的设计,并遵循“不要重复你自己”(Don’t Repeat Yourself, DRY)原则。
注意:根据 BSD 许可证授权,由 Django 软件基金会(DSF)维护。
- 2003 年始于劳伦斯世界报(Lawrence Journal-World newspaper)。
- 2005 年 7 月公开发布。
- 一个积极开发的开源项目,拥有庞大的社区。
- 松耦合(Loosely Coupled):组件相互独立。
- 代码更少(Less Code):减少样板代码。
- DRY:避免冗余。
- 快速开发(Fast Development):工具加快开发过程。
- 清晰设计(Clean Design):提倡最佳实践。
- 显式优于隐式(Explicit over Implicit):避免“魔法”。
- ORM(Object-Relational Mapper):使用 Python 与数据库交互。
- Admin 界面:自动化的站点管理。
- URL 路由:清晰的 URL 设计。
- 模板系统:将展示层与逻辑分离。
- 表单处理:验证和处理。
- 安全性:内置保护措施。
- 可伸缩性:解耦的组件。
- 多功能性:可以构建各种 Web 应用程序。
- 内置丰富功能(Batteries Included):包含许多内置功能。
- 开发服务器:用于测试的轻量级服务器。
--- Django 概览(MVT 模式)---
Section titled “--- Django 概览(MVT 模式)---”Django 通常遵循 Model-View-Template(MVT)架构模式,这是常见的 Model-View-Controller(MVC)模式的一个变体。
MVT 组件:
Section titled “MVT 组件:”- Model:表示数据结构(通常是数据库表)。定义数据的字段和行为。
- View:处理请求逻辑。它接收 HTTP 请求,与 Model 交互(如果需要),并通过渲染 Template 返回 HTTP 响应。
- Template:定义展示层(HTML)。它包含数据的占位符(变量)以及 View 提供的基本逻辑(标签、过滤器)。
- URL Dispatcher:将请求的 URL 映射到特定的 View。
与 MVC 的区别:
Section titled “与 MVC 的区别:”在 MVT 中,“View” 更像 MVC 中的“Controller”(处理逻辑),而“Template” 更像 MVC 中的“View”(处理展示)。Django 本身处理了许多类似 Controller 的框架方面的工作(路由请求等)。
- 用户请求一个 URL。
- Django 的 URL Dispatcher 找到匹配的 URL 模式,并调用相关的 View。
- View 执行逻辑,可能与 Model 交互以获取或保存数据。
- View 选择一个 Template 并将数据(Context)传递给它。
- Template Engine 使用 Context 渲染 Template,生成 HTML。
- View 将渲染后的 HTML 作为 HttpResponse 返回给用户的浏览器。
--- Django 环境设置 ---
Section titled “--- Django 环境设置 ---”设置 Django 开发环境包括安装 Python、Django 本身,通常还有一个数据库系统。
步骤 1:安装 Python
Section titled “步骤 1:安装 Python”Django 需要 Python。请查阅具体 Django 版本的文档以了解兼容的 Python 版本(现代 Django 需要 Python 3.8+)。如果您没有安装 Python,请从 python.org 下载。使用 python --version 或 python3 --version 验证安装。
最佳实践: 使用虚拟环境来隔离项目依赖。使用以下命令创建一个虚拟环境:
$ python -m venv myenv$ source myenv/bin/activate # 在 Linux/macOS 上$ myenv\Scripts\activate # 在 Windows 上步骤 2:安装 Django
Section titled “步骤 2:安装 Django”激活虚拟环境后,使用 pip 安装 Django:
$ pip install Django验证安装:
$ python -m django --version步骤 3:数据库设置
Section titled “步骤 3:数据库设置”Django 支持 PostgreSQL、MySQL、SQLite 和 Oracle。对于开发来说,SQLite 通常足够,并且无需单独的服务器设置(它在默认情况下已配置)。对于生产环境,通常使用更健壮的数据库,如 PostgreSQL 或 MySQL。您需要在虚拟环境中安装数据库服务器本身和相应的 Python 驱动程序(PostgreSQL 的 psycopg2-binary,MySQL 的 mysqlclient)。
在 settings.py 的 DATABASES 字典中配置您的数据库连接。
步骤 4:Web 服务器
Section titled “步骤 4:Web 服务器”Django 包含一个轻量级的开发 Web 服务器(python manage.py runserver)。这不适合生产环境。对于部署,常见的选择包括使用 Gunicorn 或 uWSGI 运行在 Nginx 等反向代理后面,或使用 Apache 配合 mod_wsgi。
--- 创建项目 ---
Section titled “--- 创建项目 ---”一个 Django Project 代表一个 Web 应用程序。
创建 Project 命令:
Section titled “创建 Project 命令:”$ django-admin startproject myprojectProject 结构:
Section titled “Project 结构:”myproject/├── manage.py└── myproject/ ├── __init__.py ├── asgi.py ├── settings.py ├── urls.py └── wsgi.pymanage.py:命令行工具。settings.py:项目配置。urls.py:主 URL 路由。wsgi.py/asgi.py:服务器入口点。
初始配置(settings.py):
Section titled “初始配置(settings.py):”- 设置
DEBUG = True(仅用于开发)。 - 配置
DATABASES(默认为 SQLite)。 - 检查
INSTALLED_APPS、MIDDLEWARE、TEMPLATES、STATIC_URL。
运行开发服务器:
Section titled “运行开发服务器:”$ python manage.py runserver在浏览器中访问 http://127.0.0.1:8000/ 查看欢迎页面。
--- 应用生命周期 ---
Section titled “--- 应用生命周期 ---”一个 Django 项目由 App 组成。App 是一个可重用的模块,处理特定的功能(例如,博客、投票)。
创建 App:
Section titled “创建 App:”导航到您的项目目录(包含 manage.py 的目录),并运行:
$ python manage.py startapp myapp这会创建一个 myapp 目录:
myapp/├── __init__.py├── admin.py # Admin 站点配置├── apps.py # App 配置├── migrations/ # 数据库迁移文件│ └── __init__.py├── models.py # 数据模型(数据库结构)├── tests.py # 应用测试└── views.py # 请求处理逻辑(视图)注册 App:
Section titled “注册 App:”将您的应用添加到项目 settings.py 文件中的 INSTALLED_APPS 列表。使用 myapp/apps.py 中找到的 App 配置类路径:
INSTALLED_APPS = [ # ... 其他应用 'myapp.apps.MyappConfig', # 或者只写 'myapp' 'django.contrib.admin', 'django.contrib.auth', # ... 更多默认应用]App 开发周期:
Section titled “App 开发周期:”- 在
models.py中定义模型。 - 运行
python manage.py makemigrations myapp创建迁移文件。 - 运行
python manage.py migrate将更改应用到数据库。 - 在
views.py中创建视图来处理请求。 - 创建模板(例如,在
myapp/templates/myapp/中)用于展示。 - 在
myapp/urls.py中定义 URL 模式,并将其包含在项目的urls.py中。 - 可选地,在
admin.py中注册模型,以便通过 Admin 站点管理它们。 - 在
tests.py中编写测试。
--- Admin 界面 ---
Section titled “--- Admin 界面 ---”Django 的 Admin 是一个强大、自动生成的界面,用于管理您网站的内容。
- 确保
django.contrib.admin及其依赖项在INSTALLED_APPS中。 - 确保所需的 Middleware(
SessionMiddleware、AuthenticationMiddleware等)在MIDDLEWARE中。 - 在项目
urls.py中包含 Admin URL:path('admin/', admin.site.urls)。
1. 运行迁移:`python manage.py migrate`2. 创建超级用户:`python manage.py createsuperuser`运行 python manage.py runserver 并访问 /admin/。使用超级用户凭据登录。
Admin 站点列出已注册的模型。您可以对模型实例执行 CRUD 操作(创建、读取、更新、删除)。要使您自己的模型可管理,请在应用的 admin.py 文件中注册它们。
myapp/admin.py 示例:
from django.contrib import adminfrom .models import YourModel # 导入您的模型
admin.site.register(YourModel) # 注册您的模型--- 创建 Views ---
Section titled “--- 创建 Views ---”Views 处理请求逻辑并返回响应。它们位于 views.py 中。
基于函数的 View (FBV):
Section titled “基于函数的 View (FBV):”from django.http import HttpResponse
def index(request): return HttpResponse("Hello, world!")使用 Templates 的 View:
Section titled “使用 Templates 的 View:”from django.shortcuts import renderimport datetime
def current_time(request): now = datetime.datetime.now() return render(request, 'myapp/time.html', {'current_time': now})myapp/templates/myapp/time.html:
<p>当前时间: {{ current_time }}</p>带参数的 Views:
Section titled “带参数的 Views:”from django.http import HttpResponse
def detail(request, item_id): return HttpResponse(f"您正在查看 item {item_id}。")参数从 URL 配置中捕获。
--- URL 映射 ---
Section titled “--- URL 映射 ---”Django 使用 urls.py 文件将请求的 URL 映射到 Views。
项目 urls.py (myproject/urls.py):
Section titled “项目 urls.py (myproject/urls.py):”URL 路由的主要入口点。它通常包含来自各个 App 的 URL。
from django.contrib import adminfrom django.urls import path, include
urlpatterns = [ path('admin/', admin.site.urls), path('myapp/', include('myapp.urls')), # 包含 App 的 URL]App urls.py (myapp/urls.py):
Section titled “App urls.py (myapp/urls.py):”定义特定于 App 的 URL 模式。
from django.urls import pathfrom . import views
# app_name = 'myapp' # 可选:为 URL 添加命名空间
urlpatterns = [ path('', views.index, name='index'), # 例如,/myapp/ path('time/', views.current_time, name='current_time'), # 例如,/myapp/time/ path('item/<int:item_id>/', views.detail, name='detail'), # 例如,/myapp/item/5/]解释:
path():定义一个 URL 路由。- 第一个参数:URL 模式字符串。转换器(如
<int:item_id>)捕获 URL 的一部分并将其作为参数传递给 View。 - 第二个参数:View 函数或基于类的 View 的
as_view()方法。 name:URL 模式的唯一名称,用于反向解析 URL(例如,在模板中使用{% url %})。
--- 模板系统 ---
Section titled “--- 模板系统 ---”将展示层(HTML)与逻辑(Python)分离。
{{ variable }}:输出 Context 中变量的值。{{ variable.attribute }}:访问属性。{{ variable|filter }}:应用过滤器修改输出(例如,{{ name|lower }})。{% tag %}:执行逻辑(例如,{% if %}、{% for %}、{% url %}、{% extends %})。
{% if condition %}…{% else %}…{% endif %}:条件判断。{% for item in list %}…{% empty %}…{% endfor %}:循环。{% extends 'base.html' %}:模板继承(必须是第一个标签)。{% block block_name %}…{% endblock %}:在基础模板中定义可覆盖的块。{% url 'url_name' arg1 arg2 %}:反向解析 URL。{% load static %}:加载静态文件标签。{% static 'path/to/file.css' %}:生成静态文件 URL。{# comment #}或{% comment %}…{% endcomment %}:注释。
Context:
Section titled “Context:”Views 通过 Context 字典将数据传递给 Templates:render(request, 'template.html', {'my_var': value})。
--- 模型 ---
Section titled “--- 模型 ---”Models 定义了应用程序的数据结构,映射到数据库表。
定义 Models(models.py):
Section titled “定义 Models(models.py):”from django.db import modelsfrom django.utils import timezone
class Post(models.Model): title = models.CharField(max_length=200) content = models.TextField() published_date = models.DateTimeField('date published', default=timezone.now) author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
def __str__(self): return self.title
class Meta: ordering = ['-published_date'] # 默认排序解释:
- 每个继承自
models.Model的类代表一个数据库表。 - 类属性是模型字段(
CharField、TextField、DateTimeField、ForeignKey等),代表表列。 ForeignKey、ManyToManyField、OneToOneField定义关系。on_delete=models.CASCADE:定义关联对象删除时的行为。__str__:返回对象的可读字符串表示(用于 Admin)。Meta类:可选元数据(例如,默认排序、表名)。
迁移(Migrations):
Section titled “迁移(Migrations):”更改模型后:
1. 创建迁移:`python manage.py makemigrations myapp`2. 将迁移应用到数据库:`python manage.py migrate`查询数据(Views 或 Shell):
Section titled “查询数据(Views 或 Shell):”Django 提供了一个数据库抽象 API(ORM)。
from .models import Post
# 获取所有文章all_posts = Post.objects.all()
# 通过主键 (pk) 获取特定文章post = Post.objects.get(pk=1)
# 过滤文章recent_posts = Post.objects.filter(published_date__year=2023)
# 创建新文章new_post = Post.objects.create(title='新标题', content='...', author=request.user)
# 更新文章post.title = '更新后的标题'post.save()
# 删除文章post.delete()--- 页面重定向 ---
Section titled “--- 页面重定向 ---”使用 django.shortcuts.redirect 将用户发送到不同的 URL。
在 Views 中的使用:
Section titled “在 Views 中的使用:”from django.shortcuts import redirect
def old_view(request): # 使用 URL 名称进行重定向(最佳实践) return redirect('new_view_name', permanent=True)
def another_view(request): # 使用硬编码路径进行重定向 return redirect('/some/other/path/')
def view_with_args(request, item_id): # 带参数的重定向 return redirect('item_detail', pk=item_id)redirect 的参数:
- 一个模型实例(使用其
get_absolute_url()方法)。 - 一个 URL 名称(来自
urls.py)加上可选的位置参数/关键字参数。 - 一个硬编码的 URL 路径字符串(例如,
/myapp/home/)。 permanent=True发送 301(永久)重定向,默认为 302(临时)。
使用 reverse() 生成 URL:
Section titled “使用 reverse() 生成 URL:”使用 django.urls.reverse 获取 URL 字符串,而不是重定向(在模型或其他地方很有用)。
from django.urls import reverse
url = reverse('item_detail', kwargs={'pk': 5})# url 将是 '/myapp/item/5/'(取决于您的 URLConf)--- 发送电子邮件 ---
Section titled “--- 发送电子邮件 ---”Django 提供了发送电子邮件的函数。
配置(settings.py):
Section titled “配置(settings.py):”设置电子邮件后端和凭据:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'# 对于开发,可以使用控制台输出:# EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'EMAIL_HOST = 'smtp.example.com'EMAIL_PORT = 587EMAIL_USE_TLS = TrueEMAIL_HOST_USER = '您的邮箱@example.com'EMAIL_HOST_PASSWORD = '您的密码'发送简单电子邮件:
Section titled “发送简单电子邮件:”from django.core.mail import send_mail
send_mail( '主题在此', '消息内容在此。', 'from@example.com', # 发件人 ['to@example.com'], # 收件人列表 fail_silently=False,)发送 HTML 电子邮件:
Section titled “发送 HTML 电子邮件:”from django.core.mail import send_mail
html_message = '<p>这是**HTML**消息。</p>'send_mail( 'HTML 主题', '非 HTML 客户端的备用纯文本消息。', # 必填,用于非 HTML 客户端 'from@example.com', ['to@example.com'], html_message=html_message,)使用 EmailMessage 获得更多控制:
Section titled “使用 EmailMessage 获得更多控制:”from django.core.mail import EmailMessage
email = EmailMessage( '你好', '消息体在此', 'from@example.com', ['to1@example.com', 'to2@example.com'], bcc=['bcc@example.com'], reply_to=['another@example.com'], headers={'Message-ID': 'foo'},)# email.attach('logo.png', img_data, 'image/png') # 附加文件email.send()--- 通用视图 (Generic Views) ---
Section titled “--- 通用视图 (Generic Views) ---”基于类的 View,以最少的代码解决常见的 Web 开发模式(显示列表、详情页、表单等)。
常用 Generic Views:
Section titled “常用 Generic Views:”TemplateView:渲染模板。ListView:显示对象列表。DetailView:显示单个对象的详情。CreateView、UpdateView、DeleteView:处理用于创建、更新、删除对象的表单。FormView:处理表单显示和处理。
示例:ListView
Section titled “示例:ListView”from django.views.generic import ListViewfrom .models import Post
class PostListView(ListView): model = Post template_name = 'myapp/post_list.html' # 默认值: <app>/<model>_list.html context_object_name = 'posts' # 默认值: object_list paginate_by = 10 # 可选: 添加分页from django.urls import pathfrom .views import PostListView
urlpatterns = [ path('posts/', PostListView.as_view(), name='post_list'),]<h1>文章列表</h1><ul>{% for post in posts %} <li><a href="{{ post.get_absolute_url }}">{{ post.title }}</a></li>{% empty %} <li>暂无文章。</li>{% endfor %}</ul><!-- 如果使用 paginate_by,添加分页控制 -->--- 表单处理 ---
Section titled “--- 表单处理 ---”Django 的表单库处理表单渲染、验证和数据清洗。
创建 Forms(forms.py):
Section titled “创建 Forms(forms.py):”from django import forms
class ContactForm(forms.Form): name = forms.CharField(max_length=100) email = forms.EmailField() message = forms.CharField(widget=forms.Textarea)在 Views 中使用 Forms(views.py):
Section titled “在 Views 中使用 Forms(views.py):”from django.shortcuts import render, redirectfrom .forms import ContactForm
def contact_view(request): if request.method == 'POST': form = ContactForm(request.POST) if form.is_valid(): # 处理 form.cleaned_data 中的数据 name = form.cleaned_data['name'] email = form.cleaned_data['email'] # ... 发送邮件、保存到数据库等 return redirect('success_page') # POST 后重定向 else: # GET form = ContactForm() return render(request, 'myapp/contact.html', {'form': form})在 Templates 中渲染 Forms:
Section titled “在 Templates 中渲染 Forms:”<form method="post"> {% csrf_token %} <!-- 对于安全性至关重要 --> {{ form.as_p }} <!-- 将字段渲染在 <p> 标签中 --> <button type="submit">发送</button></form>form.is_valid() 运行验证。错误可通过 form.errors、form.field_name.errors、form.non_field_errors 访问。通过表单类中的 clean_fieldname() 或 clean() 方法进行自定义验证。
--- 文件上传 ---
Section titled “--- 文件上传 ---”处理用户上传的文件。
- 安装 Pillow:
pip install Pillow(用于ImageField)。 - 在
settings.py中配置MEDIA_ROOT(文件存储的文件系统路径)和MEDIA_URL(服务这些文件的 URL 前缀)。 - 配置 URL 模式以在开发期间提供媒体文件(参见 Django 文档)。
Model:
Section titled “Model:”class UserProfile(models.Model): user = models.OneToOneField('auth.User', on_delete=models.CASCADE) avatar = models.ImageField(upload_to='avatars/', blank=True, null=True) # 对于非图像文件使用 FileFieldclass ProfileForm(forms.ModelForm): class Meta: model = UserProfile fields = ['avatar'] # 或者在 forms.Form 中使用 forms.ImageFielddef upload_avatar(request): if request.method == 'POST': # 将 request.FILES 传递给表单! form = ProfileForm(request.POST, request.FILES, instance=request.user.userprofile) if form.is_valid(): form.save() return redirect('profile_view') else: form = ProfileForm(instance=request.user.userprofile) return render(request, 'myapp/upload.html', {'form': form})Template:
Section titled “Template:”<!-- 重要:为文件上传添加 enctype --><form method="post" enctype="multipart/form-data"> {% csrf_token %} {{ form.as_p }} <button type="submit">上传</button></form>--- Apache 设置(部署)---
Section titled “--- Apache 设置(部署)---”使用 Apache 部署 Django 通常使用 mod_wsgi。
安装并启用 Apache 服务器和 mod_wsgi。
Apache 配置(httpd.conf 或虚拟主机文件):
Section titled “Apache 配置(httpd.conf 或虚拟主机文件):”# mod_wsgi 配置示例WSGIScriptAlias / /path/to/your/myproject/myproject/wsgi.pyWSGIPythonHome /path/to/your/virtualenvWSGIPythonPath /path/to/your/myproject
<Directory /path/to/your/myproject/myproject><Files wsgi.py> Require all granted</Files></Directory>
# 静态文件别名(由 Apache 处理)Alias /static/ /path/to/your/project/staticfiles/<Directory /path/to/your/project/staticfiles> Require all granted</Directory>
# 媒体文件别名(由 Apache 处理)Alias /media/ /path/to/your/project/mediafiles/<Directory /path/to/your/project/mediafiles> Require all granted</Directory>注意:
- 将路径替换为您实际的项目/虚拟环境路径。
- 确保
settings.py中的DEBUG = False。 - 在
settings.py中配置ALLOWED_HOSTS。 - 运行
python manage.py collectstatic将静态文件收集到STATIC_ROOT指定的目录中(该目录应与上面/path/to/your/project/staticfiles/匹配)。
现代替代方案:
Section titled “现代替代方案:”一种非常常见的生产环境设置是使用 Gunicorn(或 uWSGI)作为应用程序服务器运行 Django,并在其前面使用 Nginx 作为反向代理。Nginx 处理传入请求,直接提供静态/媒体文件,并将动态请求转发给 Gunicorn。这种设置通常被认为性能更优且更灵活。
--- Cookie 处理 ---
Section titled “--- Cookie 处理 ---”Cookie 在客户端浏览器上存储少量数据。
设置 Cookies:
Section titled “设置 Cookies:”Cookies 在 HttpResponse 对象上设置。
from django.shortcuts import renderimport datetime
def set_cookie_view(request): response = render(request, 'myapp/cookie_set.html') response.set_cookie( 'username', 'testuser', max_age=3600, # 1 小时后过期 # expires=datetime.datetime.utcnow() + datetime.timedelta(days=7), # 7 天后过期(指定具体时间) # httponly=True, # 推荐:JavaScript 无法访问 # secure=True, # 推荐:仅通过 HTTPS 发送 # samesite='Lax' # 推荐:CSRF 保护 ) return response读取 Cookies:
Section titled “读取 Cookies:”从 HttpRequest 对象的 COOKIES 字典中读取 Cookies。
def read_cookie_view(request): username = request.COOKIES.get('username', 'Guest') # 使用 .get() 获取默认值 return render(request, 'myapp/cookie_read.html', {'username': username})删除 Cookies:
Section titled “删除 Cookies:”def delete_cookie_view(request): response = render(request, 'myapp/cookie_deleted.html') response.delete_cookie('username') return response注意:Cookies 是客户端的,用户可以修改。请勿将敏感信息直接存储在 Cookies 中。请改用 Django Sessions。
--- Sessions ---
Section titled “--- Sessions ---”Sessions 允许在服务器端存储数据,这些数据与存储在客户端 Cookie 中的唯一会话 ID 相关联。对于用户数据而言,比普通 Cookie 更安全。
- 确保
django.contrib.sessions在INSTALLED_APPS中。 - 确保
django.contrib.sessions.middleware.SessionMiddleware在MIDDLEWARE中(通常默认包含)。 - 运行
python manage.py migrate(如果使用基于数据库的 Session,这是默认设置)。
SESSION_ENGINE 设置控制存储方式(数据库、缓存数据库、文件、签名 Cookie)。
在 Views 中使用 Sessions:
Section titled “在 Views 中使用 Sessions:”通过 request.session 字典访问 Session 数据。
def session_example_view(request): # 设置 Session 值 request.session['favorite_color'] = 'blue'
# 获取 Session 值 fav_color = request.session.get('favorite_color', 'unknown')
# 检查键是否存在 if 'user_id' in request.session: user_id = request.session['user_id']
# 删除 Session 值 if 'temp_data' in request.session: del request.session['temp_data']
# 清空整个 Session(如果使用认证系统,这将导致用户注销) # request.session.flush()
# 设置 Session 过期时间(例如,30 分钟不活动) # request.session.set_expiry(1800)
return render(request, 'myapp/session_info.html', {'color': fav_color})Session 在被修改时会自动保存。
--- 缓存 (Caching) ---
Section titled “--- 缓存 (Caching) ---”Caching 存储耗时操作的结果,以提高性能。
设置(settings.py):
Section titled “设置(settings.py):”配置 CACHES 设置。
CACHES = { 'default': { # 'default' 是标准别名 # Memcached(推荐用于生产环境) 'BACKEND': 'django.core.cache.backends.memcached.PyMemcacheCache', 'LOCATION': '127.0.0.1:11211', # 或者使用 Redis(需要 django-redis 包) # 'BACKEND': 'django_redis.cache.RedisCache', # 'LOCATION': 'redis://127.0.0.1:6379/1', # 或者数据库缓存 # 'BACKEND': 'django.core.cache.backends.db.DatabaseCache', # 'LOCATION': 'my_cache_table', # 运行 createcachetable 命令 # 或者文件系统缓存 # 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', # 'LOCATION': '/var/tmp/django_cache', # 或者本地内存缓存(进程内,主要用于开发) # 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', # 'LOCATION': 'unique-snowflake', }}- 站点级: 在
MIDDLEWARE中使用UpdateCacheMiddleware和FetchFromCacheMiddleware。 - 视图级: 在 View 函数上使用
@cache_page(timeout_seconds)装饰器,或在urls.py中包装 View。 - 模板片段级: 在模板中使用
{% load cache %}和{% cache timeout_seconds fragment_name %} ... {% endcache %}。 - 低级 API: 在代码中直接使用
django.core.cache.cache.set('key', value, timeout)和cache.get('key')。
示例:视图级缓存
from django.views.decorators.cache import cache_page
@cache_page(60 * 15) # 缓存 15 分钟def expensive_view(request): # ... 执行耗时的计算 ... return render(request, 'myapp/results.html', context)--- 评论 ---
Section titled “--- 评论 ---”注意: 内置的 django.contrib.comments 框架已从 Django 1.8 版本开始从核心移除,并且已废弃。请勿在新项目中使用它。
现代替代方案:
Section titled “现代替代方案:”- 第三方 Django 应用: 在 PyPI 上搜索维护中的评论应用,如
django-comments-xtd,它构建在旧框架的概念之上。 - 外部服务: 使用 JavaScript 片段集成托管的评论平台,如 Disqus 或 Commento。
概念方法(如果自行构建):
Section titled “概念方法(如果自行构建):”您通常会创建一个 Comment 模型,包含 user(指向 User 的 ForeignKey)、content(TextField)、timestamp(DateTimeField)等字段,以及一个重要的 GenericForeignKey,用于将评论链接到任何其他模型实例(例如,一篇博客文章、一个产品等)。然后,您需要创建表单和视图来处理评论提交和显示。
由于该框架已废弃,此处省略了旧框架的详细实现步骤。
--- RSS Feed ---
Section titled “--- RSS Feed ---”使用 django.contrib.syndication 生成 RSS 或 Atom Feed。
创建 Feed 类(feeds.py):
Section titled “创建 Feed 类(feeds.py):”from django.contrib.syndication.views import Feedfrom django.urls import reversefrom .models import Post # 假设有一个 Post 模型
class LatestPostsFeed(Feed): title = "我的博客文章" link = "/blog/" description = "我博客的最新更新。"
def items(self): return Post.objects.order_by('-published_date')[:5]
def item_title(self, item): return item.title
def item_description(self, item): return item.content # 或摘要字段
# 如果模型有 get_absolute_url,则 item_link 是可选的 def item_link(self, item): return reverse('post_detail', args=[item.pk])映射 URL(urls.py):
Section titled “映射 URL(urls.py):”from django.urls import pathfrom .feeds import LatestPostsFeed
urlpatterns = [ # ... 其他 urls path('latest/feed/', LatestPostsFeed(), name='post_feed'),]访问 Feed URL(例如,/myapp/latest/feed/)将生成 XML Feed。
--- Ajax ---
Section titled “--- Ajax ---”AJAX(Asynchronous JavaScript and XML)允许网页动态更新内容,无需完全重新加载页面,通常通过在后台与服务器通信实现。
Django 中的现代 AJAX 通常涉及:
- 前端 JavaScript: 使用浏览器的
fetchAPI、Axios 等库,或框架(React、Vue、Angular)向 Django 后端发出异步 HTTP 请求(GET、POST 等)。 - Django 后端 View: 一个常规的 Django View,它接收 AJAX 请求,进行处理(例如,查询数据库、验证数据),并返回数据,通常使用
django.http.JsonResponse返回 JSON 格式。 - URL Endpoint:
urls.py中的一个 URL 模式,映射到处理 AJAX 请求的 Django View。 - CSRF 处理: 确保通过 JavaScript 发送的 POST/PUT/DELETE 请求中包含 CSRF token。
注意: 以前版本中提到的旧库,如 django-dajaxice,通常不推荐使用或不再维护。请专注于标准前端 JS 和后端 JSON 响应。
简单示例:点赞按钮
Section titled “简单示例:点赞按钮”- 模板 (
like_button.html):
<button id="like-btn" data-post-id="{{ post.id }}" data-url="{% url 'like_post' %}"> 赞 ({{ post.like_count }})</button>
<script> const likeBtn = document.getElementById('like-btn'); const postId = likeBtn.dataset.postId; const url = likeBtn.dataset.url; const csrftoken = getCookie('csrftoken'); // 获取 CSRF cookie 值的方法
likeBtn.addEventListener('click', () => { fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': csrftoken }, body: JSON.stringify({ post_id: postId }) }) .then(response => response.json()) .then(data => { if (data.success) { likeBtn.textContent = `赞 (${data.new_count})`; // 可能更新按钮样式 } else { alert('点赞文章出错: ' + data.error); } }) .catch(error => console.error('错误:', error)); });
// 获取 CSRF cookie 的简单方法(更稳健的版本请参阅 Django 文档) function getCookie(name) { let cookieValue = null; if (document.cookie && document.cookie !== '') { const cookies = document.cookie.split(';'); for (let i = 0; i < cookies.length; i++) { const cookie = cookies[i].trim(); if (cookie.substring(0, name.length + 1) === (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; }</script>- View (
views.py):
import jsonfrom django.http import JsonResponsefrom django.views.decorators.http import require_POSTfrom django.shortcuts import get_object_or_404from .models import Post
@require_POST # 确保此视图仅接受 POST 请求def like_post_view(request): try: data = json.loads(request.body) post_id = data.get('post_id') post = get_object_or_404(Post, pk=post_id)
# 添加逻辑以增加点赞计数(考虑原子性) post.like_count += 1 post.save(update_fields=['like_count'])
return JsonResponse({'success': True, 'new_count': post.like_count}) except Exception as e: return JsonResponse({'success': False, 'error': str(e)}, status=400)- URL (
urls.py):
from django.urls import pathfrom . import views
urlpatterns = [ # ... 其他 urls path('like_post/', views.like_post_view, name='like_post'),]对于复杂的 API,请考虑使用 Django REST Framework (DRF),它提供了 Serializer、ViewSet 和 Router 来构建健壮的 REST API。