用 Python 和 Django 实现一个更实用的博客系统,让写作更简单、更愉快

July

Django实现一个更实用的博客系统,让写作更简单,更愉快。

Demo


博客相关页面

  • 博客首页

home

  • 博文详情

article

后台管理相关页面

  • 后台首页

admin

  • 添加文章

add-article

  • 文章列表

article-list

  • 标签管理

tag

  • 分类管理

categories

  • 系统消息

message-os

  • 用户列表

users

  • 友链管理

link

  • 用户个人信息

profile

  • 全局设置

settings

  • 普通用户登录所看到的页面

putongyonghu

环境

  1. Python3.5.2
  2. Django 1.10.6
  3. Markdown(Editor.md)
  4. 后台模板(AdminLTE)

后记

看到这儿是不是已经迫不及待了?没关系,安装文章我已问你写好,客官请慢用,点我

下个版本?

下个版本预计会修复如下问题:

  1. 文章多级评论
  2. 后台修复评论通知
  3. 添加微信和 github 登录

然后,如果你有什么问题,欢迎提issues

反馈与建议

感谢你的阅读,如果可以,请献出你宝贵的Star


用 Python 和 Django 实现一个更实用的博客系统,让写作更简单、更愉快

36 回复

就喜欢这股子直爽劲 :-D


> 别问我为什么不用配置文件方式启动 uwsgi ,因为我不会。


我理解你想用Django构建一个更实用的博客系统。这里给你一个核心实现方案,包含文章管理、Markdown支持和简单的分类功能。

首先创建Django项目和应用:

django-admin startproject blog_project
cd blog_project
python manage.py startapp blog

models.py - 核心数据模型:

from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
import markdown

class Category(models.Model):
    name = models.CharField(max_length=50)
    slug = models.SlugField(unique=True)
    
    def __str__(self):
        return self.name

class Post(models.Model):
    STATUS_CHOICES = (
        ('draft', '草稿'),
        ('published', '已发布'),
    )
    
    title = models.CharField(max_length=200)
    slug = models.SlugField(unique_for_date='publish_date')
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    content = models.TextField()
    content_html = models.TextField(editable=False)  # 存储转换后的HTML
    excerpt = models.CharField(max_length=300, blank=True)
    category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True)
    status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='draft')
    publish_date = models.DateTimeField(default=timezone.now)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    
    def save(self, *args, **kwargs):
        # 自动将Markdown转换为HTML
        self.content_html = markdown.markdown(
            self.content,
            extensions=['extra', 'codehilite']
        )
        super().save(*args, **kwargs)
    
    def __str__(self):
        return self.title
    
    class Meta:
        ordering = ['-publish_date']

admin.py - 后台管理配置:

from django.contrib import admin
from .models import Category, Post

@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
    list_display = ['name', 'slug']
    prepopulated_fields = {'slug': ('name',)}

@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
    list_display = ['title', 'author', 'status', 'publish_date', 'category']
    list_filter = ['status', 'publish_date', 'category']
    search_fields = ['title', 'content']
    prepopulated_fields = {'slug': ('title',)}
    date_hierarchy = 'publish_date'
    ordering = ['status', '-publish_date']

views.py - 视图函数:

from django.shortcuts import render, get_object_or_404
from django.views.generic import ListView, DetailView
from .models import Post, Category

class PostListView(ListView):
    model = Post
    template_name = 'blog/post_list.html'
    context_object_name = 'posts'
    paginate_by = 10
    
    def get_queryset(self):
        return Post.objects.filter(status='published')

class PostDetailView(DetailView):
    model = Post
    template_name = 'blog/post_detail.html'
    context_object_name = 'post'
    
    def get_queryset(self):
        return Post.objects.filter(status='published')

class CategoryPostListView(ListView):
    template_name = 'blog/post_list.html'
    context_object_name = 'posts'
    paginate_by = 10
    
    def get_queryset(self):
        category = get_object_or_404(Category, slug=self.kwargs['slug'])
        return Post.objects.filter(category=category, status='published')

urls.py - URL配置:

from django.urls import path
from .views import PostListView, PostDetailView, CategoryPostListView

urlpatterns = [
    path('', PostListView.as_view(), name='post_list'),
    path('post/<slug:slug>/', PostDetailView.as_view(), name='post_detail'),
    path('category/<slug:slug>/', CategoryPostListView.as_view(), name='category_posts'),
]

模板示例 (post_detail.html)

{% extends 'base.html' %}

{% block content %}
<article class="post">
    <h1>{{ post.title }}</h1>
    <div class="meta">
        <span>作者: {{ post.author }}</span>
        <span>发布于: {{ post.publish_date|date:"Y-m-d" }}</span>
        {% if post.category %}
        <span>分类: <a href="{% url 'category_posts' post.category.slug %}">{{ post.category.name }}</a></span>
        {% endif %}
    </div>
    <div class="content">
        {{ post.content_html|safe }}
    </div>
</article>
{% endblock %}

requirements.txt

Django>=4.0
markdown>=3.4
Pygments  # 代码高亮支持

这个实现包含了博客系统的核心功能:文章发布流程、Markdown支持、分类管理。你可以在此基础上添加标签系统、评论功能、搜索等特性。安装markdown和Pygments后,代码块会自动高亮显示。

总结:这个基础框架已经能让你愉快地写作了。

很精致。赞!

O(∩_∩)O 谢谢

嘿嘿嘿,\坏笑

July …
我记得有个叫 June 的项目……

好漂亮啊 我喜欢!

不错。收藏。

July 与安生 已 star

七月与安生么…

邮箱密码。。。。

底部版权可以去掉么

另外,你的私人账号信息之类的可在 setting 里面哟

你的 GitHub 里面的版本不是最新的,根本找不到发表文章的地方.

是的。

这个无所谓,本来就是测试来的。

版权什么的直接改 HTML ,运行这个项目需要 Nginx ,访问静态文件用的,然后你说的找不到发布文章的地方,可能是因为你直接注册了个账户,然后这个账户并不是超级管理员,所以,没有发布文章等按钮,你需要把你的用户改成超级用户~

配色感觉怪怪的

博客页套的模板,我也感觉怪怪的,实在是没找到更好的。

django 一直 import 失败是什么节奏 T ^ T

这个怎么了吗?

样式不错,可以抄抄吗

手机 mark 一下,做的好好

后台犀利

模板而已哈。

全局设置的实现,是把配置存放到数据库中的吗?

是的,

之前在 layui 里好像看到你= =

你可能遇到了假的我

gayhub 上边的代码是最新的么,最近刚好在学 python web ,战略性 mark 加帮顶

目前赶项目,等闲下来了在更新。

回到顶部