Django基础概念
本章将深入介绍Django的核心概念,包括项目设置、应用配置、中间件系统、信号机制等,帮助你全面理解Django框架的工作原理。
Django项目架构
MVT架构模式
Django采用MVT (Model-View-Template) 架构模式,这是对传统MVC模式的变体:
┌─────────────────────────────────────────────────────────┐
│ Django MVT 架构 │
├─────────────────────────────────────────────────────────┤
│ HTTP请求 → URL路由 → 视图(View) → 模型(Model) │
│ ↓ ↓ │
│ 模板(Template) ← 数据处理 │
│ ↓ │
│ HTTP响应 → 客户端 │
└─────────────────────────────────────────────────────────┘Model (模型):
- 定义数据结构和业务逻辑
- 与数据库交互
- 数据验证和处理
View (视图):
- 处理HTTP请求
- 业务逻辑控制
- 调用模型和模板
Template (模板):
- 表现层逻辑
- HTML生成
- 数据展示
请求-响应流程
python
# 1. URL路由匹配
# urls.py
from django.urls import path
from . import views
urlpatterns = [
path('articles/<int:id>/', views.article_detail, name='article_detail'),
]
# 2. 视图处理请求
# views.py
from django.shortcuts import render, get_object_or_404
from .models import Article
def article_detail(request, id):
article = get_object_or_404(Article, id=id)
return render(request, 'articles/detail.html', {'article': article})
# 3. 模型数据查询
# models.py
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
# 4. 模板渲染
# templates/articles/detail.html
<h1>{{ article.title }}</h1>
<p>{{ article.content }}</p>
<small>发布时间: {{ article.created_at }}</small>Django设置系统
设置文件结构
python
# settings.py 的基本结构
import os
from pathlib import Path
# 项目根目录
BASE_DIR = Path(__file__).resolve().parent.parent
# 核心设置
DEBUG = True
SECRET_KEY = 'your-secret-key'
ALLOWED_HOSTS = []
# 应用程序
INSTALLED_APPS = [
# Django内置应用
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# 第三方应用
'rest_framework',
'debug_toolbar',
# 本地应用
'blog.apps.BlogConfig',
'accounts.apps.AccountsConfig',
]
# 中间件
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
# URL配置
ROOT_URLCONF = 'mysite.urls'
# 数据库
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
```##
# 重要设置详解
#### DEBUG设置
```python
# 开发环境
DEBUG = True
ALLOWED_HOSTS = [] # 空列表表示只允许localhost
# 生产环境
DEBUG = False
ALLOWED_HOSTS = ['yourdomain.com', 'www.yourdomain.com']
# DEBUG=True时的特性
- 详细的错误页面
- 自动重载代码
- 静态文件自动服务
- SQL查询调试信息
# DEBUG=False时的要求
- 必须设置ALLOWED_HOSTS
- 需要配置静态文件服务
- 错误信息被隐藏
- 性能优化启用SECRET_KEY设置
python
# 生成安全的密钥
from django.core.management.utils import get_random_secret_key
SECRET_KEY = get_random_secret_key()
# 从环境变量读取
import os
SECRET_KEY = os.environ.get('SECRET_KEY')
# 使用python-decouple
from decouple import config
SECRET_KEY = config('SECRET_KEY')
# SECRET_KEY的用途
- CSRF令牌生成
- 会话签名
- 密码重置令牌
- 其他加密操作数据库配置
python
# SQLite配置(开发环境)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# PostgreSQL配置(推荐生产环境)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydatabase',
'USER': 'mydatabaseuser',
'PASSWORD': 'mypassword',
'HOST': '127.0.0.1',
'PORT': '5432',
'OPTIONS': {
'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
},
}
}
# MySQL配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mydatabase',
'USER': 'mydatabaseuser',
'PASSWORD': 'mypassword',
'HOST': '127.0.0.1',
'PORT': '3306',
'OPTIONS': {
'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
},
}
}
# 多数据库配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'main_db',
'USER': 'postgres',
'PASSWORD': 'password',
'HOST': 'localhost',
'PORT': '5432',
},
'users_db': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'users_db',
'USER': 'mysql_user',
'PASSWORD': 'mysql_password',
'HOST': 'localhost',
'PORT': '3306',
}
}
# 数据库路由
DATABASE_ROUTERS = ['mysite.routers.DatabaseRouter']应用配置系统
AppConfig类
python
# apps.py
from django.apps import AppConfig
class BlogConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'blog'
verbose_name = '博客管理'
def ready(self):
"""应用准备就绪时调用"""
# 导入信号处理器
import blog.signals
# 执行初始化代码
self.setup_logging()
def setup_logging(self):
"""设置日志配置"""
import logging
logger = logging.getLogger(__name__)
logger.info(f'{self.verbose_name} 应用已加载')应用注册
python
# settings.py
INSTALLED_APPS = [
# 使用AppConfig类
'blog.apps.BlogConfig',
# 或简化形式
'blog',
# 第三方应用
'rest_framework',
'corsheaders',
# Django内置应用
'django.contrib.admin',
'django.contrib.auth',
]应用发现和加载
python
# Django应用加载过程
1. 读取INSTALLED_APPS设置
2. 导入每个应用的AppConfig
3. 调用AppConfig.ready()方法
4. 注册模型、管理命令等
# 检查已安装的应用
from django.apps import apps
# 获取所有应用
all_apps = apps.get_app_configs()
for app in all_apps:
print(f"应用: {app.name}, 标签: {app.label}")
# 获取特定应用
blog_app = apps.get_app_config('blog')
print(f"应用名称: {blog_app.verbose_name}")
# 获取应用的模型
blog_models = blog_app.get_models()
for model in blog_models:
print(f"模型: {model.__name__}")中间件系统
中间件概念
中间件是Django请求/响应处理的钩子框架,它是一个轻量级的插件系统,用于全局改变Django的输入或输出。
python
# 中间件执行顺序
请求阶段(从上到下):
SecurityMiddleware
SessionMiddleware
CommonMiddleware
CsrfViewMiddleware
AuthenticationMiddleware
MessageMiddleware
XFrameOptionsMiddleware
↓
视图处理
↓
响应阶段(从下到上):
XFrameOptionsMiddleware
MessageMiddleware
AuthenticationMiddleware
CsrfViewMiddleware
CommonMiddleware
SessionMiddleware
SecurityMiddleware内置中间件
python
# settings.py
MIDDLEWARE = [
# 安全中间件 - 添加安全相关的HTTP头
'django.middleware.security.SecurityMiddleware',
# 会话中间件 - 启用会话支持
'django.contrib.sessions.middleware.SessionMiddleware',
# 通用中间件 - 处理URL重写、ETags等
'django.middleware.common.CommonMiddleware',
# CSRF保护中间件
'django.middleware.csrf.CsrfViewMiddleware',
# 认证中间件 - 添加user属性到request
'django.contrib.auth.middleware.AuthenticationMiddleware',
# 消息中间件 - 启用消息框架
'django.contrib.messages.middleware.MessageMiddleware',
# 点击劫持保护中间件
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]自定义中间件
python
# middleware.py
import time
import logging
from django.utils.deprecation import MiddlewareMixin
class RequestLoggingMiddleware:
"""请求日志中间件"""
def __init__(self, get_response):
self.get_response = get_response
self.logger = logging.getLogger(__name__)
def __call__(self, request):
# 请求处理前
start_time = time.time()
self.logger.info(f"请求开始: {request.method} {request.path}")
# 调用下一个中间件或视图
response = self.get_response(request)
# 响应处理后
duration = time.time() - start_time
self.logger.info(f"请求完成: {response.status_code} ({duration:.2f}s)")
return response
def process_exception(self, request, exception):
"""处理异常"""
self.logger.error(f"请求异常: {request.path} - {exception}")
return None
class CustomHeaderMiddleware:
"""自定义HTTP头中间件"""
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
# 添加自定义头
response['X-Custom-Header'] = 'MyValue'
response['X-Request-ID'] = getattr(request, 'request_id', 'unknown')
return response
# 基于类的中间件(旧式)
class LegacyMiddleware(MiddlewareMixin):
def process_request(self, request):
"""处理请求"""
request.custom_attribute = 'custom_value'
return None
def process_response(self, request, response):
"""处理响应"""
response['X-Legacy-Header'] = 'legacy_value'
return response中间件配置和使用
python
# settings.py
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'myapp.middleware.RequestLoggingMiddleware', # 自定义中间件
'django.contrib.sessions.middleware.SessionMiddleware',
'myapp.middleware.CustomHeaderMiddleware', # 自定义中间件
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
# 条件性中间件
if DEBUG:
MIDDLEWARE += ['debug_toolbar.middleware.DebugToolbarMiddleware']信号系统
Django信号概念
Django信号是一种调度器,允许解耦的应用程序在框架的其他地方发生操作时得到通知。
python
# 常用的Django信号
from django.db.models.signals import (
pre_save, post_save, # 保存前后
pre_delete, post_delete, # 删除前后
m2m_changed, # 多对多关系变化
)
from django.contrib.auth.signals import (
user_logged_in, # 用户登录
user_logged_out, # 用户登出
user_login_failed, # 登录失败
)
from django.core.signals import (
request_started, # 请求开始
request_finished, # 请求结束
)信号处理器
python
# signals.py
from django.db.models.signals import post_save, pre_delete
from django.contrib.auth.signals import user_logged_in
from django.contrib.auth.models import User
from django.dispatch import receiver
from .models import Profile, Article
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
"""用户创建时自动创建用户资料"""
if created:
Profile.objects.create(user=instance)
print(f"为用户 {instance.username} 创建了资料")
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
"""用户保存时同时保存用户资料"""
if hasattr(instance, 'profile'):
instance.profile.save()
@receiver(user_logged_in)
def log_user_login(sender, request, user, **kwargs):
"""记录用户登录"""
import logging
logger = logging.getLogger(__name__)
logger.info(f"用户 {user.username} 从 {request.META.get('REMOTE_ADDR')} 登录")
@receiver(pre_delete, sender=Article)
def backup_article_before_delete(sender, instance, **kwargs):
"""删除文章前备份"""
import json
backup_data = {
'title': instance.title,
'content': instance.content,
'created_at': instance.created_at.isoformat(),
}
# 保存到备份文件或数据库
with open(f'backup_article_{instance.id}.json', 'w') as f:
json.dump(backup_data, f)
# 手动连接信号(不使用装饰器)
def article_saved_handler(sender, instance, created, **kwargs):
if created:
print(f"新文章创建: {instance.title}")
else:
print(f"文章更新: {instance.title}")
post_save.connect(article_saved_handler, sender=Article)自定义信号
python
# signals.py
import django.dispatch
# 定义自定义信号
article_published = django.dispatch.Signal()
user_profile_updated = django.dispatch.Signal()
# 在模型中发送信号
# models.py
from django.db import models
from .signals import article_published
class Article(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
is_published = models.BooleanField(default=False)
def publish(self):
self.is_published = True
self.save()
# 发送自定义信号
article_published.send(
sender=self.__class__,
instance=self,
user=self.author
)
# 处理自定义信号
@receiver(article_published)
def notify_subscribers(sender, instance, user, **kwargs):
"""文章发布时通知订阅者"""
print(f"文章 '{instance.title}' 已发布,作者: {user}")
# 发送邮件通知、推送消息等日志系统
日志配置
python
# settings.py
import os
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}',
'style': '{',
},
'simple': {
'format': '{levelname} {message}',
'style': '{',
},
},
'filters': {
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
},
},
'handlers': {
'console': {
'level': 'INFO',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'file': {
'level': 'INFO',
'class': 'logging.FileHandler',
'filename': os.path.join(BASE_DIR, 'logs', 'django.log'),
'formatter': 'verbose',
},
'mail_admins': {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler',
'formatter': 'verbose',
}
},
'root': {
'handlers': ['console'],
},
'loggers': {
'django': {
'handlers': ['console', 'file'],
'level': 'INFO',
},
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': True,
},
'myapp': {
'handlers': ['console', 'file'],
'level': 'DEBUG',
'propagate': True,
},
}
}使用日志
python
# views.py
import logging
# 获取日志记录器
logger = logging.getLogger(__name__)
def my_view(request):
logger.debug('这是调试信息')
logger.info('这是信息日志')
logger.warning('这是警告信息')
logger.error('这是错误信息')
logger.critical('这是严重错误')
try:
# 一些可能出错的代码
result = risky_operation()
except Exception as e:
logger.exception('操作失败: %s', e)
raise
return render(request, 'template.html')
# 使用结构化日志
logger.info('用户登录', extra={
'user_id': request.user.id,
'ip_address': request.META.get('REMOTE_ADDR'),
'user_agent': request.META.get('HTTP_USER_AGENT'),
})缓存系统
缓存配置
python
# settings.py
# 内存缓存(开发环境)
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'unique-snowflake',
}
}
# Redis缓存(推荐生产环境)
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.redis.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379/1',
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
}
}
}
# Memcached缓存
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyMemcacheCache',
'LOCATION': '127.0.0.1:11211',
}
}
# 多级缓存
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.redis.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379/1',
},
'sessions': {
'BACKEND': 'django.core.cache.backends.redis.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379/2',
}
}
# 会话缓存
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
SESSION_CACHE_ALIAS = 'sessions'使用缓存
python
# views.py
from django.core.cache import cache
from django.views.decorators.cache import cache_page
from django.utils.decorators import method_decorator
# 手动缓存
def expensive_view(request):
# 尝试从缓存获取
result = cache.get('expensive_calculation')
if result is None:
# 缓存未命中,执行计算
result = perform_expensive_calculation()
# 存储到缓存,过期时间300秒
cache.set('expensive_calculation', result, 300)
return render(request, 'result.html', {'result': result})
# 视图缓存装饰器
@cache_page(60 * 15) # 缓存15分钟
def cached_view(request):
return render(request, 'template.html')
# 类视图缓存
@method_decorator(cache_page(60 * 15), name='dispatch')
class CachedView(View):
def get(self, request):
return render(request, 'template.html')
# 模板片段缓存
# template.html
{% load cache %}
{% cache 500 sidebar request.user.username %}
<!-- 复杂的侧边栏内容 -->
{% endcache %}
# 低级缓存API
from django.core.cache import caches
# 使用特定缓存
cache = caches['sessions']
cache.set('key', 'value', 300)
value = cache.get('key')
# 批量操作
cache.set_many({'a': 1, 'b': 2, 'c': 3}, 300)
values = cache.get_many(['a', 'b', 'c'])
# 原子操作
cache.add('key', 'value', 300) # 只在键不存在时设置
cache.delete('key')
cache.clear() # 清空所有缓存本章小结
本章深入介绍了Django的基础概念和核心系统:
关键要点:
- MVT架构:Model-View-Template设计模式
- 设置系统:项目配置和环境管理
- 应用配置:AppConfig类和应用生命周期
- 中间件系统:请求/响应处理钩子
- 信号系统:解耦的事件通知机制
- 日志系统:结构化日志记录
- 缓存系统:性能优化工具
重要概念:
- Django的请求-响应流程
- 中间件的执行顺序和作用
- 信号的发送和接收机制
- 缓存策略和使用场景
最佳实践:
- 合理组织设置文件
- 正确使用中间件顺序
- 适当使用信号处理业务逻辑
- 配置结构化日志记录
- 选择合适的缓存策略
在下一章中,我们将学习Django的视图和URL配置,了解如何处理HTTP请求和响应。