<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Django6.1 - 标签 | 飞污熊小站</title><link>https://xiongneng.me/tags/django6.1/</link><description>飞污熊小站</description><generator>Hugo 0.166.0 &amp; FixIt v0.4.6-20260512073637-464c4659</generator><language>zh-CN</language><managingEditor>yidao620@163.com (XiongNeng)</managingEditor><webMaster>yidao620@163.com (XiongNeng)</webMaster><copyright>XiongNeng</copyright><lastBuildDate>Sat, 26 Sep 2026 03:04:43 +0000</lastBuildDate><atom:link href="https://xiongneng.me/tags/django6.1/index.xml" rel="self" type="application/rss+xml"/><item><title>使用Django6.1开发博客（14） - 部署与收尾</title><link>https://xiongneng.me/posts/python/simpleblog/django61-blog-14-deployment/</link><pubDate>Sat, 26 Sep 2026 14:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/python/simpleblog/django61-blog-14-deployment/</guid><category domain="https://xiongneng.me/categories/python/">Python</category><description>&lt;p&gt;功能已经比较完整，最后把项目放进真实运行环境。部署要收口开发阶段的假设。&lt;code&gt;DEBUG&lt;/code&gt; 要关掉，密钥要交给环境，静态文件要有出口，进程要有健康检查。&lt;/p&gt;&#10;&lt;p&gt;&lt;img loading="lazy" src='https://static.xiongneng.me/deploy-runtime-20260926140000.png' alt="https://static.xiongneng.me/deploy-runtime-20260926140000.png"&gt;&lt;/p&gt;&#10;&lt;p&gt;公共请求先到 Nginx，TLS 和静态文件在这里结束；动态请求进入 Gunicorn，再交给 Django。应用数据、附件对象和缓存分开存放，任何一块出问题都不会把所有状态混在一起。&lt;/p&gt;</description></item><item><title>使用Django6.1开发博客（13） - I18n国际化</title><link>https://xiongneng.me/posts/python/simpleblog/django61-blog-13-i18n/</link><pubDate>Sat, 26 Sep 2026 13:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/python/simpleblog/django61-blog-13-i18n/</guid><category domain="https://xiongneng.me/categories/python/">Python</category><description>&lt;p&gt;博客界面已有中文文案，但语言仍写死在模板里。我把界面文案交给 Django 翻译机制，加入 LocaleMiddleware、语言目录和切换表单。读者选择 English 后，导航、列表分页和空状态会一起变化。&lt;/p&gt;&#10;&lt;p&gt;&lt;img loading="lazy" src='https://static.xiongneng.me/i18n-locale-flow-20260926000000.png' alt="https://static.xiongneng.me/i18n-locale-flow-20260926000000.png"&gt;&lt;/p&gt;&#10;&lt;p&gt;请求先经过 LocaleMiddleware，它会读取 &lt;code&gt;django_language&lt;/code&gt; Cookie 或 &lt;code&gt;Accept-Language&lt;/code&gt;，解析出当前语言。模板再从翻译目录里取对应文案。&lt;/p&gt;</description></item><item><title>使用Django6.1开发博客（12） - Redis缓存</title><link>https://xiongneng.me/posts/python/simpleblog/django61-blog-12-redis-cache/</link><pubDate>Sat, 26 Sep 2026 12:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/python/simpleblog/django61-blog-12-redis-cache/</guid><category domain="https://xiongneng.me/categories/python/">Python</category><description>&lt;p&gt;侧边栏在每一页都会查分类、最新文章、热门文章、最新评论和归档。这些数据不要求毫秒级新鲜，很适合缓存。我把侧边栏结果缓存一分钟；本地开发使用 LocMemCache，配置 &lt;code&gt;REDIS_URL&lt;/code&gt; 后自动切到 Redis。&lt;/p&gt;&#10;&lt;p&gt;&lt;img loading="lazy" src='https://static.xiongneng.me/cache-sequence-20260926000000.png' alt="https://static.xiongneng.me/cache-sequence-20260926000000.png"&gt;&lt;/p&gt;&#10;&lt;p&gt;视图先查缓存；命中就直接渲染；未命中执行数据库查询，写回缓存。&lt;/p&gt;</description></item><item><title>使用Django6.1开发博客（11） - 图片上传与OSS</title><link>https://xiongneng.me/posts/python/simpleblog/django61-blog-11-oss-uploads/</link><pubDate>Sat, 26 Sep 2026 11:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/python/simpleblog/django61-blog-11-oss-uploads/</guid><category domain="https://xiongneng.me/categories/python/">Python</category><description>&lt;p&gt;博客经常需要给文章配图。我加入图片附件模型，并把图片写入阿里云 OSS。五个配置全部来自环境变量，密钥不写进代码。&lt;/p&gt;&#10;&lt;p&gt;&lt;img loading="lazy" src='https://static.xiongneng.me/oss-deployment-20260926000000.png' alt="https://static.xiongneng.me/oss-deployment-20260926000000.png"&gt;&lt;/p&gt;&#10;&lt;p&gt;上传链路是 Django 收文件，&lt;code&gt;ImageField&lt;/code&gt; 校验图片，自定义 Storage 调用 OSS SDK，数据库只保存对象键。&lt;/p&gt;</description></item><item><title>使用Django6.1开发博客（10） - 用户认证</title><link>https://xiongneng.me/posts/python/simpleblog/django61-blog-10-authentication/</link><pubDate>Sat, 26 Sep 2026 10:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/python/simpleblog/django61-blog-10-authentication/</guid><category domain="https://xiongneng.me/categories/python/">Python</category><description>&lt;p&gt;评论和互动可以开放给访客；作者管理、附件上传、后台统计都需要身份。我先补上注册、登录、登出，让导航根据登录状态变化。&lt;/p&gt;&#10;&lt;p&gt;&lt;img loading="lazy" src='https://static.xiongneng.me/auth-sequence-20260926000000.png' alt="https://static.xiongneng.me/auth-sequence-20260926000000.png"&gt;&lt;/p&gt;&#10;&lt;p&gt;注册成功后马上建立会话；登录成功进入首页；登出只接受 POST，并回到首页。&lt;/p&gt;&#10;&lt;h2 class="heading-element" id="注册表单扩展-django-自带表单"&gt;&lt;span&gt;注册表单扩展 Django 自带表单&lt;/span&gt;&#10; &lt;a href="#%e6%b3%a8%e5%86%8c%e8%a1%a8%e5%8d%95%e6%89%a9%e5%b1%95-django-%e8%87%aa%e5%b8%a6%e8%a1%a8%e5%8d%95" class="heading-mark"&gt;&#10; &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"&gt;&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"&gt;&lt;/path&gt;&lt;/svg&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&lt;p&gt;不要手写密码哈希。Django 的 &lt;code&gt;UserCreationForm&lt;/code&gt; 已经处理两次密码校验和密码安全规则。&lt;/p&gt;</description></item><item><title>使用Django6.1开发博客（9） - 全文搜索</title><link>https://xiongneng.me/posts/python/simpleblog/django61-blog-09-full-text-search/</link><pubDate>Sat, 26 Sep 2026 09:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/python/simpleblog/django61-blog-09-full-text-search/</guid><category domain="https://xiongneng.me/categories/python/">Python</category><description>&lt;p&gt;文章多起来以后，导航只能帮人缩小范围，搜索才能直接找答案。我给首页加一个搜索框，检索标题、摘要和正文，并让搜索词跟着分页链接继续传递。&lt;/p&gt;&#10;&lt;p&gt;&lt;img loading="lazy" src='https://static.xiongneng.me/search-dataflow-20260926000000.png' alt="https://static.xiongneng.me/search-dataflow-20260926000000.png"&gt;&lt;/p&gt;&#10;&lt;p&gt;搜索词进入视图后先清理空格，再构造 OR 条件。只要标题、摘要或正文命中，文章就进入结果集。&lt;/p&gt;</description></item><item><title>使用Django6.1开发博客（8） - 后台统计</title><link>https://xiongneng.me/posts/python/simpleblog/django61-blog-08-admin-stats/</link><pubDate>Sat, 26 Sep 2026 08:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/python/simpleblog/django61-blog-08-admin-stats/</guid><category domain="https://xiongneng.me/categories/python/">Python</category><description>&lt;p&gt;文章后台已有管理入口，但管理员每天关心的几个数字还得点进列表慢慢数。我把基础统计放进文章列表页上方，显示文章总数、发布数、草稿数、浏览总量和平均浏览量。&lt;/p&gt;&#10;&lt;p&gt;&lt;img loading="lazy" src='https://static.xiongneng.me/admin-stats-component-20260926000000.png' alt="https://static.xiongneng.me/admin-stats-component-20260926000000.png"&gt;&lt;/p&gt;&#10;&lt;p&gt;数据仍然从数据库实时聚合。博客规模不大，这样做最诚实。等访问量上来，再把统计结果放进缓存或定时汇总表。&lt;/p&gt;</description></item><item><title>使用Django6.1开发博客（7） - 分页与站点设置</title><link>https://xiongneng.me/posts/python/simpleblog/django61-blog-07-pagination-settings/</link><pubDate>Sat, 26 Sep 2026 00:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/python/simpleblog/django61-blog-07-pagination-settings/</guid><category domain="https://xiongneng.me/categories/python/">Python</category><description>&lt;p&gt;列表、分类、标签和归档都会随着文章增多变长。我给它们加同一套分页，并把每页数量放进 Django Admin。编辑改一个数字，所有文章列表一起生效。&lt;/p&gt;&#10;&lt;p&gt;&lt;img loading="lazy" src='https://static.xiongneng.me/pagination-dataflow-20260926000000.png' alt="https://static.xiongneng.me/pagination-dataflow-20260926000000.png"&gt;&lt;/p&gt;&#10;&lt;p&gt;请求进入视图后，文章集合先按业务规则过滤，再交给 &lt;code&gt;Paginator&lt;/code&gt;。页大小来自 &lt;code&gt;SiteSetting&lt;/code&gt;，页码来自 URL 的 &lt;code&gt;page&lt;/code&gt; 参数。模板只接收 &lt;code&gt;page_obj&lt;/code&gt;，不用关心当前视图是列表、分类还是归档。&lt;/p&gt;</description></item><item><title>使用Django6.1开发博客（6） - 评论与互动</title><link>https://xiongneng.me/posts/python/simpleblog/django61-blog-06-comments-votes/</link><pubDate>Fri, 25 Sep 2026 23:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/python/simpleblog/django61-blog-06-comments-votes/</guid><category domain="https://xiongneng.me/categories/python/">Python</category><description>&lt;p&gt;博客能被人读，也需要能被人回应。我先加上匿名评论、顶和踩、热门文章。互动功能第一次把不可信输入带进数据库，验证和转义因此比表单本身更重要。&lt;/p&gt;&#10;&lt;p&gt;&lt;img loading="lazy" src='https://static.xiongneng.me/interaction-sequence-20260926000000.png' alt="https://static.xiongneng.me/interaction-sequence-20260926000000.png"&gt;&lt;/p&gt;&#10;&lt;p&gt;评论请求先经过表单验证，再绑定到已发布文章；投票请求先找到文章和浏览器会话，再检查是否已经投过。两者都只在验证通过后写库。&lt;/p&gt;</description></item><item><title>使用Django6.1开发博客（5） - 分类标签与归档</title><link>https://xiongneng.me/posts/python/simpleblog/django61-blog-05-taxonomy-archive/</link><pubDate>Fri, 25 Sep 2026 22:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/python/simpleblog/django61-blog-05-taxonomy-archive/</guid><category domain="https://xiongneng.me/categories/python/">Python</category><description>&lt;p&gt;文章多了以后，列表页会变成一条长队。读者想找的内容通常很具体，可能看某个分类，可能记得写作月份，也可能只记得一个标签。我先把这三条找文章的路补上，同时给每一页加上侧边栏。&lt;/p&gt;&#10;&lt;p&gt;&lt;img loading="lazy" src='https://static.xiongneng.me/taxonomy-class-diagram-20260926000000.png' alt="https://static.xiongneng.me/taxonomy-class-diagram-20260926000000.png"&gt;&lt;/p&gt;&#10;&lt;p&gt;分类、标签、归档分别回答三个问题。分类说文章主要属于哪里，标签说文章还涉及什么，归档说文章出现在哪个时间。三者不互相替代。&lt;/p&gt;</description></item><item><title>使用Django6.1开发博客（4） - Markdown与代码高亮</title><link>https://xiongneng.me/posts/python/simpleblog/django61-blog-04-markdown-code/</link><pubDate>Fri, 25 Sep 2026 21:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/python/simpleblog/django61-blog-04-markdown-code/</guid><category domain="https://xiongneng.me/categories/python/">Python</category><description>&lt;p&gt;上一篇文章的详情页能打开，但正文只是几行普通段落。技术博客离不开 fenced code、表格和标题层级，纯文本很快就会不够用。我接着把 Markdown 渲染接进详情页，并让代码块得到 Pygments 高亮。&lt;/p&gt;&#10;&lt;p&gt;&lt;img loading="lazy" src='https://static.xiongneng.me/markdown-component-pipeline-20260926000000.png' alt="https://static.xiongneng.me/markdown-component-pipeline-20260926000000.png"&gt;&lt;/p&gt;&#10;&lt;p&gt;整条链路很短。作者在后台保存 Markdown，数据库只保存原始文本；详情页请求到达时，模板过滤器把它渲染成 HTML；CodeHilite 给代码块加上类名；页面加载预生成的 Pygments CSS，浏览器完成着色。&lt;/p&gt;</description></item><item><title>使用Django6.1开发博客（3） - 页面与详情</title><link>https://xiongneng.me/posts/python/simpleblog/django61-blog-03-views-templates/</link><pubDate>Fri, 25 Sep 2026 20:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/python/simpleblog/django61-blog-03-views-templates/</guid><category domain="https://xiongneng.me/categories/python/">Python</category><description>&lt;p&gt;模型稳住以后，博客该见人了。我先接通文章列表和详情页，顺手处理两个很容易拖到上线后的问题。草稿不能因为一个判断写漏就跑到前台；浏览量也不能在并发访问里被旧值覆盖。&lt;/p&gt;&#10;&lt;p&gt;&lt;img loading="lazy" src='https://static.xiongneng.me/blog-request-sequence-20260926000000.png' alt="https://static.xiongneng.me/blog-request-sequence-20260926000000.png"&gt;&lt;/p&gt;&#10;&lt;p&gt;一个读者请求先经过根路由，再进入 &lt;code&gt;blog&lt;/code&gt; 应用的路由，最后到达视图。视图只取已发布文章，交给模板渲染。详情页还会多一步浏览量更新。&lt;/p&gt;</description></item><item><title>使用Django6.1开发博客（2） - 模型与后台</title><link>https://xiongneng.me/posts/python/simpleblog/django61-blog-02-models-admin/</link><pubDate>Fri, 25 Sep 2026 19:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/python/simpleblog/django61-blog-02-models-admin/</guid><category domain="https://xiongneng.me/categories/python/">Python</category><description>&lt;p&gt;项目骨架能跑以后，我先把博客的数据模型立起来。页面可以晚一点出现，数据边界不能晚。接下来要定义分类、标签和文章三张业务表，打开 Django Admin，再把模型交给测试守住。&lt;/p&gt;&#10;&lt;p&gt;&lt;img loading="lazy" src='https://static.xiongneng.me/blog-model-er-20260925180510.png' alt="https://static.xiongneng.me/blog-model-er-20260925180510.png"&gt;&lt;/p&gt;&#10;&lt;p&gt;图里有四类对象。&lt;code&gt;User&lt;/code&gt; 来自 Django 的认证系统，&lt;code&gt;Category&lt;/code&gt; 收敛文章的纵向归属，&lt;code&gt;Tag&lt;/code&gt; 补充横向主题，&lt;code&gt;Post&lt;/code&gt; 是这张图的核心。一篇文章只有一个作者和一个分类，可以挂多个标签；一个标签也会被多篇文章使用。&lt;/p&gt;</description></item><item><title>使用Django6.1开发博客（1） - 项目初始化</title><link>https://xiongneng.me/posts/python/simpleblog/django61-blog-01-init/</link><pubDate>Fri, 25 Sep 2026 17:30:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/python/simpleblog/django61-blog-01-init/</guid><category domain="https://xiongneng.me/categories/python/">Python</category><description>&lt;p&gt;背景是这样子的，大概十年前我写了一个使用Django开发博客系列教程，那时候的Django版本还是1.9。十年弹指一挥就过去了，人生又有多少个十年呢？&lt;/p&gt;&#10;&lt;p&gt;这次我将使用最新版本 Django 6.1 从零开始重新来开发这个博客，通过循序渐进的方式一步步的构建这个博客系统，一个功能一个功能的往上加。从构建整个博客的过程中来学习Django6.1的使用方式，以及最新的Python WEB开发技术。&lt;/p&gt;</description></item></channel></rss>