前言
这个django的博客已经不再更新了。因为维护更新起来太过麻烦(就是懒)
项目链接
源码放这了哈!
github仓库地址: https://github.com/dajavv/DjangoBolg
使用工具
- 
- PyCharm 2023.1
 
 
- 
- python3.10 版本
 
 
Hexo框架
在使用了一段时间的Hexo博客后,对该框架的感受:
优势
- 
- 具有很多的主题,每一款都非常好看
 
 
- 
- 强大的模板语法
 
 
- 
- 生态完善,具有大量插件,比如:bilibili视频的小卡片、全局搜索、评论模块
 
 
劣势
- 
- 部署不便,要使用命令导入静态文件后部署到github,国内登入网络不稳定(痛点)
 
 
- 
- 维护较为困难
 
 
- 
- 加载缓慢
 
 
- 
- 缺少后端进行管理
 
 
- 
- 无法对整体文章进行搜索(可以通过插件实现,比较麻烦,不考虑)
 
 
- 
- 缺少与访客的互动
 
 
- 
- 缺少对访客数据的记录
 
 
解决问题
对于这些问题我决定对博客进行重构,让博客具有更强的功能,我计划对Hexo框架所创建的博客进行重构。 在重构的同时对django框架进行学习
功能
- 
- (√)导航栏
 
 
- 
- (√)白天黑夜切换
 
 
- 
- (√)分类
 
 
- 
- (√)归档
 
 
- 
- (√)标签分类
 
 
- 
- (√)最新文章
 
 
- 
- (√)后台发布公告
 
 
- 
- (√)后台发布文章
 
 
- 
- (√)后台管理
 
 
- 
- (×)代码高亮
 
 
- 
- ## 新计划
 
 
- 
- (×)访客数据统计
 
 
- 
- (×)全站搜索
 
 
- 
- (×)音乐盒
 
 
流程
- 
- 使用PyCharm创建Django项目,conda创建虚拟环境python3.10,导包
 
 
- 
- 创建app命名为post
 
 
- 
- settings中添加post应用
 
 
- 
- 对原html静态文件进行导入拆分,制作基础模版
 
 
- 
- 配置路由,创建视图函数,
 
 
- 
- 检查是否能正常运行显示
 
 
- 
- 配置数据库,创建数据表,对需要进行动态更新的数据创建数据表
 
 
- 
- 将要管理的数据表添加到admin文件中
 
 
- 
- 使用django的模版语法将要动态改变的数据放到html中
 
 
- 
- 完善功能(分页、分类、归档、标签归类、最新文章……)
 
 
- 
- 对网页进行测试
 
 
- 
- 完成
 
 
开始
创建虚拟环境
其中的python为python.exe的路径
python -m pip install virtualenv # 安装虚拟环境库
virtualenv env # 创建虚拟环境
env\Scripts\activate # 进入虚拟环境
创建应用
打开控制台 (可以使用使用ctrl+alt+R快捷键打开manage专属控制台)
django-admin startproject 项目名
cd 项目名
python manage.py startapp app名
在settings.py文件INSTALLED_APPS配置项中添加post应用
INSTALLED_APPS = [
 ...
'post' #添加app
]
创建基础模板
对博客网页进行拆分 组件化拆分利于更新与维护,
- 
- 基础模版
- 
- 横幅
 
 
- 
- 导航栏
 
 
- 
- 侧边栏
- 
- 介绍卡片
 
 
- 
- 公告
 
 
- 
- 分类
 
 
- 
- 标签
 
 
- 
- 归档
 
 
- 
- 最新文章
 
 
- 
- 底部页脚
 
 
 - 
 
 - 侧边栏
 
 - 
 
 - 基础模版
 
- 
- 内容模块
- 
- 分类
 
 
- 
- 归档
 
 
- 
- 标签
 
 
- 
- 文章选项卡
 
 
- 
- 关于
 
 
 - 
 
 - 内容模块
 
基础模板
在基础模版中,多为静态不需要改动的页面部分,将他们封装在根目录的templates模版文件夹中
{% include 'banner.html' %} #横幅
<div id="main-grid" class="shadow">
    {% include 'head.html' %} #导航栏
    {% include 'right.html' %} #侧边栏
    {% block main %} <!--与app中的index相连--> #文章选项卡片
    {% endblock %}
    {% include 'footer.html' %} #底部页脚
    <div class="back-to-top-wrapper"><!--回到顶部按键-->
        <button id="back-to-top-btn" class="back-to-top-btn" onclick="topFunction()"> #回到顶部的按钮
            <span class="material-symbols-rounded">keyboard_arrow_up</span>
        </button>
    </div>
</div>
Django模版语法
{% include 'banner.html' %} #引入一部分html代码
{% block main %}...{% endblock %} #页面的动态部分,后面写的会覆盖同名的代码块,在基础模版中用于占位
{% extends 'base.html' %} #继承基础模版中的静态部分
{% block title %}网页标题{% endblock %} #指定该网页的标题
{% for i in 传递过来的相应数据 %}...{% endfor %} #和python中的for相似
{% if 判断条件 %}{% elif 判断条件 %}{% else %}{% endif %} #条件加载
静态文件路径配置
在settings配置文件中添加STATICFILES_DIRS配置
这里是模版的配置,设置优先在根目录中寻找templates模版文件夹
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'templates']
        ,
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                'post.mycontextprocessor.getRightInfo'  # 引入分类,路径是app中的类中的函数
            ],
        },
    },
]
路径配置
只有配置了静态文件在html文件中才能正确找到静态的文件
在settings配置文件中
STATIC_URL = 'static/' #根目录下的static文件夹
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static', 'css'),  # BASE_DIR根目录,这条配置会指定对寻找文件的路径,这里我让他去寻找static文件夹中的css文件夹
os.path.join(BASE_DIR, 'static', 'js'),
os.path.join(BASE_DIR, 'static', 'fontawesome'),
]
在html中
<link rel="stylesheet" href="/static/style.css">
其中的href路径,相当于
static/css/style.css
<script src="/static/bundle.js"></script>
路由配置
在项目名的文件夹中的urls文件中进行配置 在这里我将路由导向了app中的urls文件
urlpatterns = [
    path('admin/', admin.site.urls), #django自带的后台管理面板
    path('', include('post.urls')), # 将路由导向app中的urls文件,核心路由配置
]
app中的路由配置
导入视图类来自app中的views文件 导入路由url配置类
from post import views #app中的视图类
from django.urls import path, re_path #
在这里的路由配置方法主要有两种
as_view的作用
as_view()是Django中用于将类视图转换为可调用的视图函数的方法。 在Django中,类视图是基于类的视图的一种方式。类视图通过继承Django提供的一些基类,可以更清晰、灵活地定义视图逻辑,并提供了许多便捷的方法和属性。但在URL配置中,我们需要将视图映射到具体的URL路径上,这就需要将类视图转换为可调用的函数形式。 .as_view()方法就是用来实现这个转换的。当在URL配置中定义一个类视图时,我们通常会使用.as_view() 方法将其转换为可调用的视图函数,并将其作为参数传递给URL配置。
path(常用):
<>中会匹配一个具体的数据,这个数据将会作为参数传递到视图函数当中
      path('page/<int:num>/', views.IndexViex.as_view(), name='页面'), #路由配置
      #参数一:路由将要拼接的url
      #参数二:指定路由的视图函数
      #参数一:别名
      #views视图函数
      def get(self, request,num=1): #num设置了默认值
re_path(使用正则表达式进行匹配):
用r''来标识正则表达式的文字, ^$匹配开头导结尾 (page/.?/)? page/后面匹配任意文本(除换行符),匹配多次,?可有可无,()?该段文本可有可无 post/ 必须存在的路径 (?P\d+)/ 这里使用了django中的专属语法, <>中匹配一个数据,这个数据将会作为参数传递到视图函数当中
      re_path(r'^(page/.*?/)?post/(?P<postid>\d+)/$', views.DetailViex.as_view(), name='文章'),
视图函数的创建
在viexs文件中创建与视图一一应的视图类,同时必须继承View视图类 get方法,因为是类方法索引必须有self,同时,必须有一个名为request消息的参数,这个参数承载了请求者的信息,我们可以对他进行响应处理,在这个方法中将会接收访问该URL时候的get请求,get请求会在进入url时发起( get请求也可以手动发起),多用于获取数据
class IndexViex(View):
    def get(self, request):
        return render(request, 'index.html', {})#向浏览器返回视图,响应数据
        #第一个参数是请求消息
        #第二个参数是指定所要显示的页面,这里是名为index的html网页文件返回到浏览器,(这里会在前面我们在settings中配置的模版文件夹中自动寻找,当根目录中的模版文件夹中没有该html文件时才会来到app的模版文件夹中寻找)
        #第三个参数是响应数据,一般为将要加载到网页中的动态数据,会在html中使用django模版语法进行加载
启动程序
若前面的配置的没有问题,这时候已经可以启动项目查看网页的大体形态了 这时候的页面还是静态的 打开控制台输入启动命令,启动程序
cd 项目文件夹
python manage.py runserver --post=8000
动态数据
数据库配置
在settings文件中设置数据库
默认数据库SQLite,SQLite 是一个轻量级的关系型数据库管理系统,它以文件形式存储数据库,并且不需要独立的数据库服务器进程。这使得 SQLite 在开发和测试阶段非常方便,因为它不需要额外的数据库服务器安装和配置。
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',  # 数据库引擎
        'NAME': BASE_DIR / 'db.sqlite3',  # 路径
    }
}
mysql数据库的配置方法
使用mysql需要额外导入一个包
pip install mysqlclient
导入后对settings中的DATABASES进行配置
DATABASES = {  # 配置数据库
        'default': {
            'ENGINE': 'django.db.backends.mysql',  # mysql数据库引擎
            'NAME': 'boke1',  # 数据库名
            'USER': 'root',  # 账号
            'PASSWORD': '123456',  # 密码
            'HOST': '127.0.0.1',  # url
            'PORT': '3306',  # 端口号
        }
    }
models模型配置
需要我们导入模型库,创建自己的模型类。 在这里写的代码会被转化为sql语句在数据库中创建数据表
from django.db import models#导入模型库
# Create your models here.
class Category(models.Model):#继承于models.Model
    cname = models.CharField(max_length=30, unique=True, verbose_name=u'类别名称')
    def __unicode__(self):
        return u'<Category:%s>' % self.cname
    class Meta:
        db_table = 't_category'  # 表名
        verbose_name_plural = u'类别'
class Tag(models.Model):
    tname = models.CharField(max_length=20, unique=True, verbose_name=u'标签')
    def __unicode__(self):
        return u'<Tag:%s>' % self.tname
    class Meta:
        db_table = 't_tag'
        verbose_name_plural = u'标签'
from ckeditor_uploader.fields import RichTextUploadingField
class Post(models.Model):
    title = models.CharField(max_length=100, unique=True, verbose_name=u'标题')
    desc = models.CharField(max_length=200, verbose_name=u'简介')
    content = RichTextUploadingField(null=True, blank=True, verbose_name=u'内容')  # 引入控件
    created = models.DateTimeField(auto_now_add=True, verbose_name=u'发帖时间')  # 当前时间
    modified = models.DateTimeField(auto_now=True, verbose_name=u'修改时间')  #
    isdelete = models.BooleanField(default=False, verbose_name=u'是否删除')
    category = models.ForeignKey(Category, on_delete=models.CASCADE, verbose_name=u'所属类别')
    tag = models.ManyToManyField(Tag, verbose_name=u'所属标签')
    words = models.CharField(max_length=15, verbose_name=u'字数')
    photos = models.CharField(max_length=300, verbose_name=u'封面图片')
    def __unicode__(self):
        return u'<Post:%s>' % self.title
    class Meta:
        db_table = 't_Post'
        verbose_name_plural = u'帖子'
class AdminUser(models.Model):
    aname = models.CharField(max_length=20, unique=True, verbose_name='名字')
    avatar = models.CharField(max_length=200, unique=True, verbose_name='头像')
    signature = models.CharField(max_length=100, unique=True, verbose_name='签名')
    announcement = models.CharField(max_length=200, unique=True, verbose_name='公告')
    steam = models.CharField(max_length=200, unique=True, verbose_name='steam链接')
    bilibili = models.CharField(max_length=200, unique=True, verbose_name='bilibili链接')
    github = models.CharField(max_length=200, unique=True, verbose_name='github链接')
    about = models.CharField(max_length=1000, null=True, blank=True, verbose_name=u'关于')
    banner = models.CharField(max_length=200, unique=True, verbose_name='横幅')
    def __unicode__(self):
        return u'<AdminUser:%s>' % self.aname
    class Meta:
        db_table = 't_AdminUser'
        verbose_name_plural = u'管理用户信息'
    verbose_name="名字"#相当于别名会在admin管理界面中使用
    def __unicode__(self):
        return u'<Post:%s>' % self.title #该数据表类在admin管理界面中的标题
数据字段的定意
 aname = models.CharField(max_length=20, unique=True, verbose_name='名字')#字符类型字段,max_length最大长度20,unique不可重复,
 created = models.DateTimeField(auto_now_add=True, verbose_name=u'发帖时间')  # 时间类型字段,auto_now_add自动添加会自动记录当前时间
 isdelete = models.BooleanField(default=False, verbose_name=u'是否删除')#布尔类型字段
 category = models.ForeignKey(Category, on_delete=models.CASCADE, verbose_name=u'所属类别')#外键
 tag = models.ManyToManyField(Tag, verbose_name=u'所属标签')#多对多类型字段
 content = RichTextUploadingField(null=True, blank=True, verbose_name=u'内容')  # 这里使用了引入的控件库,这个控件库可以使用makdown语法对数据进行编辑
迁移文件
完成数据库的配置后,输入命令创建数据库的迁移文件,执行迁移文件
python manage.py makemigrations #创建迁移文件
python manage.py migrate #执行迁移文件
这时候在根目录下就会生成一个db.sqlite3数据库文件 下载驱动,对数据库进行连接
后台管理系统
这里使用django自带的管理系统 在应用的admin文件夹中配置
from __future__ import unicode_literals
from django.contrib import admin
from .models import *
# Register your models here.
admin.site.register(Category)  # 注册到admin控制面板中
admin.site.register(Tag)
admin.site.register(Post)
admin.site.register(AdminUser)
并且在urls配置中
path('admin/', admin.site.urls),
添加管理用户
对数据库中的auth_user表添加默认管理员账户(我用的是PyCharm右侧的数据库栏手动添加的数据)
python manage.py collectstatic --noinput
python manage.py compress --force
登入管理页面http://127.0.0.1:8000/admin/ 输入你所设置的后台管理账户 添加数据库基础测试数据 在admin中我们可以对配置的数据库数据进行可视化管理
404跳转
在urls配置中添加这一条代码 这行代码会读取settings中的DEBUG配置(该配置为TRUE时),当我们访问不存在的网址时,就会进行跳转
if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
视图
在views文件中,我们需要书写代码逻辑对前端的数据进行响应 对库进行导入
import math#数学库
from django.core.paginator import Paginator #分页器
from django.http import HttpResponse, HttpResponseRedirect #响应
from django.shortcuts import render, redirect #渲染,重定向
from django.urls import reverse
from django.views import View  # 导入
from post.models import * #定义的全部模型类
类继承于View,定义视图类。 这是主页的响应类,这里使用render渲染视图
render(request,'要渲染的html文件,响应数据')
首页
渲染index.html文件 请求中的num会从url中得到 使用Paginator分页器,结果返回数据,postList当前页码的数据,page_list页面列表,currentNum当前页码 通过构建一个最大为9个索引的码列表,根据当前页面不断更改页码列表
# Create your views here.
class IndexViex(View):
    def get(self, request, num=1):
        num = int(num)  # 转型
        postList = Post.objects.all().order_by('-created')  # 查询所有的帖子信息,按照发帖时间排序
        page_obj = Paginator(postList, 10)  # 创建分页器对象,每一页显示一条记录
        page_post = page_obj.page(num)  # 获取num页的数据
        begin = int(num - math.ceil(10.0 / 2))  # 页码num在数组中的相对位置
        # print(begin)  # [-4,-3,-2,-1,0,1,2,3,4] 页面的相对位置?
        if begin < 1:  # 当前位置在1(数组后半段)之前,
            begin = 1  # 将当前位置变为1
        end = begin + 9
        if end > page_obj.num_pages:
            end = page_obj.num_pages  # 获取页码总数(最大页码)
        if end < 10:  #
            begin = 1
        else:
            begin = end - 9
        page_list = range(begin, end + 1)  # 构造一个最大为10的数组,并且里面的数字随着页面num的增大而变换,
        return render(request, 'index.html', {'postList': page_post, 'page_list': page_list, 'currentNum': num})
文章
渲染detail.html文件 在这里会通过postid帖子id进行查询获得帖子的内容数据
class DetailViex(View):
    def get(self, request, postid):  # 文章内容
        postid = int(postid)
        post_obj = Post.objects.get(id=postid)  # 条件查询id
        return render(request, 'detail.html', {'post_obj': post_obj})
分类
通过导入的模型类查询该类别的文章,显示在同一页面上
def getPostByCid(request, categorie):  # 分类
    # categoryid = int(category)
    c_post = Post.objects.filter(category__cname=categorie)  # 查询类别下的文章
    # print(c_post)
    return render(request, 'postlist.html', {'categorie': categorie, 'c_post': c_post})
归档
查询全部
def getPostArchives(request):
    c_post = Post.objects.all()  # 查询全部
    return render(request, 'archives.html', {'c_post': c_post})
标签
根据tag查询文章
def getPostTags(request, tag):
    c_post = Post.objects.filter(tag__tname=tag)  # 根据标签名查询
    return render(request, 'tags.html', {'tag': tag, 'c_post': c_post})
关于
读取关于页面的数据表,返回页面信息
def About(request):
    post_obj = AdminUser.objects.all()[0]
    return render(request, 'about.html', {'post_obj': post_obj})
404跳转
# def page_not_found(request, exception):  # 全局404处理函数
#     return redirect('11')  # 重定向回到主页            非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:https://cpxigxs.cn/2024/04/20/90/
    
            
 
										
										
										
    
共有 0 条评论