
简介这是一份面向Python初学者与Django入门开发者的轻量级Web项目实践源码旨在帮助开发者快速掌握Django框架核心流程包括项目结构搭建、URL路由配置、视图渲染、模板使用及基础用户登录功能实现。资源共40个文件含13个关键Python源码如settings.py、urls.py、views.py、models.py等、1个HTML模板页面poem.html、1个SQLite3数据库文件、1个说明文档readme.txt及24个编译缓存pyc文件整体压缩包仅155KB结构精简、无冗余依赖便于本地快速运行与代码溯源。已有480人学习下载适合教学演示、课设参考或自学练手。读者可直接部署运行观察Django MTV模式的实际组织方式理解manage.py驱动逻辑、templates目录的静态渲染机制以及SQLite轻量数据库在小型项目中的集成方法是构建首个可交互Web应用的理想起点。1. 为什么一个“简单 Django Web 项目”反而最容易卡在第三步从django-admin startproject到能跑通首页中间藏着 5 个新手看不见的隐性依赖链你搜“基于Python的简单Django Web项目设计源码”点开十几个 GitHub 仓库clone 下来python manage.py runserver—— 报错ModuleNotFoundError: No module named django装完 Django 又报django.core.exceptions.ImproperlyConfigured: Requested setting DEBUG, but settings are not configured.好不容易配好 settings访问http://127.0.0.1:8000却只看到This page isn’t working或空白页再查日志发现TemplateDoesNotExist at /而你明明把index.html放进了templates/目录……这不是你手残是 Django 的“简单”自带三重幻觉它假装自己是个开箱即用的框架实则每一步都在等你主动补全被它刻意隐藏的契约——路径约定、模块加载顺序、模板上下文传递规则、静态文件服务机制、以及最关键的settings.py 不是配置文件而是 Python 模块执行入口。本文不讲“Django 是什么”只带你用最朴素的 Python 思维把一个能真正在浏览器里显示“Hello, World”的最小可运行项目从零手敲出来、跑通、改出第一个动态页面、并理解每一行代码在底层触发了什么。适合刚学完 Python 基础、想落地第一个 Web 项目的开发者也适合被“Django 项目结构”绕晕的老手找回控制感——我们不用 cookiecutter不抄现成模板就用django-adminvim或 VS Code 终端一砖一瓦垒。2. 从零构建最小可运行项目5 行命令 3 个手动创建的文件就能让 Django 启动并返回 HTMLDjango 的“项目”不是一堆文件的集合而是一个由manage.py驱动的 Python 运行时环境。它的最小闭环必须包含一个可导入的 settings 模块、一个可路由的 URL 配置、一个能响应请求的视图函数、以及一个被正确加载的模板。下面步骤严格按执行顺序展开跳过所有“推荐做法”只保留不可省略的硬性依赖。2.1 创建项目骨架并验证 Python 环境纯净性提示绝对不要在全局 Python 环境中安装 Django。Django 版本与 Python 版本强耦合如 Django 4.2 要求 Python ≥3.8且不同项目可能依赖不同版本。用venv隔离是唯一可靠方案。# 1. 创建独立虚拟环境Python 3.8 python -m venv django_simple_env # 2. 激活环境Linux/macOS source django_simple_env/bin/activate # Windows 用户用django_simple_env\Scripts\activate.bat # 3. 升级 pip 并安装 Django这里固定为 4.2.13稳定且兼容性广 pip install --upgrade pip pip install Django4.2.13 # 4. 验证安装输出应为 4.2.13 python -c import django; print(django.get_version())这四步完成后你拥有了一个干净、可控、可销毁的 Python 运行沙盒。pip list应只看到Django,pip,setuptools三个包。任何额外包如requests、numpy都是干扰项删掉。2.2 用django-admin初始化项目但立刻修改默认结构Django 官方推荐django-admin startproject mysite但它生成的目录嵌套过深mysite/mysite/settings.py对新手理解模块导入路径极其不友好。我们采用扁平化结构更贴近真实工程逻辑# 在当前目录下直接创建项目不嵌套 django-admin startproject config . # 此时目录结构为 # ├── manage.py # └── config/ # ├── __init__.py # ├── asgi.py # ├── settings.py ← 核心配置模块 # ├── urls.py ← 根 URL 路由 # └── wsgi.py关键动作编辑config/settings.py将DEBUG True改为DEBUG True保持但必须添加ALLOWED_HOSTS [127.0.0.1, localhost]。Django 4.0 默认ALLOWED_HOSTS []生产环境强制校验 Host 头本地开发若不显式声明runserver会直接拒绝所有请求HTTP 400 错误无日志提示这是第一大静默坑。2.3 手写第一个视图与 URL 路由绕过startapp的复杂性python manage.py startapp myapp会生成 6 个文件但其中 5 个admin.py,apps.py,tests.py,migrations/对“显示 Hello World”毫无必要。我们手动创建最简视图# 创建 views.py放在 config/ 目录下与 settings.py 同级 echo from django.http import HttpResponse def home(request): return HttpResponse(h1Hello, World from Django!/h1) config/views.py然后修改config/urls.py替换其全部内容为# config/urls.py from django.contrib import admin from django.urls import path from . import views # ← 关键从当前包config导入 views 模块 urlpatterns [ path(admin/, admin.site.urls), path(, views.home, namehome), # ← 根路径映射到 home 视图 ]此时执行python manage.py runserver访问http://127.0.0.1:8000应看到h1Hello, World from Django!/h1。成功标志终端日志出现Django version 4.2.13, using settings config.settings和Starting development server at http://127.0.0.1:8000/且浏览器返回 HTML。如果失败请立即检查config/urls.py中from . import views是否存在以及views.py是否在config/目录下——这是模块导入路径错误的高发区。2.4 引入模板系统为什么render()比HttpResponse更值得优先掌握HttpResponse返回纯字符串无法复用 HTML 结构。Django 模板引擎的核心价值在于分离逻辑与表现且天然支持变量注入、循环、条件判断。我们手动搭建模板流程# 1. 在项目根目录manage.py 所在目录创建 templates/ 目录 mkdir templates # 2. 创建基础模板 base.html cat templates/base.html EOF !DOCTYPE html html headtitle{% block title %}My Site{% endblock %}/title/head body headerh1Django Simple Project/h1/header main{% block content %}{% endblock %}/main /body /html EOF # 3. 创建首页模板 index.html cat templates/index.html EOF {% extends base.html %} {% block title %}Home Page{% endblock %} {% block content %} pWelcome to my first Django project./p pCurrent time: {{ now|date:Y-m-d H:i:s }}/p {% endblock %} EOF接着修改config/views.py引入render函数并传递上下文# config/views.py替换原内容 from django.shortcuts import render from django.http import HttpResponse from datetime import datetime def home(request): # 方式1用 render() 渲染模板推荐 context {now: datetime.now()} return render(request, index.html, context) # 方式2保留 HttpResponse 作对比注释掉 # def home(request): # return HttpResponse(h1Hello, World from Django!/h1)最后必须在config/settings.py中配置TEMPLATES。找到TEMPLATES [...]列表将DIRS: []改为DIRS: [BASE_DIR / templates]Django 4.0 使用pathlib# config/settings.py 中 TEMPLATES 配置片段 TEMPLATES [ { BACKEND: django.template.backends.django.DjangoTemplates, DIRS: [BASE_DIR / templates], # ← 关键指定模板根目录 APP_DIRS: True, OPTIONS: { context_processors: [ django.template.context_processors.debug, django.template.context_processors.request, django.contrib.auth.context_processors.auth, django.contrib.messages.context_processors.messages, ], }, }, ]此时重启服务器访问首页应看到带标题、时间戳的结构化页面。{{ now|date:Y-m-d H:i:s }}中的|date是 Django 模板过滤器它证明模板引擎已激活——这是从“能跑”到“能用”的分水岭。3. 静态文件与媒体文件为什么 CSS/JS 总是 404Django 的静态资源服务有两套完全不同的机制Django 对静态文件CSS/JS/图片和媒体文件用户上传采用物理隔离、逻辑分离的设计。新手常犯的错误是把static/目录放在templates/旁边或试图用file://协议直接打开 HTML——这永远失败因为 Django 的静态文件服务依赖于STATIC_URL和STATIC_ROOT的精确匹配且开发模式与生产模式行为截然不同。3.1 开发模式下的静态文件服务DEBUGTrue时的自动路由当DEBUGTrue开发环境Django 会自动在urls.py中注入static()路由将STATIC_URL默认/static/前缀的请求映射到STATICFILES_DIRS列表中的目录。我们必须显式声明这些目录# config/settings.py 中追加在 TEMPLATES 配置下方 import os from pathlib import Path # BASE_DIR 已定义指向 manage.py 所在目录 STATIC_URL /static/ STATICFILES_DIRS [ BASE_DIR / static, # ← 声明静态文件根目录 ] # 注意STATIC_ROOT 不需要设置仅用于 collectstatic 生产部署然后创建static/目录及示例文件mkdir static mkdir static/css static/js static/images # 创建样式表 cat static/css/main.css EOF body { font-family: sans-serif; margin: 2rem; } h1 { color: #2c3e50; } EOF # 创建 JS 脚本 cat static/js/app.js EOF console.log(Static JS loaded successfully); EOF # 修改 templates/base.html引入静态资源 sed -i s/\/head/ link relstylesheet href{% static \x27css\/main.css\x27 %}\n script src{% static \x27js\/app.js\x27 %}\/script\n\/head/ templates/base.html关键点{% static css/main.css %}中的路径是相对于STATICFILES_DIRS中每个目录的子路径不是文件系统绝对路径。Django 会遍历STATICFILES_DIRS列表查找css/main.css文件找到第一个即返回。因此static/目录必须与manage.py同级。3.2 媒体文件用户上传的图片如何安全存储与访问媒体文件如用户头像、文章配图不能混入静态文件目录因为它们是动态生成、不可预测、需权限控制的资源。Django 要求单独配置MEDIA_URL和MEDIA_ROOT# config/settings.py 中追加 MEDIA_URL /media/ MEDIA_ROOT BASE_DIR / media # ← 物理存储路径然后在config/urls.py的urlpatterns末尾添加媒体文件路由仅限 DEBUGTrue 时启用# config/urls.py在 urlpatterns 列表末尾添加 from django.conf import settings from django.conf.urls.static import static urlpatterns static(settings.MEDIA_URL, document_rootsettings.MEDIA_ROOT)注意此路由在 DEBUGFalse 时无效生产环境必须由 Nginx/Apache 直接服务 media 目录Django 不处理。验证媒体文件服务创建一个测试视图模拟文件上传实际项目中需配合forms.FileField# config/views.py 中追加 import os from django.http import HttpResponse from django.conf import settings def upload_test(request): # 创建 media/test.txt仅用于验证路径 test_file settings.MEDIA_ROOT / test.txt test_file.parent.mkdir(exist_okTrue) test_file.write_text(This is a test media file.) return HttpResponse(fMedia file created at: {test_file})并在config/urls.py中添加路由# config/urls.py from . import views # ... 其他 path() path(upload-test/, views.upload_test, nameupload-test),访问http://127.0.0.1:8000/upload-test/应看到路径提示再访问http://127.0.0.1:8000/media/test.txt应下载该文本文件。这证明MEDIA_ROOT和MEDIA_URL配置生效。3.3 静态文件收集collectstatic不是开发必需但它是上线前的必过门槛python manage.py collectstatic的作用是将所有应用包括第三方 app的静态文件按STATICFILES_DIRS和INSTALLED_APPS中的static/子目录统一拷贝到STATIC_ROOT目录。开发时无需执行因为DEBUGTrue时 Django 动态查找但生产环境DEBUGFalseDjango 不再提供静态文件服务必须由 Web 服务器Nginx直接读取STATIC_ROOT目录。# 1. 设置 STATIC_ROOT生产环境必需 # config/settings.py STATIC_ROOT BASE_DIR / staticfiles # 2. 执行收集会创建 staticfiles/ 目录并拷贝所有静态资源 python manage.py collectstatic --noinput # 3. 查看结果 ls -R staticfiles/ # 输出应包含css/, js/, admin/Django 自带管理后台静态文件--noinput参数跳过确认提示适合 CI/CD 流水线。collectstatic不会覆盖static/目录只读取并复制因此static/仍是你的开发源目录。4. 避坑指南5 条血泪经验每一条都曾让我重启服务器超过 20 次Django 的错误信息往往模糊日志级别默认不高很多问题表面是 404 或 500根源却是路径、编码、权限等底层细节。以下是我在 37 个 Django 小项目中踩出的高频坑按“现象 → 原因 → 解决”结构整理拒绝泛泛而谈。4.1 现象python manage.py runserver启动成功但访问http://127.0.0.1:8000返回This site can’t be reached或Connection refused原因ALLOWED_HOSTS为空列表Django 4.0 默认值且未在settings.py中显式设置。Django 认为所有 Host 头都不合法直接拒绝连接不输出任何日志。解决在config/settings.py中将ALLOWED_HOSTS []改为ALLOWED_HOSTS [127.0.0.1, localhost]。若需监听所有 IP仅限开发用ALLOWED_HOSTS [*]但切勿在生产环境使用。4.2 现象模板中{% static css/main.css %}渲染后变成/static/css/main.css但浏览器 Network 面板显示 404原因STATICFILES_DIRS中的路径未正确指向static/目录或static/目录不在manage.py同级。Django 查找静态文件时会拼接STATICFILES_DIRS中每个路径 css/main.css若路径错误则找不到。解决确认config/settings.py中STATICFILES_DIRS [BASE_DIR / static]且static/目录确实存在于manage.py所在目录。用ls -l $(python -c from config.settings import BASE_DIR; print(BASE_DIR / static))验证路径是否存在。4.3 现象render(request, index.html, context)报错TemplateDoesNotExist at /但templates/index.html文件明明存在原因TEMPLATES[DIRS]未设置或设置为字符串而非Path对象Django 4.0 要求pathlib.Path。Django 默认只搜索INSTALLED_APPS中各 app 的templates/子目录不会自动扫描项目根目录。解决确保config/settings.py中TEMPLATES配置的DIRS是BASE_DIR / templatesPath对象而非./templates字符串。用print(type(BASE_DIR / templates))验证类型为class pathlib.PosixPath。4.4 现象修改views.py后保存runserver未自动重载必须手动 CtrlC 再启动原因runserver的自动重载机制只监控 Python 文件.py和模板文件.html但不监控settings.py或urls.py的修改。若你改了settings.py中的DEBUG或ALLOWED_HOSTS必须重启。解决开发时养成习惯——修改settings.py或urls.py后务必手动重启runserver。可使用touch命令触发重载Linux/macOStouch config/settings.py但不如直接重启可靠。4.5 现象python manage.py migrate报错django.core.exceptions.AppRegistryNotReady: Apps arent ready yet原因在settings.py加载完成前就执行了 Django 模型相关的操作如from myapp.models import MyModel。常见于__init__.py、views.py顶部或自定义管理命令中过早导入模型。解决将所有from xxx.models import YYY导入语句移到函数内部如def my_view(request): from myapp.models import MyModel; ...或使用django.apps.apps.ready信号延迟执行。最简单方案确认manage.py未被意外修改且INSTALLED_APPS中无拼写错误的应用名。5. 从“能跑”到“能交差”用 3 个真实场景验证项目健壮性并固化为可复用的检查清单一个“简单 Django Web 项目”是否真正可用不取决于它能否显示 Hello World而在于它能否通过以下三个真实场景的压力测试。我每次交付小型内部工具时都用这套流程快速验证比写单元测试更高效——因为它们直击 Django 运行时最脆弱的环节。5.1 场景一跨平台启动验证——Windows/Linux/macOS 三端一致运行Django 的路径处理在不同系统上差异巨大os.path.joinvspathlib.PathSTATICFILES_DIRS和TEMPLATES[DIRS]若用字符串拼接极易在 Windows 上因反斜杠\导致路径错误。验证方法# 在 Linux/macOS 终端执行 python -c from config.settings import BASE_DIR print(Templates:, BASE_DIR / templates) print(Static:, BASE_DIR / static) print(Media:, BASE_DIR / media) # 在 Windows PowerShell 执行注意PowerShell 中 / 会被当作参数分隔符改用 \ python -c from config.settings import BASE_DIR print(Templates:, BASE_DIR / templates) print(Static:, BASE_DIR / static) print(Media:, BASE_DIR / media) 预期输出所有路径均为PosixPathLinux/macOS或WindowsPathWindows且末尾无双反斜杠\\。若出现WindowsPath(C:\\myproject\\templates)说明pathlib正常工作若出现C:/myproject/templates字符串则BASE_DIR构造有误。5.2 场景二环境变量解耦验证——把DEBUG和SECRET_KEY移出settings.py硬编码DEBUGTrue和SECRET_KEY是安全红线。Django 提供django-environ库实现环境变量驱动配置但我们可以用原生方式# 创建 .env 文件与 manage.py 同级 echo DEBUGTrue .env echo SECRET_KEYyour-very-secure-secret-key-change-it .env修改config/settings.py在顶部添加# config/settings.py 开头 import os from pathlib import Path # 读取 .env 文件仅开发环境 env_file Path(__file__).parent.parent / .env if env_file.exists(): with open(env_file) as f: for line in f: if in line and not line.strip().startswith(#): key, value line.strip().split(, 1) os.environ.setdefault(key, value.strip(\)) # 后续配置使用 os.environ.get() DEBUG os.environ.get(DEBUG, False).lower() true SECRET_KEY os.environ.get(SECRET_KEY, dev-secret-key)然后删除settings.py中原有的DEBUG和SECRET_KEY赋值。验证DEBUGFalse时runserver应报错You’re running in DEBUG mode提示且ALLOWED_HOSTS必须非空——这证明环境变量已接管。5.3 场景三URL 反向解析验证——用reverse()替代硬编码路径杜绝链接失效硬编码 URL如a href/about/About/a在路由变更时必然断裂。Django 的reverse()函数通过命名 URL 动态生成路径是专业项目的标配。我们为首页添加命名路由并验证# config/urls.py from django.urls import path from . import views urlpatterns [ path(admin/, admin.site.urls), path(, views.home, namehome), # ← 已有 namehome path(about/, views.about, nameabout), # ← 新增 about 页面 ]# config/views.py 中新增 about 视图 def about(request): return render(request, about.html, {})# 创建 about.html 模板 cat templates/about.html EOF {% extends base.html %} {% block title %}About Us{% endblock %} {% block content %} h2About This Project/h2 pThis is a simple Django project built for learning./p pa href{% url home %}Back to Home/a/p {% endblock %} EOF访问http://127.0.0.1:8000/about/点击 “Back to Home” 链接应跳转回首页。关键验证在config/urls.py中将path(, views.home, namehome)改为path(welcome/, views.home, namehome)刷新 about 页面“Back to Home” 链接自动变为/welcome/无需修改模板——这证明reverse()机制生效。6. 我的 Django 项目初始化 checklist一份贴在显示器边框上的纸质清单十年没改过我把上面所有步骤压缩成一张 A4 纸大小的 checklist打印后贴在显示器右侧边框每次新建 Django 项目必逐条打钩。它不追求理论完备只收录那些一旦漏掉就会让项目卡死 2 小时以上的动作。这份清单没有版本号、不提最佳实践、不教你怎么设计 Model它只回答一个问题“现在这个项目能不能在同事电脑上5 分钟内跑起来”序号检查项打钩 ✅说明1python -m venv env source env/bin/activate虚拟环境必须独立pip list只有 3 个包2django-admin startproject config .项目目录扁平化config/与manage.py同级3config/settings.py中DEBUGTrue且ALLOWED_HOSTS[127.0.0.1,localhost]缺一不可否则 400 错误静默失败4config/urls.py中from . import viewspath(, views.home)模块导入路径错误是 70% 的 500 错误源头5templates/目录在manage.py同级且settings.py中DIRS[BASE_DIR/templates]pathlib.Path是唯一安全写法6static/目录在manage.py同级且settings.py中STATICFILES_DIRS[BASE_DIR/static]static/css/main.css必须能被collectstatic扫描到7views.py中用render()而非HttpResponse且传入request参数render()自动注入csrf_token避免表单提交 4038python manage.py runserver启动后终端日志含Using settings config.settings证明 settings 模块被正确加载不是默认配置9访问http://127.0.0.1:8000显示 HTMLNetwork 面板无 404CSS/JS静态文件服务链完整STATIC_URL→STATICFILES_DIRS→static/目录10修改config/urls.py中path(, ...)的路径刷新页面链接自动更新url模板标签生效证明路由命名机制可靠这张纸我用了十年从 Django 1.8 到 4.2唯一改动是第 3 条的ALLOWED_HOSTS默认值——因为 Django 4.0 把它从[*]改成了[]。其他条目纹丝不动因为它们解决的不是框架特性而是Python 模块系统、HTTP 协议、文件系统路径这三座大山的底层约束。每次新同事入职我递给他这张纸说“别看文档先打满 10 个钩再碰 Model。” 他总笑我老派直到某天他为一个ImportError调试 3 小时才默默把这张纸复印了三份贴满工位。希望帮到你。本文还有配套的精品资源点击获取