You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django中实现类似WordPress的动态页面创建功能

Django 实现类WordPress动态自定义页面方案

核心思路

通过「页面基础信息表+自定义内容区块表」的组合结构,解耦内容配置与模板代码,用单个视图匹配不同页面slug实现多独立页面的动态渲染,支持后台完全自定义页面内容,可直接复用现有博客的侧边栏组件、媒体资源管理等已有能力。

1. 模型设计

首先定义两类数据表,分别存储页面基础属性和页面内的所有内容区块:

from django.db import models
from django.utils.text import slugify

class Page(models.Model):
    BLOCK_TYPE_CHOICES = [
        ('text', '富文本'),
        ('image', '单图'),
        ('video', '视频'),
        ('slider', '轮播图'),
        ('widget', '侧边栏组件'),
    ]
    title = models.CharField(max_length=200, verbose_name="页面标题")
    slug = models.SlugField(max_length=200, unique=True, verbose_name="页面标识")
    is_published = models.BooleanField(default=True, verbose_name="是否发布")
    template_name = models.CharField(max_length=100, default="custom_page.html", verbose_name="页面模板")
    create_time = models.DateTimeField(auto_now_add=True)
    update_time = models.DateTimeField(auto_now=True)

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title)
        super().save(*args, **kwargs)

    def __str__(self):
        return self.title

class ContentBlock(models.Model):
    page = models.ForeignKey(Page, on_delete=models.CASCADE, related_name="blocks", verbose_name="所属页面")
    block_type = models.CharField(max_length=20, choices=Page.BLOCK_TYPE_CHOICES, verbose_name="区块类型")
    content = models.TextField(verbose_name="区块内容", help_text="根据类型填写:富文本/图片链接/视频链接/JSON格式的轮播图列表/组件名")
    sort_order = models.IntegerField(default=0, verbose_name="排序优先级(数字越小越靠前)")
    is_visible = models.BooleanField(default=True, verbose_name="是否显示")

    class Meta:
        ordering = ['sort_order']

2. 后台管理配置

将内容区块设置为页面的内联管理项,编辑页面时可直接增减、排序区块,无需跳转其他页面:

from django.contrib import admin
from .models import Page, ContentBlock

class ContentBlockInline(admin.TabularInline):
    model = ContentBlock
    extra = 1
    fields = ['block_type', 'content', 'sort_order', 'is_visible']

@admin.register(Page)
class PageAdmin(admin.ModelAdmin):
    list_display = ['title', 'slug', 'is_published', 'update_time']
    prepopulated_fields = {"slug": ("title",)}
    inlines = [ContentBlockInline]

如果需要拖拽排序功能,可直接使用Django生态的可排序内联插件,无需修改核心逻辑。

3. 单视图实现多页面路由

写统一的页面处理视图,根据slug匹配对应页面,无需为每个独立页面单独编写视图:

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

def custom_page_view(request, page_slug):
    page = get_object_or_404(Page, slug=page_slug, is_published=True)
    blocks = page.blocks.filter(is_visible=True)
    context = {
        'page': page,
        'blocks': blocks
    }
    return render(request, page.template_name, context)

在urls.py中添加路由配置即可覆盖所有自定义页面:

urlpatterns = [
    # 原有博客路由保持不变
    path('page/<slug:page_slug>/', custom_page_view, name='custom_page'),
]

4. 模板动态渲染

在通用模板custom_page.html中根据区块类型动态渲染对应内容,完全无需硬编码页面结构,新增区块类型只需扩展模板判断逻辑即可:

<!DOCTYPE html>
<html>
<head>
    <title>{{ page.title }}</title>
</head>
<body>
    <h1>{{ page.title }}</h1>
    {% for block in blocks %}
        {% if block.block_type == 'text' %}
            <div class="text-block">
                {{ block.content|safe }}
            </div>
        {% elif block.block_type == 'image' %}
            <div class="image-block">
                <img src="{{ block.content }}" alt="页面图片">
            </div>
        {% elif block.block_type == 'video' %}
            <div class="video-block">
                <video src="{{ block.content }}" controls></video>
            </div>
        {% elif block.block_type == 'slider' %}
            <div class="slider-block">
                {% with slider_items=block.content|json_script:"slider-data" %}
                <!-- 可直接复用现有博客的轮播组件逻辑 -->
                {% endwith %}
            </div>
        {% elif block.block_type == 'widget' %}
            <div class="widget-block">
                {% include f"widgets/{block.content}.html" %}
            </div>
        {% endif %}
    {% endfor %}
</body>
</html>

可扩展功能

  • 支持为不同页面配置独立的SEO字段(meta标题、描述、关键词),直接添加在Page模型字段中即可
  • 可增加页面权限控制,指定特定登录用户才能访问
  • 对发布后的页面做缓存,降低服务器负载
  • 支持页面草稿、版本回溯功能,只需扩展Page模型状态字段即可

内容的提问来源于stack exchange,提问作者B Syal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 17:06:04