Django项目开发全链路:数据库操作、多环境配置、windows/linux项目部署一站式指南
夸克资源分享:
表情包:https://pan.quark.cn/s/5b9ddeb237fe
工具箱:https://pan.quark.cn/s/aa2d6a730482,图吧、美蛋、路遥、入梦等
Fiddler Everywhere抓包:https://pan.quark.cn/s/6b1e2fbae019,
Adobe:https://pan.quark.cn/s/13e39cfeaadb,先看安装教程
JetBranis开发者工具:https://pan.quark.cn/s/16e94dcff1f7,先看安装教程下的jetbra教程
逆向工具:https://pan.quark.cn/s/50e93c8ca54c
前端项目搭建集锦:https://blog.youkuaiyun.com/randy521520/article/details/146998467
UV教程:Python多版本管理神器
Django数据库配置:Django多数据库配置:mysql、mongo、redis、达梦
DRF教程:django rest framework:从零开始搭建RESTful API
一、项目初始化
1.运行uv add django 安装依赖,未使用uv管理工具可使用pip install django安装,uv教程:https://blog.youkuaiyun.com/randy521520/article/details/147001879

2.运行django-admin startproject demo创建项目

3.项目新建后的目录大致如下

manage.py: 一个命令行实用程序,可让您与此交互 Django项目以各种方式。
mysite/: 一个目录,它是实际Python包 项目。它的名称是您需要用于导入的Python包名称里面的任何东西 (例如mysite.urls)。
mysite/__init__.py: 一个空文件,它告诉Python这个目录应该被认为是一个Python包。
mysite/settings.py: 此Django的设置/配置项目。 Django设置会告诉你所有关于如何设置 工作。
mysite/urls.py: 此Django项目的URL声明; Django驱动的网站的 “目录”。
mysite/asgi.py: ASGI兼容的web服务器的入口点 为你的项目服务。
mysite/wsgi.py: 兼容WSGI的web服务器的入口点 为你的项目服务。
4.修改demo下的urls.py

5.cd项目目录demo,运行uv run python manage.py runserver 6002启动服务,未使用uv管理工具可使用 python manage.py runserver 6002,访问:http://127.0.0.1:6002/,将管理后台登录页面,django官网地址:https://docs.djangoproject.com/en/5.2/

6.manage.py 相关命令如下
| 命令分类 | 命令名称 | 功能描述 | 常用度 |
|---|---|---|---|
| 项目与应用管理 | startproject | 创建新的 Django 项目 | ⭐⭐⭐⭐⭐ |
| startapp | 在当前项目中创建一个新的应用 | ⭐⭐⭐⭐⭐ | |
| 开发服务器 | runserver | 启动开发服务器,默认运行在 127.0.0.1:8000 | ⭐⭐⭐⭐⭐ |
| 数据库操作 | makemigrations | 根据模型变更创建新的数据库迁移文件 | ⭐⭐⭐⭐⭐ |
| migrate | 应用数据库迁移,使模型与数据库同步 | ⭐⭐⭐⭐⭐ | |
| flush | 清空数据库中的所有数据,但不删除表 | ⭐⭐⭐⭐ | |
| dbshell | 启动数据库命令行工具 | ⭐⭐⭐ | |
| 数据导入导出 | dumpdata | 将数据库中的数据导出为 JSON 或 YAML 格式 | ⭐⭐⭐⭐ |
| loaddata | 从 Fixture 文件(如 JSON)中加载数据到数据库 | ⭐⭐⭐⭐ | |
| 用户与权限管理 | createsuperuser | 创建超级用户,用于访问 Django 管理后台 | ⭐⭐⭐⭐⭐ |
| changepassword | 更改指定用户的密码 | ⭐⭐⭐ | |
| 测试与检查 | test | 运行项目的测试套件 | ⭐⭐⭐⭐⭐ |
| check | 检查 Django 项目的设置和配置是否存在问题 | ⭐⭐⭐⭐⭐ | |
| 迁移管理 | showmigrations | 显示所有应用的迁移历史和状态 | ⭐⭐⭐⭐ |
| sqlmigrate | 生成指定迁移文件对应的 SQL 语句 | ⭐⭐⭐ | |
| squashmigrations | 将多个迁移文件压缩成一个 | ⭐ | |
| 静态文件管理 | collectstatic | 收集所有静态文件到 STATIC_ROOT 目录,用于生产环境部署 | ⭐⭐⭐⭐⭐ |
| findstatic | 查找静态文件的绝对路径 | ⭐ | |
| 会话管理 | clearsessions | 删除过期的会话数据 | ⭐ |
| 国际化 | compilemessages | 编译多语言翻译文件 | ⭐ |
| 缓存 | createcachetable | 创建缓存表,用于数据库缓存 | ⭐ |
| 信息查看 | showurls | 显示项目的所有 URL 配置 | ⭐⭐⭐ |
| diffsettings | 显示当前设置与 Django 默认设置之间的差异 | ⭐ |
二、创建第一个应用
1.cd项目目录demo,运行uv run python manage.py startapp school新建应用,未使用uv管理工具可使用python manage.py startapp school

2.应用新建后的目录大致如下

__init__.py - 包标识文件
admin.py - 管理员后台配置
apps.py - 应用配置
migrations/ - 数据库迁移目录
models.py - 数据模型定义
tests.py - 测试文件
views.py - 视图函数/类
'''''可选但常用的额外文件'''''
urls.py - URL路由配置
forms.py - 表单定义
serializers.py - DRF序列化器
managers.py - 自定义模型管理器
templates/ - HTML模板目录
static/ - 静态文件目录(CSS, JS, 图片)

3.修改demo中的settings.pym,在INSTALLED_APPS中加入school

4.修改school>views.py文件

5.新增school>urls.py文件

6.修改demo下的urls.py文件

7.此时访问http://127.0.0.1:6002/school/,就可以看到欢迎光临页面

三、数据库与数据模型的应用
1.修改demo下的settings.py,配置mysql数据库,name为连接的数据库名,需要确保该数据库已创建

2.安装pymysql,并修改demo下的__init__.py,作用是让pymysql 库伪装成 MySQLdb 库,以便在 Django 等框架中使用

3.修改school>models.py,创建一些学校公共的数据模型,如:班级、课程等
from django.contrib.auth.models import User
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from django.utils import timezone
class Class(models.Model):
"""
班级模型
字段说明:
- name: 班级名称,从预定义的年级名称中选择,具有唯一性
- class_code: 班级代码,对应年级编号,具有唯一性
- department: 班级类型,区分理科班、文科班等不同类型
- max_students: 最大学生数,限制班级容量在1-100人之间
- established_date: 成立日期,记录班级成立时间
- graduation_date: 预计毕业日期,可为空的毕业时间预估
- is_active: 是否活跃,标识班级当前状态
- head_teacher: 班主任,外键关联到用户模型,可为空
- created_at: 创建时间,自动记录数据创建时间
- updated_at: 更新时间,自动记录最后修改时间
- description: 班级描述,可选的详细说明文本
预定义数据:
- class_info: 包含1-8年级的详细信息字典
- name_choices: 基于class_info生成的班级名称选项
- class_code_choices: 基于class_info生成的班级代码选项
- department_choices: 班级类型选项列表
"""
class_info = {
'1':{
'name': '一年级',
'description': '一年级 - 小学起始阶段,6-7岁'
},
'2':{
'name': '二年级',
'description': '二年级 - 小学基础阶段,7-8岁'
},
'3':{
'name': '三年级',
'description': '三年级 - 小学巩固阶段,8-9岁'
},
'4':{
'name': '四年级',
'description': '四年级 - 小学提高阶段,9-10岁'
},
'5':{
'name': '五年级',
'description': '五年级 - 小学进阶阶段,10-11岁'
},
'6':{
'name': '六年级',
'description': '六年级 - 小学毕业阶段,11-12岁'
},
'7':{
'name': '七年级',
'description': '七年级 - 初中起始阶段(初一),12-13岁'
},
'8':{
'name': '八年级',
'description': '八年级 - 初中中间阶段(初二),13-14岁'
}
}
# 基本信息
name_choices = [(v['name'], v['description']) for k, v in class_info.items()]
name = models.CharField(
max_length=100, choices=name_choices,verbose_name='班级名称',unique=True,
db_comment='\n'.join([f'{
name}:{
description}' for name, description in name_choices])
)
class_code_choices = [(k, v['name']) for k, v in class_info.items()]
class_code = models.CharField(
max_length=20, choices=class_code_choices, verbose_name='班级代码', unique=True,
db_comment='\n'.join([f'{
code}:{
name}' for code, name in class_code_choices])
)
department_choices = [
('science', '理科班'),
('arts', '文科班'),
('commercial', '商科班'),
('general', '普通班'),
('experimental', '实验班'),
('international', '国际班'),
]
department = models.CharField(
max_length=20, choices=department_choices, verbose_name='班级类型',
db_comment='\n'.join([f'{
code}:{
dep}' for code, dep in department_choices])
)
# 容量限制
max_students = models.PositiveIntegerField(
default=50,
validators=[MinValueValidator(1), MaxValueValidator(100)],
verbose_name='最大学生数',
db_comment='最大学生数:1-100人'
)
# 时间信息
established_date = models.DateField(verbose_name='成立日期')
graduation_date = models.DateField(verbose_name='预计毕业日期', null=True, blank=True)
is_active = models.BooleanField(default=True, verbose_name='是否活跃',db_default=True)
# 教师关系
head_teacher = models.ForeignKey(
User,
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name='headed_classes',
verbose_name='班主任'
)
# 元数据
created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')
description = models.TextField(verbose_name='班级描述', blank=True)
class Meta:
verbose_name = '班级'
verbose_name_plural = '班级管理'
ordering = ['class_code', 'name']
indexes = [
models.Index(fields=['class_code', 'department']),
models.Index(fields=['is_active']),
]
class Course(models.Model):
"""
课程模型
"""
course_info = {
'1':{
'name': '语文',
'description': '语文课程'
},
'2':{
'name': '数学',
'description': '数学课程'
},
'3':{
'name': '英语',
'description': '英语课程'
},
'4':{
'name': '物理',
'description': '物理课程'
},
'5':{
'name': '化学',
'description': '化学课程'
},
'6':{
'name': '生物',
'description': '生物课程'
},
'7':{
'name': '历史',
'description': '历史课程'
},
'8':{
'name': '地理',
'description': '地理课程'
},
'9':{
'name': '政治',
'description': '政治课程'
},
'10':{
'name': '音乐',
'description': '音乐课程'
},
'11':{
'name': '美术',
'description': '美术课程'
},
'12':{
'name': '体育',
'description': '体育课程'
},
'13':{
'name': '信息技术',
'description': '信息技术课程'
},
'14':{
'name': '综合',
'description': '综合课程'
}
}
# 基本信息
name_choices = [(v['name'], v['description']) for k, v in course_info.items()]
name = models.CharField(
max_length=100, verbose_name='课程名称', choices=name_choices,
db_comment='\n'.join([f'{
name}:{
description}' for name, description in name_choices])
)
course_code_choices = [(k, v['name']) for k, v in course_info.items()]
course_code = models.CharField(
max_length=20, unique=True, verbose_name='课程代码', choices=course_code_choices,
db_comment='\n'.join([f'{
code}:{
name}' for code, name in course_code_choices])
)
description = models.TextField(verbose_name='课程描述', blank=True)
# 学术信息
course_type_choices = [
('required', '必修课'),
('elective', '选修课'),
('practice', '实践课'),
('experiment', '实验课'),
('seminar', '研讨课'),
]
course_type = models.CharField(max_length=20, choices=course_type_choices, verbose_name='课程类型')
# 学分和学时
credits = models.PositiveIntegerField(
default=2,
validators=[MinValueValidator(1), MaxValueValidator(10)],
verbose_name='学分'
)
total_hours = models.PositiveIntegerField(
default=36,
validators=[MinValueValidator(1), MaxValueValidator(200)],
verbose_name='总学时'
)
# 班级关联
target_classes = models.ManyToManyField(
Class,
related_name='courses',
blank=True,
verbose_name='开设班级',
help_text='选择这门课程面向的班级'
)
# 时间信息
start_date = models.DateField(verbose_name='开课日期', default=timezone.now)
end_date = models.DateField(verbose_name='结课日期', null=True, blank=True)
is_active = models.BooleanField(default=True, verbose_name='是否开课')
# 课程安排
CLASS_SCHEDULE_CHOICES = [
('mon1', '周一第1节'),
('mon2', '周一第2节'),
('mon3', '周一第3节'),
('mon4', '周一第4节'),
('tue1', '周二第1节'),
('tue2', '周二第2节'),
('tue3', '周二第3节'),
('tue4', '周二第4节'),
('wed1', '周三第1节'),
('wed2', '周三第2节'),
('wed3', '周三第3节'),
('wed4', '周三第4节'),
('thu1', '周四第1节'),
('thu2', '周四第2节'),
('thu3', '周四第3节'),
('thu4', '周四第4节'),
('fri1', '周五第1节'),
('fri2', '周五第2节'),
('fri3', '周五第3节'),
('fri4', '周五第4节'),
]
schedule = models.CharField(
max_length=10,
choices=CLASS_SCHEDULE_CHOICES,
verbose_name='上课时间'
)
classroom = models.CharField(max_length=50, verbose_name='教室', blank=True)
# 元数据
created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
verbose_name = '课程'
verbose_name_plural = '课程管理'
ordering = ['course_code', 'name']
indexes = [
models.Index(fields=['course_code', 'course_type']),
models.Index(fields=['is_active'])
]
class CourseMaterial(models.Model):
"""课程资料模型"""
course = models.ForeignKey(
Course,
on_delete=models.CASCADE,
related_name='materials',
verbose_name='所属课程'
)
title = models.CharField(max_length=200, verbose_name='资料标题')
description = models.TextField(verbose_name='资料描述', blank=True)
file = models.FileField(
upload_to='course_materials/%Y/%m/%d/',
verbose_name='资料文件'
)
upload_date = models.DateTimeField(auto_now_add=

最低0.47元/天 解锁文章
4821

被折叠的 条评论
为什么被折叠?



