1. Django项目创建全流程指南
作为Python生态中最受欢迎的Web框架之一,Django以其"开箱即用"的特性深受开发者喜爱。我在过去五年里用Django开发过电商平台、内容管理系统和API服务,今天就来分享从零开始创建Django项目的完整流程,包含那些官方文档里不会告诉你的实战细节。
1.1 环境准备要点
在开始之前,我们需要确保开发环境配置正确。我强烈建议使用Python 3.8及以上版本,这是目前大多数生产环境采用的稳定版本。以下是具体步骤:
bash复制# 检查Python版本
python --version
# 如果没有安装pip,需要先安装
python -m ensurepip --upgrade
创建虚拟环境是必须的——我见过太多人因为跳过这一步导致依赖冲突。使用venv模块创建隔离环境:
bash复制python -m venv myenv
source myenv/bin/activate # Linux/Mac
myenv\Scripts\activate # Windows
注意:有些Linux发行版需要单独安装python3-venv包。如果遇到错误,先运行
sudo apt install python3-venv
1.2 Django安装的版本选择
安装Django时,新手常犯的错误是直接pip install django而不指定版本。对于新项目,我推荐使用LTS(长期支持)版本:
bash复制pip install django==4.2.3 # 当前最新的LTS版本
如果想尝试最新特性,可以使用pip install django --pre,但要注意生产环境可能存在兼容性问题。安装后验证:
bash复制python -m django --version
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 项目创建核心步骤
2.1 初始化项目结构
使用django-admin startproject命令创建项目骨架:
bash复制django-admin startproject myproject
这会产生如下目录结构:
code复制myproject/
manage.py
myproject/
__init__.py
settings.py
urls.py
asgi.py
wsgi.py
我习惯在项目根目录下额外创建这些目录,方便后续管理:
code复制mkdir -p myproject/{apps,static,templates,media}
2.2 关键配置文件解析
打开settings.py,这几个配置项需要特别注意:
python复制# 安全配置
SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY') # 不要直接硬编码
DEBUG = False # 开发时可设为True,上线必须改为False
ALLOWED_HOSTS = ['*'] # 生产环境要指定具体域名
# 数据库配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# 静态文件配置
STATIC_URL = 'static/'
STATICFILES_DIRS = [BASE_DIR / "static"] # 开发环境静态文件目录
STATIC_ROOT = BASE_DIR / "staticfiles" # 生产环境收集静态文件目录
经验:使用python-decouple或django-environ管理敏感配置,不要直接写在settings.py中
3. 应用(App)创建与管理
3.1 创建第一个应用
Django项目由多个应用组成,每个应用处理特定功能。创建应用命令:
bash复制python manage.py startapp blog
建议的应用目录结构:
code复制blog/
migrations/
__init__.py
admin.py
apps.py
models.py
tests.py
views.py
urls.py # 需要手动创建
templates/ # 手动创建
blog/
base.html
post_list.html
3.2 注册应用到项目
在settings.py的INSTALLED_APPS中添加:
python复制INSTALLED_APPS = [
...
'blog.apps.BlogConfig', # 推荐使用这种完整路径方式
]
4. 数据库与模型配置
4.1 模型定义最佳实践
在models.py中定义数据模型时,我遵循这些原则:
python复制from django.db import models
from django.urls import reverse
class Post(models.Model):
title = models.CharField(max_length=200, verbose_name="标题")
content = models.TextField(verbose_name="内容")
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
ordering = ['-created_at']
verbose_name = "博客文章"
verbose_name_plural = verbose_name
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post_detail', args=[str(self.id)])
4.2 数据库迁移
定义模型后,需要生成并应用迁移:
bash复制python manage.py makemigrations
python manage.py migrate
常见问题:如果修改模型后迁移失败,可以尝试:
- 删除迁移文件(除了__init__.py)
- 删除数据库
- 重新运行makemigrations和migrate
5. 视图与URL配置
5.1 基于类的视图实现
现代Django推荐使用类视图(CBV),比函数视图更结构化:
python复制# blog/views.py
from django.views.generic import ListView, DetailView
from .models import Post
class PostListView(ListView):
model = Post
template_name = 'blog/post_list.html'
context_object_name = 'posts'
paginate_by = 10
class PostDetailView(DetailView):
model = Post
template_name = 'blog/post_detail.html'
5.2 URL路由配置
项目级URLs (myproject/urls.py):
python复制from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls')),
]
应用级URLs (blog/urls.py):
python复制from django.urls import path
from .views import PostListView, PostDetailView
urlpatterns = [
path('', PostListView.as_view(), name='post_list'),
path('<int:pk>/', PostDetailView.as_view(), name='post_detail'),
]
6. 模板系统实战技巧
6.1 基础模板架构
创建templates/base.html作为基础模板:
html复制<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}My Site{% endblock %}</title>
{% block css %}{% endblock %}
</head>
<body>
<header>
<nav><!-- 导航栏内容 --></nav>
</header>
<main>
{% block content %}{% endblock %}
</main>
<footer><!-- 页脚内容 --></footer>
{% block js %}{% endblock %}
</body>
</html>
6.2 模板继承与包含
子模板 (blog/templates/blog/post_list.html):
html复制{% extends "base.html" %}
{% block title %}博客列表{% endblock %}
{% block content %}
<h1>最新文章</h1>
<ul>
{% for post in posts %}
<li>
<a href="{{ post.get_absolute_url }}">{{ post.title }}</a>
<span>{{ post.created_at|date:"Y-m-d" }}</span>
</li>
{% endfor %}
</ul>
{% endblock %}
7. 管理后台定制
7.1 注册模型到Admin
在blog/admin.py中:
python复制from django.contrib import admin
from .models import Post
@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
list_display = ('title', 'created_at', 'updated_at')
list_filter = ('created_at',)
search_fields = ('title', 'content')
prepopulated_fields = {'slug': ('title',)}
7.2 创建超级用户
bash复制python manage.py createsuperuser
访问/admin即可使用功能完善的后台管理系统。
8. 开发服务器与调试
8.1 启动开发服务器
bash复制python manage.py runserver
默认运行在127.0.0.1:8000,可以指定IP和端口:
bash复制python manage.py runserver 0.0.0.0:8000
8.2 调试工具栏配置
安装django-debug-toolbar:
bash复制pip install django-debug-toolbar
配置settings.py:
python复制INSTALLED_APPS = [
# ...
'debug_toolbar',
]
MIDDLEWARE = [
# ...
'debug_toolbar.middleware.DebugToolbarMiddleware',
]
INTERNAL_IPS = ['127.0.0.1']
配置URLs:
python复制from django.urls import include, path
urlpatterns = [
# ...
path('__debug__/', include('debug_toolbar.urls')),
]
9. 生产环境部署准备
9.1 安全配置检查
生产环境必须修改这些设置:
python复制# settings.py
DEBUG = False
ALLOWED_HOSTS = ['yourdomain.com', 'www.yourdomain.com']
CSRF_COOKIE_SECURE = True
SESSION_COOKIE_SECURE = True
SECURE_SSL_REDIRECT = True
9.2 静态文件收集
bash复制python manage.py collectstatic
9.3 选择WSGI服务器
常见选择:
- Gunicorn + Nginx (推荐)
- uWSGI + Nginx
- Apache + mod_wsgi
Gunicorn基本用法:
bash复制pip install gunicorn
gunicorn myproject.wsgi:application --bind 0.0.0.0:8000
10. 项目结构优化建议
经过多个项目实践,我总结出这样的项目结构最便于维护:
code复制myproject/
apps/ # 所有应用放在这里
blog/
users/
config/ # 拆分settings.py为多个文件
__init__.py
base.py
development.py
production.py
static/
css/
js/
images/
templates/
base/
base.html
header.html
footer.html
blog/
media/
requirements/ # 拆分依赖文件
base.txt
development.txt
production.txt
manage.py
.env # 环境变量
.gitignore
这种结构特别适合中大型项目,可以通过修改manage.py和wsgi.py来加载不同的配置:
python复制# manage.py
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
# 开发时可以这样运行:
# export DJANGO_SETTINGS_MODULE=config.development
11. 常见问题解决方案
11.1 数据库连接问题
症状:django.db.utils.OperationalError: could not connect to server
解决方案:
- 检查数据库服务是否运行
- 验证settings.py中的数据库配置
- 确保有正确的访问权限
- 对于PostgreSQL,可能需要安装psycopg2-binary
bash复制pip install psycopg2-binary
11.2 静态文件404错误
症状:生产环境静态文件无法加载
解决方案:
- 确保运行了
collectstatic - 检查Nginx/Apache配置是否正确指向STATIC_ROOT
- 确认STATIC_URL和STATIC_ROOT设置正确
11.3 迁移冲突
症状:django.db.migrations.exceptions.InconsistentMigrationHistory
解决方案:
- 删除所有迁移文件(保留__init__.py)
- 删除数据库
- 重新创建数据库
- 重新生成和应用迁移
bash复制find . -path "*/migrations/*.py" -not -name "__init__.py" -delete
find . -path "*/migrations/*.pyc" -delete
rm db.sqlite3
python manage.py makemigrations
python manage.py migrate
12. 性能优化技巧
12.1 数据库查询优化
使用select_related和prefetch_related减少查询次数:
python复制# 不好的写法
posts = Post.objects.all()
for post in posts:
print(post.author.name) # 每次循环都查询author
# 好的写法
posts = Post.objects.select_related('author').all()
12.2 缓存策略
启用缓存能显著提升性能:
python复制# settings.py
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.redis.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379/1',
}
}
# 视图缓存示例
from django.views.decorators.cache import cache_page
@cache_page(60 * 15) # 缓存15分钟
def my_view(request):
...
12.3 异步任务
对于耗时操作,使用Celery异步处理:
python复制# tasks.py
from celery import shared_task
@shared_task
def send_email_task(email_data):
# 发送邮件逻辑
pass
# 视图中调用
send_email_task.delay(email_data)
13. 测试策略
13.1 单元测试编写
Django内置测试框架,示例测试用例:
python复制from django.test import TestCase
from django.urls import reverse
from .models import Post
class PostModelTest(TestCase):
@classmethod
def setUpTestData(cls):
Post.objects.create(title='Test title', content='Test content')
def test_title_content(self):
post = Post.objects.get(id=1)
self.assertEqual(post.title, 'Test title')
self.assertEqual(post.content, 'Test content')
class PostViewTest(TestCase):
def test_view_url_exists(self):
response = self.client.get('/blog/')
self.assertEqual(response.status_code, 200)
def test_view_uses_correct_template(self):
response = self.client.get(reverse('post_list'))
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'blog/post_list.html')
13.2 测试覆盖率
使用pytest-django和coverage.py:
bash复制pip install pytest pytest-django coverage
创建.coveragerc文件:
ini复制[run]
source = .
omit = */migrations/*,*/tests/*
[report]
show_missing = True
运行测试:
bash复制coverage run -m pytest
coverage report
coverage html # 生成HTML报告
14. 持续集成配置
14.1 GitHub Actions示例
创建.github/workflows/django.yml:
yaml复制name: Django CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:13
env:
POSTGRES_PASSWORD: postgres
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.9'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run tests
env:
DATABASE_URL: postgres://postgres:postgres@localhost:5432/postgres
DJANGO_SECRET_KEY: ${{ secrets.DJANGO_SECRET_KEY }}
run: |
python manage.py test
15. 项目文档编写
15.1 使用MkDocs
安装配置:
bash复制pip install mkdocs mkdocs-material
mkdocs new docs
编辑mkdocs.yml:
yaml复制site_name: My Project Docs
theme:
name: material
features:
- navigation.tabs
- navigation.top
- search.highlight
- search.suggest
nav:
- 首页: index.md
- 安装指南: installation.md
- API参考: api.md
- 开发指南: development.md
启动文档服务器:
bash复制mkdocs serve
16. 第三方包推荐
16.1 开发必备
django-debug-toolbar- 调试工具django-extensions- 扩展命令集ipython- 更好的shell体验black- 代码格式化flake8- 代码风格检查
16.2 生产推荐
gunicorn- WSGI服务器whitenoise- 静态文件服务django-crispy-forms- 表单美化django-allauth- 认证系统django-filter- 过滤功能django-rest-framework- API开发
17. 项目升级策略
17.1 版本升级步骤
- 在开发环境测试升级
- 阅读发布说明和破坏性变更
- 更新requirements.txt
- 运行测试套件
- 检查弃用警告
- 部署到预生产环境
- 监控生产环境
17.2 数据库迁移策略
对于大型项目,采用这些策略减少停机时间:
- 先向后兼容的迁移
- 分阶段部署
- 使用--plan检查迁移
- 备份数据库
- 在低峰期执行迁移
18. 安全最佳实践
18.1 必须配置项
python复制# settings.py
SECURE_HSTS_SECONDS = 31536000 # 1年
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
SECURE_CONTENT_TYPE_NOSNIFF = True
X_FRAME_OPTIONS = 'DENY'
SECURE_BROWSER_XSS_FILTER = True
CSRF_COOKIE_HTTPONLY = True
18.2 定期安全审计
- 运行
python manage.py check --deploy - 使用
safety check检查依赖漏洞 - 监控Django安全公告
- 更新依赖项
19. 性能监控
19.1 使用Sentry
安装配置:
bash复制pip install sentry-sdk
在settings.py中:
python复制import sentry_sdk
from sentry_sdk.integrations.django import DjangoIntegration
sentry_sdk.init(
dsn="YOUR_DSN",
integrations=[DjangoIntegration()],
traces_sample_rate=1.0,
send_default_pii=True
)
19.2 日志配置
python复制LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'file': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': '/var/log/django/debug.log',
},
'mail_admins': {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler',
}
},
'loggers': {
'django': {
'handlers': ['file'],
'level': 'DEBUG',
'propagate': True,
},
},
}
20. 项目模板化
20.1 使用Cookiecutter
安装和使用Django Cookiecutter模板:
bash复制pip install cookiecutter
cookiecutter https://github.com/pydanny/cookiecutter-django
20.2 自定义项目模板
- 创建模板项目结构
- 添加必要的配置文件
- 创建cookiecutter.json
- 发布到GitHub
- 使用模板生成新项目
json复制{
"project_name": "My Project",
"project_slug": "{{ cookiecutter.project_name.lower().replace(' ', '_') }}",
"author_name": "Your Name",
"description": "A short description of the project.",
"python_version": "3.9",
"django_version": "4.2"
}
在实际项目中,我发现遵循这些实践可以节省大量开发时间,特别是在团队协作时。每个项目都有其独特性,但良好的基础配置和结构设计能让后续开发事半功倍。
