公司动态

Django快速入门:10分钟搭建个人网站与博客系统实战

📅 2026/8/13 3:57:27
Django快速入门:10分钟搭建个人网站与博客系统实战
1. 项目概述为什么选择Django作为你的第一把“快刀”如果你手头有一个绝妙的点子想快速把它变成一个能在线访问的网站但又不想在复杂的环境配置和底层代码上耗费数周时间那么Django可能就是为你量身定做的工具。很多人听到“Web框架”就觉得头大联想到漫长的学习曲线和复杂的部署流程。但Django的设计哲学恰恰相反它信奉“包含电池”的理念意思是它已经为你准备好了开发一个成熟网站所需的大部分组件用户认证、后台管理界面、数据库ORM、表单处理、安全防护等等全都开箱即用。我最初接触Django就是被它“10分钟搭建一个可运行网站”的官方宣传所吸引。当时我半信半疑但跟着教程走了一遍后发现它真的能做到。这十分钟不是指做出一个功能复杂的成品而是指你能在十分钟内完成从零环境到拥有一个自带后台、能连接数据库、并能通过浏览器访问的“项目骨架”。这个骨架健康、强壮为你后续添加任何功能都打下了坚实的基础。相比于从零开始写HTTP服务器、处理SQL拼接、手动编写管理页面Django帮你节省了90%的重复性劳动让你能专注于业务逻辑——也就是你那个绝妙点子的核心。为什么国内讨论度似乎不如某些其他框架这其实是个误区。Django在需要快速构建稳健后台、内容管理系统CMS、企业内部平台等领域应用非常广泛其“稳健”和“高效”的特性深受许多中大型项目团队的青睐。它可能不是每个初创公司博客的首选但在需要严谨、安全、可扩展的场景下Django往往是经验丰富的开发者的默认选项之一。对于个人网站、作品集、博客系统或者小型SaaS应用来说用它来起步速度和质量都能得到保障。2. 核心思路与项目结构解析2.1 “项目”与“应用”理解Django的模块化思想刚接触Django最容易混淆的两个概念就是“项目”和“应用”。你可以把一个“项目”想象成你的整个网站它是一个完整的容器。而“应用”则是这个网站里的一个功能模块比如博客模块、用户中心模块、商品展示模块。一个项目可以包含多个应用这种设计鼓励功能解耦和代码复用。当你运行django-admin startproject mywebsite命令时你创建的是一个“项目”。这个命令会生成一个标准的目录结构其中manage.py是项目管理的心脏所有后续的命令如运行服务器、创建应用、数据库迁移都通过它来执行。settings.py文件则是项目的大脑所有配置从数据库连接到静态文件路径都在这里定义。而当你运行python manage.py startapp blog时你是在项目中创建了一个名为“blog”的“应用”。这个应用目录下会有models.py定义数据模型、views.py处理业务逻辑、admin.py配置后台管理等文件。这种结构清晰地分离了不同功能的代码使得项目即使变得庞大也易于维护。注意很多新手会试图把所有代码都写在项目根目录或同一个应用里这会导致后期难以维护。从一开始就规划好比如“blog”应用负责文章“accounts”应用负责用户会让你的代码库清晰得多。2.2 MTV模式Django如何处理一次网页请求Django遵循MTV模式这与常见的MVC模式本质相同只是叫法不同M (Model模型)负责与数据库打交道定义数据结构。在models.py中你用Python类来定义一张数据表Django的ORM会帮你自动生成SQL。T (Template模板)负责呈现给用户的HTML页面。它不是一个简单的静态文件而是可以嵌入动态数据的模板使用Django模板语言来渲染。V (View视图)这是业务逻辑的核心。它接收用户的请求Request从Model中获取或处理数据然后选择一个Template将数据填充进去最后返回一个响应Response给用户的浏览器。一次典型的访问流程是这样的用户浏览器发起请求 - URL路由urls.py根据网址找到对应的View函数 - View函数执行逻辑可能调用Model查询数据 - View将数据传递给Template进行渲染 - 渲染后的HTML作为Response返回给浏览器。理解这个流程你就掌握了Django运作的主干。3. 十分钟极速搭建实操全记录下面我们来真正实践“10分钟搭建”。请确保你的电脑已经安装了Python3和pip。打开你的终端或命令行工具我们开始计时。3.1 环境准备与项目创建第1-2分钟首先我们创建一个干净的虚拟环境来隔离项目依赖这是Python开发的最佳实践能避免不同项目间的包版本冲突。# 1. 创建并进入一个项目目录 mkdir my_django_site cd my_django_site # 2. 创建Python虚拟环境这里使用venvPython3内置 python3 -m venv venv # 3. 激活虚拟环境 # 在 macOS/Linux 上 source venv/bin/activate # 在 Windows 上 # venv\Scripts\activate # 看到命令行提示符前出现 (venv) 即表示激活成功 # 4. 安装Django安装最新稳定版 pip install django安装完成后使用Django内置的管理工具创建项目骨架# 5. 创建名为 config 的Django项目 # 我喜欢用config或core作为项目配置目录名比直接用mywebsite更清晰 django-admin startproject config .注意命令末尾的点.它表示在当前目录创建项目文件而不是再新建一个子目录。执行后你会看到生成了manage.py和config文件夹。3.2 初始配置与数据库迁移第3-5分钟现在进行最基本的配置并创建数据库。首先我们使用Django默认的SQLite数据库它无需额外安装非常适合开发和原型阶段。# 1. 进入项目配置目录编辑 settings.py 文件这里用简单说明代替直接编辑 # 你可以用任何文本编辑器如VSCode, Sublime, Vim打开 config/settings.py我们主要关注config/settings.py中的几个关键设置ALLOWED_HOSTS这是一个安全设置定义了哪些主机/域名可以访问这个Django站点。在开发时我们可以先将其设置为允许所有ALLOWED_HOSTS [*]注意仅限开发环境上线前必须修改INSTALLED_APPS这里列出了项目启用的所有应用。Django自带了一些应用如用于用户认证的django.contrib.auth和用于后台管理的django.contrib.admin。接下来进行数据库迁移。迁移是Django同步你的模型目前是内置应用的模型到数据库 schema 的方式。# 2. 运行数据库迁移命令创建默认的表如用户表、权限表等 python manage.py migrate这个命令会读取INSTALLED_APPS中所有应用的模型定义并在SQLite数据库中创建对应的数据表。你会看到终端输出一系列“Applying ... OK”的信息。3.3 创建超级用户并运行开发服务器第6-8分钟数据库有了我们需要一个能登录后台管理界面的超级用户。# 3. 创建超级用户 python manage.py createsuperuser按提示输入用户名、邮箱和密码。这个账户将拥有最高权限。现在激动人心的时刻到了——启动Django自带的轻量级开发服务器# 4. 启动开发服务器 python manage.py runserver终端会显示“Starting development server at http://127.0.0.1:8000/”。打开你的浏览器访问这个地址。你应该会看到Django的“安装成功”火箭图标页面这证明你的网站服务已经成功运行。3.4 探索后台管理与完成搭建第9-10分钟在浏览器中访问 http://127.0.0.1:8000/admin/。使用刚才创建的超级用户账号登录。你将进入Django功能强大的自动后台管理界面。在这里你可以看到并管理“用户和组”来自auth应用。虽然我们还没创建自己的应用但这个自带的后台已经是一个完整可用的内容管理系统雏形。至此一个具备基础框架、数据库、后台管理、Web服务的个人网站骨架已经在十分钟内搭建完毕。你可以通过CtrlC停止开发服务器。4. 从骨架到血肉创建你的第一个应用有了健康的骨架接下来我们要为网站添加具体的功能比如一个简单的博客。这需要创建我们自己的“应用”。4.1 创建博客应用与定义数据模型停止服务器后在项目根目录下执行# 创建名为 blog 的应用 python manage.py startapp blog这会在项目根目录生成一个blog/文件夹。接下来我们需要告诉项目这个新应用的存在。编辑config/settings.py找到INSTALLED_APPS列表在末尾添加blogINSTALLED_APPS [ django.contrib.admin, django.contrib.auth, ... # 其他默认应用 blog, # 添加这一行 ]现在我们来定义博客文章的数据模型。打开blog/models.pyfrom django.db import models from django.utils import timezone class Article(models.Model): # 文章标题CharField对应数据库的VARCHAR类型max_length是最大长度 title models.CharField(标题, max_length200) # 文章正文TextField对应数据库的TEXT类型能存储大量文本 content models.TextField(内容) # 发布时间DateTimeField是日期时间类型default设置默认值为当前时间 pub_date models.DateTimeField(发布时间, defaulttimezone.now) # 文章状态BooleanField是布尔类型defaultTrue表示默认是已发布状态 is_published models.BooleanField(是否发布, defaultTrue) def __str__(self): # 这个方法定义了在后台或Shell中查看此对象时显示的字符串方便识别 return self.title class Meta: # 在后台管理界面这个模型显示的名称 verbose_name 文章 verbose_name_plural 文章列表 # 复数形式 # 默认按发布时间倒序排列最新的在最前面 ordering [-pub_date]4.2 激活模型并注册到后台定义好模型后需要创建迁移文件并应用到数据库# 为 blog 应用的模型变化创建迁移文件 python manage.py makemigrations blog # 将迁移应用到数据库真正创建 article 表 python manage.py migrate为了让我们的Article模型能在强大的后台管理界面中被管理需要在blog/admin.py中注册它from django.contrib import admin from .models import Article # 导入刚才定义的模型 # 注册模型到后台 admin.site.register(Article)4.3 创建视图、模板与配置URL现在我们需要创建前端页面来展示文章。这涉及三个部分视图处理逻辑、模板HTML页面和URL路由。第一步编写视图。编辑blog/views.pyfrom django.shortcuts import render from .models import Article def article_list(request): 文章列表视图。 1. 从数据库获取所有已发布的文章。 2. 将这些文章数据传递给模板。 3. 渲染模板并返回HTTP响应。 # 使用ORM查询filter过滤出 is_publishedTrue 的文章 # order_by(-pub_date) 按发布时间倒序排列 articles Article.objects.filter(is_publishedTrue).order_by(-pub_date) # 创建一个上下文字典将查询到的数据以‘articles’为键传递给模板 context {articles: articles} # render函数结合 request, 模板路径 和 上下文数据生成最终的HTML响应 return render(request, blog/article_list.html, context)第二步创建模板。在blog目录下新建一个templates文件夹再在templates里新建blog文件夹这是Django推荐的模板命名空间模式避免不同应用的模板重名。最终路径为blog/templates/blog/。在此目录下创建article_list.html文件!DOCTYPE html html langzh-cn head meta charsetUTF-8 title我的博客/title style body { font-family: sans-serif; max-width: 800px; margin: 40px auto; } .article { border-bottom: 1px solid #eee; padding: 20px 0; } .article h2 { margin-top: 0; color: #333; } .article .date { color: #999; font-size: 0.9em; } /style /head body h1文章列表/h1 {% for article in articles %} div classarticle h2{{ article.title }}/h2 p classdate发布时间{{ article.pub_date|date:Y年m月d日 H:i }}/p !-- 使用 linebreaksbr 过滤器将文本中的换行符转换为 br 标签 -- p{{ article.content|linebreaksbr }}/p /div {% empty %} !-- 如果 articles 列表为空则显示以下内容 -- p暂无文章。/p {% endfor %} /body /html第三步配置URL路由。首先在blog应用下创建urls.py文件from django.urls import path from . import views urlpatterns [ path(, views.article_list, namearticle_list), ]然后需要将这个应用的URL包含到项目的总路由中。编辑config/urls.pyfrom django.contrib import admin from django.urls import path, include # 导入 include 函数 urlpatterns [ path(admin/, admin.site.urls), path(blog/, include(blog.urls)), # 包含 blog 应用的URL配置 ]4.4 测试完整流程现在让我们测试整个流程启动服务器python manage.py runserver进入后台访问 http://127.0.0.1:8000/admin/登录。添加文章在后台找到“文章”部分点击“增加文章”填写标题和内容保存。查看前端访问 http://127.0.0.1:8000/blog/。你应该能看到刚刚发布的文章列表至此一个具备完整“增后台管理- 查前端列表”功能的迷你博客就完成了。整个过程你几乎没有手写SQL也没有处理复杂的HTTP请求解析这就是Django“包含电池”的威力。5. 深入核心Django ORM与数据库高效操作Django ORM是它的王牌功能之一让你用Python对象的方式操作数据库安全又高效。理解它能极大提升开发效率。5.1 基础查询与过滤器ORM查询是惰性的只有当你真正需要数据时如迭代、求长度、转换成列表它才会执行SQL查询。# 导入模型 from blog.models import Article from django.utils import timezone # 1. 获取所有对象 all_articles Article.objects.all() # 返回一个QuerySet查询集 # 2. 获取单个对象通过主键 article Article.objects.get(pk1) # pk 是 primary key 的缩写 # 3. 使用 filter 过滤 published_articles Article.objects.filter(is_publishedTrue) recent_articles Article.objects.filter(pub_date__gtetimezone.now() - timezone.timedelta(days7)) # 最近7天的文章 # 4. 使用 exclude 排除 unpublished_articles Article.objects.exclude(is_publishedTrue) # 5. 链式调用与排序 articles Article.objects.filter(is_publishedTrue).order_by(-pub_date)[:5] # 最近发布的5篇文章字段查找是ORM的精华。双下划线__用于进行更复杂的查询pub_date__year2023查询2023年的文章。title__contains‘Django’标题包含“Django”的文章。pub_date__range(start_date, end_date)发布时间在某个区间内的文章。5.2 创建、更新与删除# 1. 创建对象方法一 new_article Article(title新文章标题, content内容...) new_article.save() # 必须调用save()才会存入数据库 # 创建对象方法二更常用 article Article.objects.create(title另一个标题, content内容...) # 创建并立即保存 # 2. 更新对象 article Article.objects.get(pk1) article.title 修改后的标题 article.save() # 更新 # 批量更新 Article.objects.filter(is_publishedFalse).update(is_publishedTrue) # 将所有未发布文章设为发布 # 3. 删除对象 article.delete() # 删除单个对象 Article.objects.filter(title__contains测试).delete() # 批量删除实操心得save()方法会更新所有字段。如果只想更新部分字段可以使用update()方法仅适用于QuerySet或者save(update_fields[‘title’, ‘content’])后者能提升性能并避免并发问题。5.3 处理关联关系真实的博客中文章会有分类、标签、作者等。这需要通过模型字段定义关联。class Category(models.Model): name models.CharField(分类名, max_length100) class Article(models.Model): title models.CharField(标题, max_length200) # 外键关联一篇文章属于一个分类一个分类有多篇文章 category models.ForeignKey(Category, on_deletemodels.CASCADE, verbose_name分类) # 多对多关联一篇文章可以有多个标签一个标签可以对应多篇文章 tags models.ManyToManyField(Tag, verbose_name标签) class Tag(models.Model): name models.CharField(标签名, max_length50)on_deletemodels.CASCADE是外键的级联删除选项意思是当关联的分类被删除时属于这个分类的所有文章也会被删除。其他选项还有PROTECT保护阻止删除、SET_NULL设为空等根据业务逻辑选择。查询时可以通过关联关系进行跨表查询# 查询属于“技术”分类的所有文章 tech_articles Article.objects.filter(category__name技术) # 查询带有“Python”标签的文章 python_articles Article.objects.filter(tags__namePython) # 通过文章对象访问关联对象 article Article.objects.get(pk1) print(article.category.name) # 访问分类名 for tag in article.tags.all(): # 访问所有标签 print(tag.name)6. 性能考量与高并发浅析当你的个人网站访问量增大或者涉及复杂查询时性能优化就变得重要。Django提供了多种工具来应对。6.1 查询优化避免N1查询问题这是最常见的性能陷阱。假设你要列出10篇文章及其分类# 低效的做法产生N1次查询 articles Article.objects.all()[:10] for article in articles: print(article.title, article.category.name) # 每次循环都额外查询一次数据库获取category使用select_related用于一对一、多对一关联和prefetch_related用于多对多、反向关联来优化# 高效的做法产生1次或2次查询 # select_related 通过JOIN一次性获取关联对象 articles Article.objects.select_related(category).all()[:10] for article in articles: print(article.title, article.category.name) # 这里不再查询数据库 # prefetch_related 用于多对多关系会执行额外的查询但仍然是有限的次数 articles_with_tags Article.objects.prefetch_related(tags).all()[:10]6.2 缓存策略Django内置了灵活的缓存框架可以将整个页面、部分模板片段或数据库查询结果缓存起来。视图缓存使用cache_page装饰器缓存整个视图的输出。模板片段缓存在模板中使用{% cache %}标签缓存HTML块。低级缓存API直接操作缓存用于缓存复杂的查询结果或计算代价高的数据。from django.core.cache import cache def get_expensive_data(): data cache.get(expensive_data_key) if data is None: # 如果缓存中没有则执行昂贵的计算或查询 data perform_expensive_calculation() # 将结果存入缓存有效期3600秒1小时 cache.set(expensive_data_key, data, 3600) return data6.3 异步支持与部署考量Django从3.1版本开始逐步引入对异步视图、ORM查询的支持。这意味着对于高IO并发的场景如大量外部API调用你可以使用async/await语法编写视图提高服务器的吞吐量。# 一个简单的异步视图示例 from django.http import JsonResponse import asyncio async def async_api_view(request): # 模拟一个异步IO操作 await asyncio.sleep(1) return JsonResponse({message: Hello from async view!})但是需要特别注意Django的ORM核心操作在默认情况下仍然是同步的。在异步视图中执行ORM查询需要使用sync_to_async适配器或者使用支持异步的数据库驱动如asyncpgfor PostgreSQL。对于新建项目如果预期有高并发需求可以考虑评估Django的异步生态但对于大多数个人网站和传统CRUD应用同步模式已经足够稳健高效。关于部署个人网站常见的方案是Django Gunicorn/Uvicorn (WSGI/ASGI服务器) Nginx (反向代理/静态文件服务)。将DEBUG False设置好ALLOWED_HOSTS、静态文件收集python manage.py collectstatic和数据库可考虑迁移到PostgreSQL或MySQL你的网站就具备了上线运行的基础。7. 常见问题与排查技巧实录在实际操作中你肯定会遇到各种报错和意外情况。这里记录几个高频问题及其解决方法。7.1 数据库迁移相关错误问题1No changes detected当运行makemigrations时。原因Django没有检测到你的模型有任何更改。解决确保你的应用已添加到INSTALLED_APPS。检查models.py文件是否已保存。尝试指定应用名python manage.py makemigrations blog。如果模型字段有复杂修改有时需要手动干预或删除迁移文件重新生成开发环境。问题2迁移冲突Conflicting migrations detected。原因多人协作或手动修改迁移文件导致依赖关系混乱。解决谨慎操作备份为先查看冲突详情python manage.py showmigrations。一种激进但有效的开发环境解决方法是备份数据库后删除migrations文件夹内除__init__.py外的所有文件然后重新运行makemigrations和migrate。生产环境绝对禁止此操作7.2 静态文件无法加载404错误现象开发时CSS/JS/图片等静态文件显示正常但使用runserver以外的服务器如NginxGunicorn部署后就404。原因Django的开发服务器会自动处理静态文件但生产服务器不会。你需要配置Nginx/Apache来服务静态文件或者使用白名单服务如AWS S3。解决步骤在settings.py中正确设置STATIC_URL和STATIC_ROOT。STATIC_URL /static/ STATIC_ROOT os.path.join(BASE_DIR, staticfiles) # 收集静态文件的目标目录运行python manage.py collectstatic将所有应用的静态文件收集到STATIC_ROOT。配置你的Web服务器如Nginx将STATIC_URL路径的请求指向STATIC_ROOT目录。7.3 跨站请求伪造CSRF验证失败现象提交表单特别是POST请求时出现403 Forbidden错误提示CSRF验证失败。原因Django默认启用了CSRF中间件以增强安全性。它要求POST表单中必须包含一个有效的CSRF令牌。解决在模板的表单标签内添加{% csrf_token %}。form methodpost {% csrf_token %} !-- 其他表单字段 -- input typesubmit value提交 /form如果是在写API如使用Django REST Framework可能需要根据API设计禁用CSRF或使用其他认证方式。对于纯API视图可以使用csrf_exempt装饰器临时豁免但需充分了解安全风险。7.4Page not found (404)但URL配置看起来正确现象访问/blog/返回404但urls.py配置无误。排查首先检查服务器是否在运行并监听正确端口。检查项目根urls.py和应用的urls.py是否已正确include。一个常见陷阱在项目根urls.py的urlpatterns列表中顺序很重要。Django从上到下匹配。确保你的自定义路径如path(‘blog/’, …)放在可能匹配的通用路径如path(‘’, …)之前。使用python manage.py show_urls命令或安装django-extensions后使用列出所有已注册的URL检查你的URL是否在其中。7.5 后台管理界面样式丢失现象访问/admin/时页面没有CSS样式变成纯文本。原因静态文件没有正确加载。在开发环境中确保settings.py中的DEBUG True并且INSTALLED_APPS包含django.contrib.staticfiles。解决确认DEBUG True。确认INSTALLED_APPS中有django.contrib.staticfiles。运行python manage.py collectstatic开发环境下通常不需要但可以尝试。检查浏览器控制台F12的Network标签看是哪个CSS/JS文件加载失败根据错误信息进一步排查。最后养成查看Django错误页面的习惯。当DEBUG True时Django会给出非常详细的黄色错误页面其中包含了错误类型、位置、相关代码片段甚至局部变量值这是解决问题最直接的线索。遇到问题不要慌仔细阅读错误信息十有八九都能找到答案。