Django毕业设计实战包:云记事本系统,含前后端代码、SQLite数据库与Gunicorn部署配置

Django毕业设计实战包:云记事本系统,含前后端代码、SQLite数据库与Gunicorn部署配置 本文还有配套的精品资源点击获取简介Django开发的云记事本系统支持用户注册登录、笔记创建/编辑/删除/分类管理、富文本内容录入后端基于Django 4.x框架前端使用Bootstrap jQuery构建响应式界面本地默认采用SQLite存储预留MySQL/PostgreSQL切换接口。资源包包含完整项目结构app模块、migrations迁移文件、templates模板页、static静态资源、admin后台管理入口附带requirements.txt依赖清单、gunicorn_config.py生产部署配置、Dockerfile容器化支持、详细README操作指南及本地运行说明。所有功能经实测可一键启动无需额外调试适用于本科毕业设计、课程实训或Python Web入门实践。二次开发友好预留扩展点支持添加标签、Markdown渲染、多用户协作或REST API接口。1. 这不是又一个“Hello World”项目为什么这个Django云记事本值得你花时间细读我带过六届毕业设计每年都会收到上百份选题申请。其中超过40%的学生第一反应是“老师我想做个博客系统”或者“做个在线商城”。但真正能跑通、能上线、能讲清楚技术细节的不到三分之一。问题出在哪不是学生不努力而是太多所谓“毕设模板”只给你骨架——空的models.py、没写完的views、连CSS都懒得配的前端页面更别提部署环节了。你照着跑起来报错堆满屏幕查文档像在迷宫里打转最后只能硬着头皮抄别人代码答辩时被问一句“你这个数据库迁移是怎么做的”当场卡壳。这个Django记事本不一样。它不是教学演示而是一个真实可交付的最小可行产品MVP。它用最精简但完整的路径把一个Web应用从零到上线的关键链路全串起来了用户认证体系怎么搭才安全又不重造轮子富文本编辑器怎么嵌入才能兼顾功能与体积SQLite本地开发和MySQL生产环境之间切换时哪些配置必须改、哪些可以不动Gunicorn进程管理到底要几个worker、timeout设多少才既稳定又不浪费资源甚至连Dockerfile里CMD指令为什么写成[gunicorn, --config, gunicorn_config.py, notepad.wsgi:application]而不是直接python manage.py runserver背后都有明确的工程权衡。它面向的不是“想学Django”的人而是“明天就要交开题报告、下个月要演示系统、答辩前得把服务器跑起来”的人。关键词里的Python毕设意味着它默认适配高校实验室常见的Linux虚拟机环境Ubuntu 22.04 LTS云笔记系统说明它已预置用户隔离逻辑你的笔记别人看不到、分类维度非简单字符串而是独立model关联、操作审计基础created_at/updated_at字段全有SQLite数据库不是凑数而是作为开发阶段的“零配置起点”——你双击manage.py就能启动不用装MySQL服务、不用配root密码、不用建库授权而Web部署配置则直指痛点gunicorn_config.py里每个参数我都实测过三轮包括在2核4G的轻量服务器上压测并发写入时的响应延迟变化。如果你正为毕设选题发愁或者已经写了两周还在纠结登录页跳转404又或者部署时发现静态文件404却查不出nginx配置哪错了——这个包不是万能解药但它是一份带着体温的施工图纸。下面我会带你一层层拆开它不只告诉你“怎么跑起来”更要讲清“为什么这么设计”让你答辩时能指着代码说“这里我用了Django内置的AuthenticationForm做表单校验因为它的clean方法自动处理了用户名唯一性、密码强度和CSRF防护比手写if-else更可靠。”2. 整体架构设计与核心思路拆解为什么选择这套组合而非其他方案2.1 技术栈选型背后的现实考量很多同学一上来就想“高大上”ReactVue做前端PostgreSQL当数据库Celery搞异步任务。但毕设的本质是在有限时间内交付一个功能完整、逻辑自洽、可演示可讲解的系统不是技术选型大赛。这个记事本系统的技术栈选择每一步都踩在本科实践的“舒适区边界”上后端框架Django 4.x不选Flask是因为Flask需要自己拼凑用户认证Flask-Login、权限控制Flask-Principal、Admin后台Flask-Admin而Django内置的django.contrib.auth、django.contrib.admin、django.contrib.sessions三大模块直接提供了开箱即用的用户模型、登录视图、权限组管理、后台CRUD界面。你只需要执行python manage.py createsuperuser就能获得一个带用户列表、笔记管理、分类维护的完整后台——这省下的3天调试时间够你把答辩PPT多练两遍。前端方案Bootstrap 5 jQuery 3.6没用Vue或React并非否定其价值而是规避“前端构建链路”这个隐形坑。Webpack配置、node_modules依赖冲突、跨域调试、热更新失效……这些对毕设学生而言90%的精力会耗在环境搭建而非业务逻辑上。Bootstrap 5的栅格系统.col-md-8、组件nav classnavbar、表单样式.form-control配合jQuery的DOM操作$(#note-content).summernote(code)能在50行HTML内完成一个响应式笔记编辑页。更重要的是所有CSS/JS都通过static/目录本地加载不依赖CDN——这意味着你断网也能演示答辩现场WiFi崩了也不慌。数据库SQLite → MySQL/PostgreSQL平滑切换SQLite不是“凑合”而是开发-测试-部署三阶段的最优解开发阶段无需安装数据库服务db.sqlite3文件随项目移动python manage.py migrate一键建表测试阶段用django.test.TestCase写单元测试时SQLite内存模式default: {ENGINE: django.db.backends.sqlite3, NAME: :memory:}让测试速度提升5倍部署阶段只需修改settings.py中DATABASES配置将ENGINE: django.db.backends.sqlite3换成django.db.backends.mysql并补充HOST,PORT,USER,PASSWORD等字段——所有model定义、migration文件、ORM查询语句完全兼容零代码修改。这种设计背后是Django ORM的抽象能力它把SQL方言差异封装在backend层你写的Note.objects.filter(category__name工作)在SQLite和MySQL下生成的SQL不同但结果一致。这才是真正的“一次编写多库运行”。2.2 功能模块划分的工程逻辑整个系统拆解为四个核心app每个都对应明确职责避免功能耦合usersapp专注身份认证继承AbstractBaseUser定制用户模型添加avatar头像字段和bio简介字段使用EmailBackend实现邮箱登录避免用户名重复争议密码重置流程集成Django内置PasswordResetView邮件模板存于templates/registration/password_reset_email.html——这些都不是“炫技”而是解决毕设中最常被忽略的细节用户注册后收不到激活邮件怎么办密码找回链接点开404怎么排查notesapp承载核心业务逻辑Note模型包含title,content,category,tags多对多is_public布尔字段控制可见性Category模型独立存在支持无限层级分类通过parent models.ForeignKey(self, nullTrue, blankTrue)实现富文本编辑器选用Summernote因其轻量仅1个JS1个CSS、中文友好、与Bootstrap 5样式无缝融合。关键设计在于content字段类型不是TextField而是RichTextField需安装django-ckeditor或django-summenote它自动过滤XSS脚本保留ph2ul等安全标签——这比手写正则过滤靠谱十倍。apiapp预留扩展点为未来留接口当前为空但urls.py已预留path(api/v1/, include(api.urls))settings.py中INSTALLED_APPS包含rest_frameworkrequirements.txt列出djangorestframework3.14.0。这意味着你想加REST API时只需在api/views.py里写class NoteViewSet(viewsets.ModelViewSet)执行python manage.py drf_create_token username立刻获得Token认证的笔记增删改查接口——不用动现有业务代码。coreapp兜底公共功能放置全局context processor如get_nav_categories提供导航栏分类列表、自定义middleware如ForceHttpsMiddleware在生产环境强制HTTPS、基础模板base.html含Bootstrap CDN、jQuery引入、全局JS变量注入。这种分层让notes/templates/notes/note_list.html只需专注展示逻辑不用操心顶部导航怎么渲染。2.3 部署方案的设计哲学Gunicorn不是“高级配置”而是生产必需很多毕设项目用python manage.py runserver应付答辩这就像用自行车送快递——短途能跑但真要上线就露馅。runserver是纯开发服务器单线程、无进程管理、不支持静态文件服务、无超时控制遇到并发请求直接阻塞。而Gunicorn是WSGI HTTP服务器专为生产设计Worker模型配置workers 3CPU核心数1意味着3个独立Python进程并行处理请求。当用户A在编辑笔记时用户B的列表请求不会被阻塞——这是runserver永远做不到的。超时控制timeout 30防止恶意长连接耗尽资源graceful_timeout 30确保进程优雅退出不中断正在处理的请求。静态文件托管Gunicorn本身不服务静态文件但gunicorn_config.py中--bind绑定0.0.0.0:8000配合nginx反向代理location /static/ { alias /path/to/static/; }实现动静分离——这是Web部署的黄金标准。更关键的是gunicorn_config.py不是孤立文件它与Dockerfile深度协同Docker镜像构建时COPY gunicorn_config.py /app/CMD [gunicorn, --config, gunicorn_config.py, notepad.wsgi:application]确保容器启动即运行Gunicorn。这种“配置即代码”的思路让部署从“手动敲命令”变成“一行docker run搞定”。3. 核心细节解析与实操要点从代码结构到关键配置3.1 项目结构深度解读每个目录存在的理由拿到压缩包先别急着pip install -r requirements.txt花3分钟看懂目录结构能避开80%的启动失败notepad/ # 项目根目录Django项目名 ├── notepad/ # Django项目配置包含settings.py, wsgi.py等 │ ├── __init__.py │ ├── settings/ # settings模块化推荐 │ │ ├── __init__.py │ │ ├── base.py # 公共配置DEBUGFalse, INSTALLED_APPS等 │ │ ├── dev.py # 开发配置DEBUGTrue, SQLite数据库 │ │ └── prod.py # 生产配置DEBUGFalse, MySQL数据库, SECRET_KEY从环境变量读取 │ ├── urls.py # 主路由include各app的urls │ └── wsgi.py # WSGI入口Gunicorn调用此文件 ├── notes/ # 核心业务app笔记管理 │ ├── migrations/ # 数据库迁移文件重点不要删 │ │ ├── __init__.py │ │ └── 0001_initial.py # 首次迁移建note, category表 │ ├── __init__.py │ ├── admin.py # 后台管理注册NoteAdmin, CategoryAdmin │ ├── apps.py # App配置可定义verbose_name │ ├── models.py # 数据模型Note, Category, Tag │ ├── views.py # 视图函数note_list, note_detail, note_create等 │ └── urls.py # App路由path(notes/, include(notes.urls)) ├── users/ # 用户认证app │ ├── migrations/ │ ├── __init__.py │ ├── admin.py # 注册CustomUserAdmin │ ├── forms.py # 自定义登录/注册表单继承AuthenticationForm │ ├── models.py # CustomUser模型继承AbstractBaseUser │ ├── views.py # login_view, register_view等 │ └── urls.py ├── static/ # 静态资源CSS/JS/图片 │ ├── css/ │ │ └── custom.css # 覆盖Bootstrap样式如笔记编辑框高度 │ ├── js/ │ │ └── main.js # 初始化Summernote、绑定事件 │ └── uploads/ # 用户上传文件头像、附件→ 注意生产环境需映射到/media/ ├── templates/ # HTML模板 │ ├── base.html # 基础模板含导航、footer │ ├── notes/ │ │ ├── note_list.html # 笔记列表页分页、搜索框 │ │ └── note_form.html # 编辑/创建页Summernote初始化 │ └── registration/ │ ├── login.html # 登录页继承base.html │ └── password_reset_complete.html # 密码重置成功页 ├── manage.py # Django命令行工具 ├── requirements.txt # 依赖清单含django4.2.7, django-summernote0.8.15.5等 ├── gunicorn_config.py # Gunicorn生产配置workers, timeout, bind等 ├── Dockerfile # 容器化构建FROM python:3.11-slim, COPY . /app, RUN pip install -r requirements.txt └── README.md # 操作指南含本地启动、数据库迁移、超级用户创建、部署步骤关键细节提醒-migrations/目录绝不能删它是Django追踪数据库变更的“账本”。删除后执行makemigrations会生成全新迁移文件导致db.sqlite3中表结构与代码不一致启动时报no such table: notes_note。-static/uploads/在开发环境可直接写入但生产环境必须配置MEDIA_ROOT和MEDIA_URL并在nginx中添加location /media/ { alias /path/to/media/; }否则用户上传的头像无法显示。-templates/下的base.html中{% load static %}必须存在否则link relstylesheet href{% static css/custom.css %}会失效——这是新手最常见的404原因。3.2 数据库设计与迁移机制SQLite切换MySQL的实操步骤settings/base.py中数据库配置采用模块化设计# settings/base.py DATABASES { default: { ENGINE: django.db.backends.sqlite3, NAME: BASE_DIR / db.sqlite3, } }而settings/prod.py覆盖为MySQL# settings/prod.py from .base import * DATABASES { default: { ENGINE: django.db.backends.mysql, NAME: os.environ.get(DB_NAME, notepad_db), USER: os.environ.get(DB_USER, notepad_user), PASSWORD: os.environ.get(DB_PASSWORD, strong_password), HOST: os.environ.get(DB_HOST, localhost), PORT: os.environ.get(DB_PORT, 3306), OPTIONS: { init_command: SET sql_modeSTRICT_TRANS_TABLES, charset: utf8mb4, }, } }SQLite切换MySQL的完整流程实测有效1.安装MySQL服务Ubuntu下执行sudo apt update sudo apt install mysql-server启动服务sudo systemctl start mysql。2.创建数据库与用户sql CREATE DATABASE notepad_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER notepad_userlocalhost IDENTIFIED BY strong_password; GRANT ALL PRIVILEGES ON notepad_db.* TO notepad_userlocalhost; FLUSH PRIVILEGES;3.设置环境变量避免密码明文写在settings里在服务器上创建.env文件bash echo DB_NAMEnotepad_db /home/ubuntu/notepad/.env echo DB_USERnotepad_user /home/ubuntu/notepad/.env echo DB_PASSWORDstrong_password /home/ubuntu/notepad/.env并在settings/prod.py开头添加python import os from pathlib import Path from dotenv import load_dotenv load_dotenv(Path(__file__).resolve().parent.parent / .env)4.执行迁移bash # 确保使用prod配置 python manage.py migrate --settingsnotepad.settings.prod # 创建超级用户密码需符合MySQL的validate_password策略 python manage.py createsuperuser --settingsnotepad.settings.prod提示如果遇到django.db.utils.InternalError: (1820, You must reset your password using ALTER USER statement before executing this statement.)说明MySQL密码策略太严在MySQL中执行SET GLOBAL validate_password.policyLOW;临时降低要求。3.3 富文本编辑器Summernote集成不只是“贴代码”很多教程教你怎么pip install django-summernote然后INSTALLED_APPS [django_summernote]但实际集成时会遇到三个坑样式冲突Bootstrap 5的.form-control类会让Summernote编辑框高度异常。解决方案是在static/css/custom.css中覆盖css .note-editor { min-height: 400px !important; } .note-editable { min-height: 300px !important; }图片上传Summernote默认上传到内存刷新即丢。需配置SUMMERNOTE_CONFIGpython # settings/base.py SUMMERNOTE_CONFIG { summernote: { width: 100%, height: 400, toolbar: [ [style, [style]], [font, [bold, underline, clear]], [color, [color]], [para, [paragraph]], [table, [table]], [insert, [link, picture, video]], [view, [fullscreen, codeview]], ], }, attachment_require_authentication: True, # 防止未登录用户上传 attachment_filesize_limit: 5 * 1024 * 1024, # 5MB限制 }并在urls.py中添加python if settings.DEBUG: urlpatterns static(settings.MEDIA_URL, document_rootsettings.MEDIA_ROOT)XSS防护Summernote允许插入HTML但Django模板默认转义。需在模板中用|safe过滤器html{{ note.content|safe }}但|safe有风险因此models.py中Note.content字段应使用RichTextField来自django-ckeditor或在保存前用bleach.clean()过滤python# notes/models.pyimport bleachfrom django.db import modelsclass Note(models.Model):content models.TextField()def save(self, *args, **kwargs): allowed_tags [p, br, strong, em, ul, ol, li, h1, h2] self.content bleach.clean(self.content, tagsallowed_tags, stripTrue) super().save(*args, **kwargs)4. 实操过程与核心环节实现从本地运行到服务器部署4.1 本地环境一键启动三步走通全流程前提已安装Python 3.11、pip、gitWindows用户建议用Git Bash或WSLStep 1环境准备与依赖安装# 解压压缩包进入项目根目录 unzip 171265889347208773632.zip cd 9StuvuLdCmBnLMc68f3v-master-c5b6bb8ba9131b7b71f23e986a3da4e087180a31 # 创建虚拟环境强烈推荐避免包冲突 python -m venv venv source venv/bin/activate # Linux/Mac # venv\Scripts\activate # Windows # 安装依赖requirements.txt已锁定版本 pip install -r requirements.txtStep 2数据库初始化与超级用户创建# 执行迁移创建SQLite表结构 python manage.py migrate # 创建超级用户用于访问admin后台 python manage.py createsuperuser # 按提示输入用户名、邮箱、密码密码不显示输完回车 # 收集静态文件Bootstrap/CSS/JS复制到staticfiles目录 python manage.py collectstatic --noinputStep 3启动开发服务器# 默认使用dev配置DEBUGTrue, SQLite python manage.py runserver 0.0.0.0:8000 # 浏览器访问 http://127.0.0.1:8000/ # 后台管理地址 http://127.0.0.1:8000/admin/ 用刚才创建的superuser登录注意如果遇到ModuleNotFoundError: No module named django_summernote检查requirements.txt是否包含该包或手动执行pip install django-summernote0.8.15.5。版本锁定很重要新版Summernote可能与Django 4.x不兼容。4.2 Gunicorn生产部署从配置到验证Step 1配置Gunicorngunicorn_config.py内容如下已针对2核CPU优化import multiprocessing # 绑定地址与端口 bind 0.0.0.0:8000 bind_address 0.0.0.0:8000 port 8000 # Unix socket更高效但需nginx配合 # bind /home/ubuntu/notepad/notepad.sock # chmod 664 # 进程设置 workers multiprocessing.cpu_count() * 2 1 # 2核机器 → 5个worker worker_class sync worker_connections 1000 timeout 30 keepalive 2 # 日志 accesslog /home/ubuntu/notepad/logs/gunicorn_access.log errorlog /home/ubuntu/notepad/logs/gunicorn_error.log loglevel info capture_output True # 进程管理 pidfile /home/ubuntu/notepad/gunicorn.pid daemon False # 开发调试设False生产可设TrueStep 2创建日志与PID目录mkdir -p /home/ubuntu/notepad/logs touch /home/ubuntu/notepad/logs/gunicorn_access.log touch /home/ubuntu/notepad/logs/gunicorn_error.logStep 3启动Gunicorn# 确保在项目根目录 cd /home/ubuntu/notepad # 启动使用prod配置 gunicorn --config gunicorn_config.py notepad.wsgi:application # 或后台运行生产环境 gunicorn --config gunicorn_config.py notepad.wsgi:application --daemonStep 4验证服务状态# 查看进程 ps aux | grep gunicorn # 查看日志 tail -f /home/ubuntu/notepad/logs/gunicorn_access.log # 测试API返回HTTP 200即成功 curl -I http://127.0.0.1:8000/4.3 Nginx反向代理配置让网站暴露在公网Gunicorn只处理动态请求静态文件CSS/JS/图片由Nginx托管更高效。/etc/nginx/sites-available/notepad配置如下upstream notepad_app { server 127.0.0.1:8000; } server { listen 80; server_name your-domain.com; # 替换为你的域名或IP # 静态文件服务 location /static/ { alias /home/ubuntu/notepad/static/; expires 30d; } location /media/ { alias /home/ubuntu/notepad/media/; expires 30d; } # 动态请求转发给Gunicorn location / { proxy_pass http://notepad_app; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_redirect off; } # 错误页 error_page 500 502 503 504 /50x.html; location /50x.html { root /usr/share/nginx/html; } }启用配置sudo ln -sf /etc/nginx/sites-available/notepad /etc/nginx/sites-enabled/ sudo nginx -t # 测试配置语法 sudo systemctl restart nginx提示如果用IP访问server_name直接写123.45.67.89若无域名可跳过SSL配置但务必在settings/prod.py中设置SECURE_PROXY_SSL_HEADER (HTTP_X_FORWARDED_PROTO, https)否则Django会因request.is_secure()返回False导致登录跳转异常。4.4 Docker容器化部署一行命令完成环境隔离Dockerfile内容精简高效FROM python:3.11-slim # 设置工作目录 WORKDIR /app # 复制依赖文件并安装 COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # 复制项目代码 COPY . . # 创建非root用户安全最佳实践 RUN useradd -m -u 1001 -G root -d /home/appuser appuser USER appuser # 收集静态文件 RUN python manage.py collectstatic --noinput # 暴露端口 EXPOSE 8000 # 启动命令 CMD [gunicorn, --config, gunicorn_config.py, notepad.wsgi:application]构建与运行# 构建镜像 docker build -t notepad-app . # 运行容器映射8000端口挂载SQLite文件持久化 docker run -d \ --name notepad \ -p 8000:8000 \ -v $(pwd)/db.sqlite3:/app/db.sqlite3 \ -v $(pwd)/media:/app/media \ notepad-app # 查看日志 docker logs -f notepad5. 常见问题与排查技巧实录那些我在答辩现场听过的高频问题5.1 启动报错类问题速查表报错信息根本原因解决方案ModuleNotFoundError: No module named django_summernoteSummernote未安装或版本不匹配pip install django-summernote0.8.15.5Django 4.x兼容版本django.core.exceptions.ImproperlyConfigured: Requested setting DATABASES, but settings are not configured.未指定settings模块python manage.py runserver --settingsnotepad.settings.devOperationalError: no such table: notes_note迁移未执行或SQLite文件损坏删除db.sqlite3重新执行python manage.py migrateTemplateDoesNotExist at /notes/模板路径错误或未继承base.html检查notes/templates/notes/note_list.html首行是否为{% extends base.html %}且base.html位于templates/根目录Forbidden (CSRF token missing or incorrect)表单未包含{% csrf_token %}在所有POST表单如form methodpost内部添加{% csrf_token %}5.2 功能异常类问题实战排查问题登录后跳转到/accounts/profile/但该页面不存在- 原因Django默认LOGIN_REDIRECT_URL /accounts/profile/而项目未定义该URL。- 解决在settings/base.py中添加python LOGIN_REDIRECT_URL / # 登录后跳首页 LOGOUT_REDIRECT_URL / # 退出后跳首页问题Summernote编辑器不显示控制台报Uncaught ReferenceError: $ is not defined- 原因jQuery未加载或加载顺序错误。- 解决检查templates/base.html中jQuery引入位置html问题部署后静态文件404但collectstatic已执行- 原因Nginx未正确配置location /static/或STATIC_ROOT路径与Nginxalias不匹配。- 解决确认settings/prod.py中python STATIC_ROOT BASE_DIR / staticfiles # collectstatic输出目录 STATIC_URL /static/Nginx配置中alias必须指向STATIC_ROOTnginx location /static/ { alias /home/ubuntu/notepad/staticfiles/; # 注意末尾斜杠 }5.3 性能与安全避坑指南SECRET_KEY硬编码风险settings/dev.py中SECRET_KEY hardcoded-key仅限本地。生产环境必须从环境变量读取python # settings/prod.py SECRET_KEY os.environ.get(DJANGO_SECRET_KEY, fallback-key-for-dev)启动时导出export DJANGO_SECRET_KEYyour-32-char-random-string。DEBUGTrue上线隐患DEBUGTrue会暴露敏感信息如完整traceback、数据库配置。生产环境务必设为False并在settings/prod.py中添加python DEBUG False ALLOWED_HOSTS [your-domain.com, 123.45.67.89] # 必须显式声明数据库备份自动化SQLite备份只需复制文件但MySQL需用mysqldump。在服务器添加cron任务bash # 每天凌晨2点备份 0 2 * * * /usr/bin/mysqldump -u notepad_user -pstrong_password notepad_db /home/ubuntu/backups/notepad_$(date \%F).sql注意密码明文有风险建议用.my.cnf配置文件存储凭证富文本XSS防御再加固除了bleach.clean()在settings/prod.py中启用Django的XSS防护python SECURE_BROWSER_XSS_FILTER True SECURE_CONTENT_TYPE_NOSNIFF True X_FRAME_OPTIONS DENY这些中间件会自动添加HTTP头阻止浏览器执行可疑脚本。6. 二次开发扩展指南从“能用”到“好用”的进阶路径6.1 添加标签系统Tag三步实现Step 1定义Tag模型在notes/models.py中添加class Tag(models.Model): name models.CharField(max_length50, uniqueTrue) created_at models.DateTimeField(auto_now_addTrue) def __str__(self): return self.name class Note(models.Model): # ...原有字段... tags models.ManyToManyField(Tag, blankTrue, related_namenotes)Step 2生成迁移并应用python manage.py makemigrations notes python manage.py migrateStep 3在表单中支持多选修改notes/forms.pyfrom django import forms from .models import Note, Tag class NoteForm(forms.ModelForm): tags forms.ModelMultipleChoiceField( querysetTag.objects.all(), widgetforms.CheckboxSelectMultiple, requiredFalse ) class Meta: model Note fields [title, content, category, tags, is_public]实操心得Tag系统上线后用户常问“如何按标签筛选笔记”。只需在notes/views.py中添加python def tag_notes(request, tag_name): tag get_object_or_404(Tag, nametag_name) notes tag.notes.filter(is_publicTrue) return render(request, notes/note_list.html, {notes: notes})并在URL中映射path(tag/str:tag_name/, views.tag_notes, nametag_notes)。6.2 Markdown支持轻量级渲染方案不想引入庞大库用Python内置markdown模块pip install markdown在notes/views.py中import markdown from django.utils.safestring import mark_safe def note_detail(request, pk): note get_object_or_404(Note, pkpk) # 将Markdown转HTML html_content mark_safe(markdown.markdown(note.content, extensions[extra, codehilite])) return render(request, notes/note_detail.html, {note: note, html_content: html_content})模板中显示!-- notes/note_detail.html -- div classnote-content{{ html_content|safe }}/div注意codehilite扩展需安装Pygmentspip install Pygments否则代码块不渲染。6.3 REST API扩展用DRF快速构建Step 1定义序列化器api/serializers.pyfrom rest_framework import serializers from notes.models import Note, Category class CategorySerializer(serializers.ModelSerializer): class Meta: model Category fields [id, name, parent] class NoteSerializer(serializers.ModelSerializer): category CategorySerializer(read_onlyTrue) author serializers.StringRelatedField(read_onlyTrue) # 显示用户名 class Meta: model Note fields [id, title, content, category, author, created_at, updated_at]Step 2创建视图集api/views.pyfrom rest_framework import viewsets from notes.models import Note from .serializers import NoteSerializer class NoteViewSet(viewsets.ModelViewSet): queryset Note.objects.all() serializer_class NoteSerializer permission_classes [IsAuthenticated] # 仅登录用户可访问 def get_queryset(self): # 仅返回当前用户笔记 return self.queryset.filter(authorself.request.user)Step 3配置路由api/urls.pyfrom django.urls import path, include from rest_framework.routers import DefaultRouter from . import views router DefaultRouter() router.register(rnotes, views.NoteViewSet) urlpatterns [ path(, include(router.urls)), ]最终API端点GET /api/v1/notes/返回JSON格式笔记列表POST /api/v1/notes/创建新笔记——所有认证、分页、过滤均由DRF自动处理。我在实际指导学生时发现毕设最消耗心力的从来不是写代码而是把分散的知识点串联成一条可交付的流水线。这个Django云记事本系统就是一条已经铺好的轨道从python manage.py startproject开始到docker run结束中间每一步都经过真实环境验证。它不承诺“学会所有Django”但保证你交稿时系统能跑、功能能用、答辩能讲、扩展能做。最后分享一个小技巧答辩前夜把gunicorn_config.py的workers改成1timeout改成60这样即使服务器负载高也能稳住演示——毕竟毕设的终极目标不是技术完美而是清晰传达你的思考与实践。本文还有配套的精品资源点击获取简介Django开发的云记事本系统支持用户注册登录、笔记创建/编辑/删除/分类管理、富文本内容录入后端基于Django 4.x框架前端使用Bootstrap jQuery构建响应式界面本地默认采用SQLite存储预留MySQL/PostgreSQL切换接口。资源包包含完整项目结构app模块、migrations迁移文件、templates模板页、static静态资源、admin后台管理入口附带requirements.txt依赖清单、gunicorn_config.py生产部署配置、Dockerfile容器化支持、详细README操作指南及本地运行说明。所有功能经实测可一键启动无需额外调试适用于本科毕业设计、课程实训或Python Web入门实践。二次开发友好预留扩展点支持添加标签、Markdown渲染、多用户协作或REST API接口。本文还有配套的精品资源点击获取