Skip to content

第13章:完整博客系统

13.3 高级功能

用户系统集成

集成完整的用户系统功能:

python
# views.py (accounts应用)
from django.shortcuts import render, redirect
from django.contrib.auth import login
from django.contrib.auth.decorators import login_required
from django.contrib.auth.views import LoginView, LogoutView
from django.contrib import messages
from django.views.generic import CreateView, DetailView, UpdateView
from django.urls import reverse_lazy
from django.contrib.auth.models import User
from .forms import UserRegistrationForm, UserProfileForm
from .models import UserProfile

class RegisterView(CreateView):
    form_class = UserRegistrationForm
    template_name = 'accounts/register.html'
    success_url = reverse_lazy('blog:home')
    
    def form_valid(self, form):
        response = super().form_valid(form)
        # 自动登录用户
        login(self.request, self.object)
        messages.success(self.request, '注册成功!欢迎加入我们。')
        return response

class ProfileView(DetailView):
    model = User
    template_name = 'accounts/profile.html'
    context_object_name = 'profile_user'
    
    def get_object(self, queryset=None):
        # 如果用户已登录,显示自己的资料;否则显示指定用户的资料
        if self.request.user.is_authenticated:
            return self.request.user
        return super().get_object(queryset)

class ProfileUpdateView(UpdateView):
    model = User
    form_class = UserProfileForm
    template_name = 'accounts/profile_edit.html'
    success_url = reverse_lazy('accounts:profile')
    
    def get_object(self, queryset=None):
        return self.request.user
    
    def form_valid(self, form):
        response = super().form_valid(form)
        messages.success(self.request, '资料更新成功!')
        return response

# forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from .models import UserProfile

class UserRegistrationForm(UserCreationForm):
    email = forms.EmailField(required=True)
    
    class Meta:
        model = User
        fields = ("username", "email", "password1", "password2")
    
    def save(self, commit=True):
        user = super().save(commit=False)
        user.email = self.cleaned_data["email"]
        if commit:
            user.save()
            # 创建用户资料
            UserProfile.objects.create(user=user)
        return user

class UserProfileForm(forms.ModelForm):
    # 用户基本信息
    first_name = forms.CharField(max_length=30, required=False)
    last_name = forms.CharField(max_length=30, required=False)
    email = forms.EmailField(required=False)
    
    class Meta:
        model = UserProfile
        fields = ['bio', 'location', 'birth_date', 'website', 'avatar']
        widgets = {
            'bio': forms.Textarea(attrs={'class': 'form-control', 'rows': 4}),
            'location': forms.TextInput(attrs={'class': 'form-control'}),
            'birth_date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}),
            'website': forms.URLInput(attrs={'class': 'form-control'}),
            'avatar': forms.FileInput(attrs={'class': 'form-control'}),
        }
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 初始化用户基本信息字段
        if self.instance and self.instance.user:
            self.fields['first_name'].initial = self.instance.user.first_name
            self.fields['last_name'].initial = self.instance.user.last_name
            self.fields['email'].initial = self.instance.user.email
    
    def save(self, commit=True):
        profile = super().save(commit=False)
        # 保存用户基本信息
        user = profile.user
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.email = self.cleaned_data['email']
        if commit:
            user.save()
            profile.save()
        return profile

富文本编辑器

集成富文本编辑器:

# 安装django-ckeditor
# pip install django-ckeditor

# settings.py
INSTALLED_APPS = [
    # ...
    'ckeditor',
    'ckeditor_uploader',
]

# CKEditor配置
CKEDITOR_CONFIGS = {
    'default': {
        'toolbar': 'full',
        'height': 300,
        'width': '100%',
    },
}

CKEDITOR_UPLOAD_PATH = "uploads/"
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

# models.py
from ckeditor.fields import RichTextField
from ckeditor_uploader.fields import RichTextUploadingField

class Article(models.Model):
    # ... 其他字段 ...
    content = RichTextUploadingField()  # 使用富文本编辑器
    excerpt = RichTextField(blank=True, config_name='default')

# forms.py
from ckeditor.widgets import CKEditorWidget

class ArticleForm(forms.ModelForm):
    class Meta:
        model = Article
        fields = ['title', 'category', 'tags', 'content', 'excerpt', 'featured_image', 'status']
        widgets = {
            'content': CKEditorWidget(config_name='default'),
            'excerpt': CKEditorWidget(config_name='default'),
            # ... 其他widgets ...
        }

缓存优化

实现缓存优化:

# settings.py
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.redis.RedisCache',
        'LOCATION': 'redis://127.0.0.1:6379/1',
    }
}

# views.py
from django.views.decorators.cache import cache_page
from django.utils.decorators import method_decorator
from django.core.cache import cache

@method_decorator(cache_page(60 * 15), name='dispatch')  # 缓存15分钟
class ArticleListView(ListView):
    # ... 视图代码 ...

class ArticleDetailView(DetailView):
    # ... 其他代码 ...
    
    def get_object(self, queryset=None):
        # 使用缓存获取文章
        slug = self.kwargs['slug']
        cache_key = f'article_{slug}'
        article = cache.get(cache_key)
        
        if article is None:
            article = super().get_object(queryset)
            # 缓存文章1小时
            cache.set(cache_key, article, 60 * 60)
        else:
            # 如果从缓存获取,仍需要增加浏览量
            article.view_count += 1
            article.save(update_fields=['view_count'])
        
        return article

# 使用模板片段缓存
# templates/blog/article_list.html
{% load cache %}

{% cache 900 article_list page_obj.number %}
    {% for article in articles %}
        <!-- 文章列表内容 -->
    {% endfor %}
{% endcache %}

# 模板中缓存侧边栏
{% cache 1800 sidebar %}
    <!-- 侧边栏内容 -->
{% endcache %}

SEO优化

实现SEO优化功能:

# models.py
class Article(models.Model):
    # ... 其他字段 ...
    meta_description = models.TextField(blank=True, help_text="SEO描述")
    meta_keywords = models.CharField(max_length=255, blank=True, help_text="SEO关键词")
    
    def get_meta_description(self):
        """获取SEO描述"""
        if self.meta_description:
            return self.meta_description
        # 如果没有设置,使用文章摘要
        return self.excerpt
    
    def get_meta_keywords(self):
        """获取SEO关键词"""
        if self.meta_keywords:
            return self.meta_keywords
        # 如果没有设置,使用标签名称
        return ', '.join([tag.name for tag in self.tags.all()])

# templates/base.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}我的博客{% endblock %}</title>
    
    <!-- SEO元数据 -->
    <meta name="description" content="{% block meta_description %}{% endblock %}">
    <meta name="keywords" content="{% block meta_keywords %}{% endblock %}">
    <meta name="author" content="{% block author %}{% endblock %}">
    
    <!-- Open Graph -->
    <meta property="og:title" content="{% block og_title %}{% endblock %}">
    <meta property="og:description" content="{% block og_description %}{% endblock %}">
    <meta property="og:type" content="article">
    <meta property="og:url" content="{{ request.build_absolute_uri }}">
    
    <!-- Twitter Card -->
    <meta name="twitter:card" content="summary">
    <meta name="twitter:title" content="{% block twitter_title %}{% endblock %}">
    <meta name="twitter:description" content="{% block twitter_description %}{% endblock %}">
    
    <link rel="canonical" href="{{ request.build_absolute_uri }}">
</head>
<body>
    <!-- 页面内容 -->
</body>
</html>

# templates/blog/article_detail.html
{% extends 'base.html' %}

{% block title %}{{ article.title }} - 我的博客{% endblock %}

{% block meta_description %}{{ article.get_meta_description }}{% endblock %}

{% block meta_keywords %}{{ article.get_meta_keywords }}{% endblock %}

{% block author %}{{ article.author.get_full_name|default:article.author.username }}{% endblock %}

{% block og_title %}{{ article.title }}{% endblock %}

{% block og_description %}{{ article.get_meta_description }}{% endblock %}

{% block twitter_title %}{{ article.title }}{% endblock %}

{% block twitter_description %}{{ article.get_meta_description }}{% endblock %}

通过这些高级功能的实现,博客系统将具备完整的用户管理、富文本编辑、性能优化和SEO优化能力。

小结

博客系统高级功能实现的关键要点:

  1. ✅ 集成完整的用户注册、登录和个人资料管理功能
  2. ✅ 集成富文本编辑器提升内容创作体验
  3. ✅ 实施缓存优化策略提高系统性能
  4. ✅ 实现SEO优化功能提升搜索引擎可见性
  5. ✅ 注重用户体验和系统可维护性

这些高级功能使博客系统更加完善和专业。

下一篇

我们将学习Django REST Framework的使用。

14.1 Django REST Framework入门 →

目录

返回课程目录

Released under the Apache 2.0 License.