Skip to content

第13章:完整博客系统

13.1 项目规划

需求分析

在开发完整的博客系统之前,我们需要进行详细的需求分析:

功能需求:

  1. 用户系统:注册、登录、个人资料管理
  2. 文章管理:创建、编辑、删除、发布文章
  3. 分类和标签:文章分类和标签系统
  4. 评论系统:用户可以对文章进行评论
  5. 搜索功能:按标题、内容、作者搜索文章
  6. 管理后台:管理员可以管理文章、用户、评论等

非功能需求:

  1. 响应式设计,支持移动端访问
  2. 良好的SEO优化
  3. 性能优化,支持高并发访问
  4. 安全性保障,防止常见Web攻击
  5. 易于维护和扩展

数据库设计

设计博客系统的数据库模型:

python
# models.py
from django.db import models
from django.contrib.auth.models import User
from django.urls import reverse
from django.utils.text import slugify

class Category(models.Model):
    name = models.CharField(max_length=100, unique=True)
    slug = models.SlugField(max_length=100, unique=True, blank=True)
    description = models.TextField(blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    
    class Meta:
        verbose_name = "分类"
        verbose_name_plural = "分类"
        ordering = ['name']
    
    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.name)
        super().save(*args, **kwargs)
    
    def __str__(self):
        return self.name
    
    def get_absolute_url(self):
        return reverse('blog:category_detail', kwargs={'slug': self.slug})

class Tag(models.Model):
    name = models.CharField(max_length=50, unique=True)
    slug = models.SlugField(max_length=50, unique=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    
    class Meta:
        verbose_name = "标签"
        verbose_name_plural = "标签"
        ordering = ['name']
    
    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.name)
        super().save(*args, **kwargs)
    
    def __str__(self):
        return self.name
    
    def get_absolute_url(self):
        return reverse('blog:tag_detail', kwargs={'slug': self.slug})

class Article(models.Model):
    STATUS_CHOICES = [
        ('draft', '草稿'),
        ('published', '已发布'),
    ]
    
    title = models.CharField(max_length=200)
    slug = models.SlugField(max_length=200, unique=True, blank=True)
    author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='articles')
    category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, blank=True)
    tags = models.ManyToManyField(Tag, blank=True, related_name='articles')
    content = models.TextField()
    excerpt = models.TextField(blank=True, help_text="文章摘要")
    featured_image = models.ImageField(upload_to='articles/%Y/%m/', blank=True)
    status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='draft')
    view_count = models.PositiveIntegerField(default=0)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    published_at = models.DateTimeField(null=True, blank=True)
    
    class Meta:
        verbose_name = "文章"
        verbose_name_plural = "文章"
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['status', 'published_at']),
            models.Index(fields=['author']),
        ]
    
    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title)
        
        if not self.excerpt:
            # 自动生成摘要
            self.excerpt = self.content[:200] + '...' if len(self.content) > 200 else self.content
        
        if self.status == 'published' and not self.published_at:
            from django.utils import timezone
            self.published_at = timezone.now()
        
        super().save(*args, **kwargs)
    
    def __str__(self):
        return self.title
    
    def get_absolute_url(self):
        return reverse('blog:article_detail', kwargs={'slug': self.slug})
    
    @property
    def is_published(self):
        return self.status == 'published'

class Comment(models.Model):
    article = models.ForeignKey(Article, on_delete=models.CASCADE, related_name='comments')
    author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='comments')
    parent = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='replies')
    content = models.TextField()
    is_approved = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)
    
    class Meta:
        verbose_name = "评论"
        verbose_name_plural = "评论"
        ordering = ['created_at']
    
    def __str__(self):
        return f'{self.author.username}{self.article.title} 的评论'
    
    @property
    def is_reply(self):
        return self.parent is not None

小结

博客系统项目规划阶段需要重点关注:

  1. ✅ 明确功能需求和非功能需求
  2. ✅ 设计合理的数据库模型结构
  3. ✅ 确定核心功能模块划分
  4. ✅ 制定开发计划和时间安排
  5. ✅ 考虑系统扩展性和维护性

良好的项目规划是成功开发的基础。

下一篇

我们将实现博客系统的核心功能。

13.2 核心功能实现 →

目录

返回课程目录

Released under the Apache 2.0 License.