Django 6中文教程

14.2 核心功能开发(一):文章管理

Django6个人博客系统开发(一):文章管理核心功能

Django 6中文教程

本教程详细讲解使用Django6构建个人博客系统的文章管理功能,涵盖模型定义与迁移、列表与详情页开发、发布编辑删除操作,以及分类和标签的关联管理,适合Django6新手学习。

推荐工具
PyCharm专业版开发必备

功能强大的Python IDE,提供智能代码补全、代码分析、调试和测试工具,提高Python开发效率。特别适合处理列表等数据结构的开发工作。

了解更多

Django6个人博客系统开发(一):文章管理核心功能

引言

欢迎来到Django6个人博客系统教程的第一部分!在这部分中,我们将专注于博客的核心功能:文章管理。如果你是Django新手,别担心,我会一步步带你从零开始,学习如何定义文章模型、进行数据库迁移、开发文章列表和详情页面,并实现文章的发布、编辑、删除功能,同时管理分类和标签。本教程假设你已经安装了Django6并创建了项目,但我会尽量详细解释每个步骤。

文章模型定义与迁移

定义模型

在Django中,模型是数据库的蓝图。我们首先需要定义文章相关的模型。假设项目名为blog,在blog/models.py文件中编写以下代码:

from django.db import models
from django.contrib.auth.models import User  # 引入用户模型,用于关联文章作者

# 分类模型
class Category(models.Model):
    name = models.CharField(max_length=100, unique=True, verbose_name='分类名称')
    description = models.TextField(blank=True, verbose_name='分类描述')
    
    def __str__(self):
        return self.name  # 方便在管理后台显示

# 标签模型
class Tag(models.Model):
    name = models.CharField(max_length=100, unique=True, verbose_name='标签名称')
    
    def __str__(self):
        return self.name

# 文章模型
class Article(models.Model):
    title = models.CharField(max_length=200, verbose_name='文章标题')
    content = models.TextField(verbose_name='文章内容')
    author = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='作者')  # 外键关联用户,删除用户时文章也删除
    published_date = models.DateTimeField(auto_now_add=True, verbose_name='发布时间')  # 自动设置发布时间
    updated_date = models.DateTimeField(auto_now=True, verbose_name='更新时间')  # 每次保存时自动更新
    category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='分类')  # 可选分类,允许为空
    tags = models.ManyToManyField(Tag, blank=True, verbose_name='标签')  # 多对多关系,文章可以有多个标签
    
    def __str__(self):
        return self.title  # 方便在管理后台显示文章标题

解释

  • 我们定义了三个模型:CategoryTagArticleArticle使用ForeignKeyCategory关联,表示每篇文章属于一个分类(可选);使用ManyToManyFieldTag关联,表示文章可以有多个标签。
  • 添加了verbose_name参数,以便在管理后台显示中文名称,提升用户体验。
  • auto_now_addauto_now是Django的便捷字段,自动处理日期时间。

迁移数据库

定义好模型后,需要将这些模型同步到数据库中。Django通过迁移系统管理数据库变化。运行以下命令:

# 生成迁移文件
python manage.py makemigrations blog  # 如果你在blog应用下,可以不加blog
# 应用迁移
python manage.py migrate

解释makemigrations命令会创建一个迁移文件,记录模型变化;migrate命令则实际应用这些变化,创建数据库表。

文章列表与详情页开发

创建视图

视图是处理用户请求并返回响应的函数。在blog/views.py中编写:

from django.shortcuts import render, get_object_or_404
from .models import Article

def article_list(request):
    """文章列表视图,显示所有文章"""
    articles = Article.objects.all().order_by('-published_date')  # 查询所有文章,按发布时间降序排列
    context = {
        'articles': articles
    }
    return render(request, 'blog/article_list.html', context)

def article_detail(request, article_id):
    """文章详情视图,根据ID显示单篇文章"""
    article = get_object_or_404(Article, id=article_id)  # 如果文章不存在,返回404错误页面
    context = {
        'article': article
    }
    return render(request, 'blog/article_detail.html', context)

解释order_by('-published_date')确保最新文章在前;get_object_or_404是一个便捷函数,简化了错误处理。

URL路由

接下来,在blog/urls.py中配置URL路径(如果还没有这个文件,请在blog应用下创建)。

from django.urls import path
from . import views

urlpatterns = [
    path('articles/', views.article_list, name='article_list'),  # 文章列表页
    path('articles/<int:article_id>/', views.article_detail, name='article_detail'),  # 文章详情页
]

同时,确保项目的主urls.py中包含了这个应用的URL配置。例如,在myproject/urls.py中添加:

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('blog/', include('blog.urls')),  # 包含blog应用的URL
]

模板开发

模板是用于渲染HTML页面的文件。首先,创建模板目录blog/templates/blog/,然后创建两个模板文件:

article_list.html:显示文章列表。

<!-- 假设基础模板在templates/base.html中,使用继承简化代码 -->
{% extends 'base.html' %}

{% block content %}
<h1>文章列表</h1>
<ul>
    {% for article in articles %}
        <li>
            <a href="{% url 'article_detail' article.id %}">{{ article.title }}</a>
            <small> - 发布时间:{{ article.published_date|date:'Y-m-d H:i' }}</small>
        </li>
    {% empty %}
        <li>暂无文章。</li>
    {% endfor %}
</ul>
{% endblock %}

article_detail.html:显示单篇文章详情。

{% extends 'base.html' %}

{% block content %}
<h1>{{ article.title }}</h1>
<p><strong>作者:</strong>{{ article.author.username }}</p>
<p><strong>发布时间:</strong>{{ article.published_date|date:'Y-m-d H:i' }} | <strong>更新时间:</strong>{{ article.updated_date|date:'Y-m-d H:i' }}</p>
<div>{{ article.content }}</div>
<p><strong>分类:</strong>{% if article.category %}{{ article.category.name }}{% else %}未分类{% endif %}</p>
<p><strong>标签:</strong>
    {% for tag in article.tags.all %}
        {{ tag.name }}{% if not forloop.last %}, {% endif %}
    {% empty %}
        无标签
    {% endfor %}
</p>
<a href="{% url 'article_list' %}">返回文章列表</a>
{% endblock %}

解释:使用Django模板标签{% url %}生成动态URL;|date是模板过滤器,格式化日期显示。

文章发布、编辑、删除功能实现

表单创建

Django提供了ModelForm来简化表单创建。在blog/forms.py中创建:

from django import forms
from .models import Article

class ArticleForm(forms.ModelForm):
    class Meta:
        model = Article
        fields = ['title', 'content', 'category', 'tags']  # 排除author等自动填充的字段

解释ModelForm自动根据模型生成表单字段,省去手动定义字段的麻烦。

视图实现

blog/views.py中添加创建、编辑和删除视图:

from django.shortcuts import render, redirect, get_object_or_404
from .models import Article
from .forms import ArticleForm

def article_create(request):
    """发布新文章"""
    if request.method == 'POST':
        form = ArticleForm(request.POST)
        if form.is_valid():
            article = form.save(commit=False)  # 先不保存到数据库
            article.author = request.user  # 设置作者为当前登录用户(确保已登录)
            article.save()  # 保存文章
            form.save_m2m()  # 保存多对多关系(如标签)
            return redirect('article_detail', article_id=article.id)  # 重定向到详情页
    else:
        form = ArticleForm()
    context = {'form': form}
    return render(request, 'blog/article_form.html', context)

def article_edit(request, article_id):
    """编辑已有文章"""
    article = get_object_or_404(Article, id=article_id)
    if request.method == 'POST':
        form = ArticleForm(request.POST, instance=article)  # instance参数指定要编辑的实例
        if form.is_valid():
            form.save()
            return redirect('article_detail', article_id=article.id)
    else:
        form = ArticleForm(instance=article)
    context = {'form': form}
    return render(request, 'blog/article_form.html', context)

def article_delete(request, article_id):
    """删除文章"""
    article = get_object_or_404(Article, id=article_id)
    if request.method == 'POST':
        article.delete()
        return redirect('article_list')  # 删除后返回列表页
    context = {'article': article}
    return render(request, 'blog/article_confirm_delete.html', context)

解释

  • commit=False允许我们在保存前添加额外数据(如作者)。
  • save_m2m()是必须的,用于保存多对多字段。
  • 删除操作使用POST方法以确保安全(防止CSRF攻击)。

更新URL和模板

blog/urls.py中添加新URL:

urlpatterns = [
    path('articles/', views.article_list, name='article_list'),
    path('articles/<int:article_id>/', views.article_detail, name='article_detail'),
    path('articles/new/', views.article_create, name='article_create'),  # 发布文章
    path('articles/<int:article_id>/edit/', views.article_edit, name='article_edit'),  # 编辑文章
    path('articles/<int:article_id>/delete/', views.article_delete, name='article_delete'),  # 删除文章
]

创建表单模板article_form.html

{% extends 'base.html' %}

{% block content %}
<h1>{% if form.instance.pk %}编辑文章{% else %}发布新文章{% endif %}</h1>
<form method="post">
    {% csrf_token %}  <!-- 必须的CSRF令牌,用于安全 -->
    {{ form.as_p }}  <!-- 以段落形式渲染表单字段 -->
    <button type="submit">保存</button>
    <a href="{% url 'article_list' %}">取消</a>
</form>
{% endblock %}

创建删除确认模板article_confirm_delete.html

{% extends 'base.html' %}

{% block content %}
<h1>确认删除</h1>
<p>您确定要删除文章 "{{ article.title }}" 吗?</p>
<form method="post">
    {% csrf_token %}
    <button type="submit">确认删除</button>
    <a href="{% url 'article_detail' article.id %}">取消</a>
</form>
{% endblock %}

解释{% csrf_token %}是Django的安全机制,防止跨站请求伪造攻击。

分类与标签关联管理

我们已经在上面的模型中定义了分类和标签的关联。为了管理它们,可以创建一个简单的视图或使用Django的管理后台。这里,我们使用Django内置的管理后台进行管理,这对新手更友好。

首先,在blog/admin.py中注册模型:

from django.contrib import admin
from .models import Category, Tag, Article

admin.site.register(Category)
admin.site.register(Tag)
admin.site.register(Article)

然后,运行服务器(python manage.py runserver),访问/admin/,使用超级用户登录(可以通过python manage.py createsuperuser创建)。在管理后台,你可以轻松添加、编辑分类和标签,并在文章表单中关联它们。

解释:Django管理后台是一个强大的工具,可以快速管理数据,无需编写额外代码。在文章表单中,会自动显示下拉菜单(分类)和多选框(标签)。

结语

恭喜!你已经完成了Django6个人博客系统文章管理核心功能的开发。我们学会了定义模型、进行迁移、开发视图和模板,并实现了文章的CRUD(创建、读取、更新、删除)操作,同时集成了分类和标签管理。这为后续添加更多功能(如用户认证、搜索、评论等)打下了基础。

在下一部分,我们将扩展功能,例如添加用户权限控制、优化UI等。希望本教程对你有所帮助,如果有问题,随时查阅Django官方文档或社区资源。祝你在Django学习之路上顺利前行!

开发工具推荐
Python开发者工具包

包含虚拟环境管理、代码格式化、依赖管理、测试框架等Python开发全流程工具,提高开发效率。特别适合处理复杂数据结构和算法。

获取工具包