1. Django开发环境准备与项目创建
1.1 环境检查与版本确认
在开始任何Django项目前,环境配置是首要工作。我习惯使用以下命令确认核心组件版本:
bash复制python -m django --version
这个命令会输出当前安装的Django版本。根据我的经验,版本兼容性问题经常是新手遇到的第一个坑。比如Django 6.0需要Python 3.12或更高版本,如果环境不匹配会导致各种奇怪的错误。
提示:建议使用虚拟环境隔离项目依赖。我常用python -m venv venv创建虚拟环境,再通过source venv/bin/activate激活(Linux/Mac)或venv\Scripts\activate(Windows)。
1.2 项目初始化实战
创建Django项目的标准命令是:
bash复制django-admin startproject mysite
但我在实际项目中更推荐带目录的创建方式:
bash复制django-admin startproject mysite djangotutorial
这种写法会在djangotutorial目录下创建项目,保持工作区整洁。项目结构通常包含:
- manage.py:项目管理脚本
- mysite/settings.py:核心配置文件
- mysite/urls.py:主路由文件
启动开发服务器的命令很简单:
bash复制python manage.py runserver
但有个细节需要注意:默认只监听127.0.0.1,如果需要局域网访问,应该使用:
bash复制python manage.py runserver 0.0.0.0:8000
2. 应用开发与视图编写
2.1 创建投票应用
Django采用"项目+应用"的架构设计。创建应用的命令是:
bash复制python manage.py startapp polls
这会在当前目录生成polls应用的基本结构:
- migrations/:数据库迁移文件
- admin.py:管理后台配置
- apps.py:应用配置
- models.py:数据模型
- tests.py:测试用例
- views.py:视图函数
2.2 编写第一个视图
视图是Django处理请求的核心组件。在polls/views.py中:
python复制from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world. You're at the polls index.")
这个简单视图返回一个HTTP响应。但要让Django能找到这个视图,需要配置URL路由:
- 在polls目录下创建urls.py
- 添加路由配置:
python复制from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
]
- 在项目级的mysite/urls.py中包含应用路由:
python复制from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('polls/', include('polls.urls')),
path('admin/', admin.site.urls),
]
经验:使用include()可以让应用保持独立性,便于复用和团队协作。
3. 数据库配置与模型设计
3.1 数据库初始化
Django默认使用SQLite数据库,初始化命令是:
bash复制python manage.py migrate
这个命令会创建必要的系统表。如果需要使用MySQL/PostgreSQL等数据库,需要:
- 修改settings.py中的DATABASES配置
- 安装对应数据库适配器(如pip install mysqlclient)
3.2 设计投票模型
在polls/models.py中定义数据模型:
python复制from django.db import models
import datetime
from django.utils import timezone
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
def __str__(self):
return self.question_text
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
def __str__(self):
return self.choice_text
关键点说明:
- 每个模型继承models.Model
- CharField需要指定max_length
- ForeignKey定义一对多关系
- __str__方法定义对象显示方式
- 可以添加自定义方法(如was_published_recently)
3.3 激活模型并生成迁移
- 在settings.py的INSTALLED_APPS中添加应用:
python复制INSTALLED_APPS = [
'polls.apps.PollsConfig',
...
]
- 生成迁移文件:
bash复制python manage.py makemigrations polls
- 查看SQL语句(可选):
bash复制python manage.py sqlmigrate polls 0001
- 应用迁移:
bash复制python manage.py migrate
注意:每次修改模型后都需要重新生成和应用迁移。我习惯在开发时使用python manage.py showmigrations查看迁移状态。
4. Django Shell与模型API
4.1 使用Django Shell
交互式shell是调试和探索API的好工具:
bash复制python manage.py shell
相比普通Python shell,它会自动加载Django环境。
4.2 常用模型操作示例
python复制from polls.models import Question, Choice
from django.utils import timezone
# 创建问题
q = Question(question_text="What's new?", pub_date=timezone.now())
q.save()
# 查询所有问题
Question.objects.all()
# 条件查询
Question.objects.filter(id=1)
# 创建选项
q.choice_set.create(choice_text="Not much", votes=0)
# 关联查询
q.choice_set.all()
技巧:在shell中使用IPython(pip install ipython)可以获得更好的交互体验,包括tab补全和语法高亮。
5. 管理后台配置
5.1 创建超级用户
bash复制python manage.py createsuperuser
按提示输入用户名、邮箱和密码即可。
5.2 注册模型到后台
在polls/admin.py中:
python复制from django.contrib import admin
from .models import Question, Choice
admin.site.register(Question)
admin.site.register(Choice)
启动开发服务器后,访问http://127.0.0.1:8000/admin/即可登录管理后台。
5.3 自定义后台显示
更专业的做法是自定义ModelAdmin:
python复制from django.contrib import admin
from .models import Question
class QuestionAdmin(admin.ModelAdmin):
list_display = ('question_text', 'pub_date', 'was_published_recently')
list_filter = ['pub_date']
search_fields = ['question_text']
admin.site.register(Question, QuestionAdmin)
这样可以在列表页看到更多信息,并支持过滤和搜索。
6. 常见问题与解决方案
6.1 数据库连接问题
错误现象:OperationalError: unable to open database file
解决方法:
- 确保项目目录有写权限
- 检查settings.py中DATABASES配置
- 如果是MySQL/PostgreSQL,确认服务已启动
6.2 静态文件404
错误现象:CSS/JS文件加载失败
解决方法:
- 确保DEBUG=True
- 在settings.py中配置STATIC_URL
- 开发阶段使用python manage.py collectstatic
6.3 迁移冲突
错误现象:Migration conflicts
解决方法:
- 删除迁移目录下所有文件(除__init__.py)
- 删除数据库中的django_migrations表相关记录
- 重新生成和应用迁移
7. 开发经验分享
7.1 项目结构优化
我习惯的项目结构:
code复制project/
├── apps/ # 自定义应用
├── static/ # 静态资源
├── templates/ # 全局模板
└── config/ # 配置文件(重命名mysite)
通过修改manage.py和wsgi.py中的默认路径实现。
7.2 调试技巧
- 使用django-debug-toolbar:
bash复制pip install django-debug-toolbar
- 在settings.py和urls.py中配置后,可以查看SQL查询、请求头等详细信息。
7.3 性能优化
- 使用select_related/prefetch_related减少查询次数
- 对高频访问视图添加缓存
- 使用django-extensions的RunProfileServer分析性能瓶颈
python复制# 不好的写法:N+1查询问题
for question in Question.objects.all():
print(question.choice_set.all())
# 好的写法:使用prefetch_related
for question in Question.objects.prefetch_related('choice_set').all():
print(question.choice_set.all())
8. 测试驱动开发
8.1 编写测试用例
在polls/tests.py中:
python复制from django.test import TestCase
from django.utils import timezone
from .models import Question
class QuestionModelTests(TestCase):
def test_was_published_recently(self):
"""
测试was_published_recently()方法
"""
time = timezone.now() + datetime.timedelta(days=30)
future_question = Question(pub_date=time)
self.assertIs(future_question.was_published_recently(), False)
8.2 运行测试
bash复制python manage.py test polls
Django会自动:
- 创建测试数据库
- 查找所有tests.py文件
- 执行TestCase子类中的测试方法
- 输出测试结果
8.3 客户端测试
python复制from django.urls import reverse
def test_index_view(self):
response = self.client.get(reverse('polls:index'))
self.assertEqual(response.status_code, 200)
self.assertContains(response, "Hello, world")
9. 部署准备
9.1 生产环境设置
关键配置修改:
python复制DEBUG = False
ALLOWED_HOSTS = ['yourdomain.com']
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
9.2 常用部署方案
- Nginx + Gunicorn:
bash复制pip install gunicorn
gunicorn mysite.wsgi:application
- Docker部署:
dockerfile复制FROM python:3.12
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["gunicorn", "mysite.wsgi:application", "--bind", "0.0.0.0:8000"]
9.3 安全建议
- 定期更新依赖
- 使用环境变量存储敏感信息
- 配置CSRF和XSS防护
- 限制管理后台访问IP
10. 项目扩展思路
10.1 添加用户认证
Django内置了完善的auth系统:
python复制from django.contrib.auth.decorators import login_required
@login_required
def my_view(request):
...
10.2 REST API开发
使用Django REST framework:
bash复制pip install djangorestframework
python复制from rest_framework import serializers, viewsets
from .models import Question
class QuestionSerializer(serializers.ModelSerializer):
class Meta:
model = Question
fields = '__all__'
class QuestionViewSet(viewsets.ModelViewSet):
queryset = Question.objects.all()
serializer_class = QuestionSerializer
10.3 异步任务
使用Celery处理耗时任务:
python复制@app.task
def send_email():
# 发送邮件逻辑
pass
在实际项目中,我通常会根据需求逐步引入这些扩展功能,而不是一开始就全部配置。保持项目简洁可维护才是最重要的。