基于Django框架的博客平台开发与实现(三)

目录

感谢

摘要

主页实现

通用模板实现

Bug出现

右侧关于博主信息动态显示实现

 右侧日志类别动态显示实现

右侧友情链接动态显示实现

 后续


感谢

感谢锋哥的指导。由于我使用的是MySQL 5.7版本,因此对项目代码进行了相应的调整。详细修改过程及源代码,请参考锋哥在B站发布的视频教程:
基于Django框架的博客系统的开发与实现https://www.bilibili.com/video/BV1GJ6uYpEwK

在此,也向锋哥表示诚挚的谢意!

摘要

        本项目利用Django框架,结合现代Web开发的最佳实践,构建了一个功能全面、易于扩展的博客平台。通过此项目,开发者可以学习到如何使用Django进行模型设计、视图逻辑编写、模板渲染以及静态文件管理等核心技能,同时掌握了用户认证、文章管理等博客系统必备功能的实现方法。

项目代码地址:

Vlog_systemGitCode是面向全球开发者的开源社区,包括原创博客,开源代码托管,代码协作,项目管理等。与开发者社区互动,提升您的研发效率和质量。https://gitcode.com/m0_50313048/Vlog_system/tree/master

上一篇: 

基于Django框架的博客平台开发与实现(二)-优快云博客文章浏览阅读533次,点赞22次,收藏11次。本项目利用Django框架,结合现代Web开发的最佳实践,构建了一个功能全面、易于扩展的博客平台。通过此项目,开发者可以学习到如何使用Django进行模型设计、视图逻辑编写、模板渲染以及静态文件管理等核心技能,同时掌握了用户认证、文章管理等博客系统必备功能的实现方法。项目代码地址:GitCode是面向全球开发者的开源社区,包括原创博客,开源代码托管,代码协作,项目管理等。与开发者社区互动,提升您的研发效率和质量。上一篇:基于Django框架的博客平台开发与实现(一) https://blog.youkuaiyun.com/m0_50313048/article/details/146123382

主页实现

通用模板实现

在技术架构层面,博客网站的全局导航栏、侧边功能栏、页脚信息等公共组件存在高度复用特性。基于Django模板继承机制,我们采用组件化开发策略:建立基模板(base.html)预置公共HTML结构,通过{% block content %}定义可扩展区域。各子模板通过{% extends 'base.html' %}语法继承基模板,仅在特定区块重写个性化内容。这种实现方式符合DRY原则,既保障了页面风格统一性,又使模板维护效率提升,同时为后续功能扩展预留标准接口。 

templates目录下新建通用模版文件base.html,这里的block标签用于定义一个可供子模板覆盖的区域

<!DOCTYPE html>
<html lang="en">
<head>
    {% load static %}
    <meta charset="UTF-8">
    <title>{% block title %}博客首页{% endblock %}-Powered by python222</title>
    <link href="{% static "bootstrap-5.3.3/css/bootstrap.css" %}" rel="stylesheet"/>
    <link href="{% static "css/blog.css" %}" rel="stylesheet"/>
    <script src="{% static "bootstrap-5.3.3/js/bootstrap.js" %}"></script>
    <script src="{% static "js/jquery-1.11.2.min.js" %}"></script>
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-4">
            <img style="width: 326px;height: 60px" alt="开源博客系统" src="{% static "images/logo.png" %}">
        </div>
        <div class="col-md-8">
            <iframe style="float: right;" width="400" scrolling="no" height="60" frameborder="0"
                    allowtransparency="true" src="http://i.tianqi.com/index.php?c=code&id=12&icon=1&num=5&py=zhanggongqu"></iframe>
        </div>
    </div>
    <div class="row">
        <div class="col-md-12" style="padding-top: 10px;padding-bottom: 10px">
            <nav class="navbar navbar-expand-lg bg-body-tertiary">
                <div class="container-fluid">
                    <a class="navbar-brand" href="{% url 'article' id 1 0 %}">博客首页</a>
                    <button class="navbar-toggler" type="button" data-bs-toggle="collapse"
                            data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent"
                            aria-expanded="false" aria-label="Toggle navigation">
                        <span class="navbar-toggler-icon"></span>
                    </button>
                    <div class="collapse navbar-collapse" id="navbarSupportedContent">
                        <ul class="navbar-nav me-auto mb-2 mb-lg-0">
                            <li class="nav-item">
                                <a class="nav-link" href="/album/1/1.html">我的相册</a>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link" href="/user/about/1.html">关于我</a>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link" href="/message/1/1.html">留言</a>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link" href="/admin/">博客后台管理</a>
                            </li>
                        </ul>
                        <form class="d-flex" role="search" method="post" action="/search/1"
                              onsubmit="return checkSearchForm()">
                            {% csrf_token %}
                            <input class="form-control me-2" type="search" placeholder="请输入搜索内容..."
                                   aria-label="Search" name="v" id="v" value="{{ v }}">
                            <button class="btn btn-outline-success" type="submit">Search</button>
                        </form>
                    </div>
                </div>
            </nav>
        </div>
    </div>

    <div class="row">
        <div class="col-md-9">
            {% block content %}{% endblock %}
        </div>
        <div class="col-md-3">
            <div class="data_list">
                <div class="data_list_title">
                    <img src="/static/images/user_icon.png">
                    关于我
                </div>
                <div class="user_image">
                    <img src="/media/avatar/222.jpg">
                </div>
                <div class="nickName">小龙ssss</div>
                <div class="userSign">(3年python新手,小程序员)</div>
            </div>

            <div class="data_list">
                <div class="data_list_title">
                    <img src="{% static 'images/byType_icon.png' %}"/>
                    按日志类别
                </div>
                <div class="datas">
                    <ul>

                        <li><span><a href="/1/1/1.html">Python基础</a></span></li>

                        <li><span><a href="/1/1/2.html">数据分析</a></span></li>

                        <li><span><a href="/1/1/3.html">人工智能</a></span></li>


                    </ul>
                </div>
            </div>


            <div class="data_list">
                <div class="data_list_title">
                    <img src="{% static 'images/link_icon.png' %}"/>
                    友情链接
                </div>
                <div class="datas">
                    <ul>
                        <li><span><a href="http://www.java1234.com/" target="_blank">java知识分享网</a></span></li>

                        <li><span><a href="http://blog.java1234.com/index.html" target="_blank">java开源博客</a></span>
                        </li>
                    </ul>
                </div>
            </div>
        </div>
    </div>

    <div class="row">
        <div class="col-md-12">
            <div align="center" style="padding-top: 120px">
                <span style="float: left;">Powered by <a href="http://python222.com"
                                                         target="_blank">小龙ssss</a></span>
                Copyright © 2023-2025 小龙ssss 版权所有 
            </div>
        </div>
    </div>
</div>
{% block script %}{% endblock %}
<script>
    function checkSearchForm() {
        var v = $("#v").val();
        if (v == null || v == '') {
            alert("请输入搜索内容!");
            return false;
        }
        return true;
    }
</script>
</body>
</html>

 templates下再新建一个article.html博客页面,通过extends继承base.html。

通过block标签重写父模板:

{% extends "base.html" %}
{% load static %}
{% block content %}
    <div class="data_list">
        <div class="data_list_title">
            <img src="{% static 'images/list_icon.png' %}"/>
            博客列表
        </div>
        <div class="datas">
            博客列表内容
        </div>
    </div>
{% endblock %}

article / views.py 定义article函数,来实现查询帖子信息,转发帖子页面:

def article(request, id, page, typeId):
    """
    查询帖子信息
    :param request:
    :return:
    """
    print(id, page, typeId)
    return render(request, 'article.html', locals())

 article / urls.py下再增加映射:

# 文章列表
path('<int:id>/<int:page>/<int:typeId>.html', article, name="article"),

 用户登录成功后的逻辑,我们改成 重定向到帖子页面:

user/urls.py:

# from django.shortcuts import redirect
# from django.urls import reverse
kwargs = {'id': request.user.id, 'page': 1, 'typeId': 0}
return redirect(reverse('article', kwargs=kwargs))

 我们启动测试下,登录后,跳转到帖子主页:

 

Bug出现

这里可能会出现一个Bug,即:

GET /media/avatar/222.jpg HTTP/1.1" 404

也就是media底下的图片加载不出来。

在主urls.py文件中加入如下代码,确保Django能够正确处理媒体文件请求。注意这段代码应该只在DEBUG=True (settings.py中设置)时生效。

from django.conf import settings
from django.conf.urls.static import static

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

如果还不行,在settings.py中,数组TEMPLATES的context_processors中添加一行代码:

# 添加以下这行
'django.template.context_processors.media',

应该就能解决这个问题,如果还有bug,我也无能为力。

右侧关于博主信息动态显示实现

 

要求不同的用户显示不一样,有头像的用户用头像,没有头像的用户用默认的图片。

我们后端从数据库获取数据,然后动态显示到页面上。

(数据库里,我们先直接加上数据

avatar:avatar/xlsss.png,

name:小龙ssss,

introduce:3年python新手,小程序员)

用户登录后,会把用户信息直接存会话中,所以页面可以直接获取。在base.html中修改:

<div class="data_list">
	<div class="data_list_title">
		<img src="/static/images/user_icon.png">
		关于我
	</div>
	<div class="user_image">
		{% if user.avatar %}
			<img src="{{ user.avatar.url }}"/>
		{% else %}
			<img src="{% static 'images/user.jpg' %}"/>
		{% endif %}
	</div>
	<div class="nickName">{{ user.name }}</div>
	<div class="userSign">({{ user.introduce }})</div>
</div>

 右侧日志类别动态显示实现

 

根据多用户博客系统的业务需求,每个日志分类需明确归属特定用户。为此我们在分类模型设计中添加用户外键字段(user),通过外键关联实现用户与分类的所属关系绑定,确保数据维度的用户隔离性。。

article/models.py

# from user.models import MyUser
user = models.ForeignKey(MyUser, on_delete=models.CASCADE, verbose_name='用户')

 再通过makemigrations和migrate,生成数据库表:

makemigrations article
# 然后选1

 外键连接主键,这里我们的id是主键,值为1,主键是什么就输入什么

migrate article

 因为好几个页面都要用到这个类别显示数据,所以我们把这些数据放到context全局上下文中,来实现 复用,也方便维护。

article下新建mycontext.py

from article.models import ArticleType
def getAllArticleType(request):
    """
    获取所有帖子类别
    :param request:
    :return:
    """
    return {"articleTypeList": ArticleType.objects.all()}

settings.py里配置下全局上下文,

TEMPLATES里添加,

# 此处添加新的全局上下文
'article.mycontext.getAllArticleType',

 修改base.html:

			<div class="datas">
                    <ul>
                        {% for type in articleTypeList %}
                            <li><span><a href="{% url 'article' id 1 type.id %}">{{ type.name }}</a>
                            </span></li>
                        {% endfor %}
                    
                    </ul>
                </div>

 运行:

 

右侧友情链接动态显示实现

link / models.py 里新建友情链接类:

from django.db import models
from user.models import MyUser


class LinkInfo(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField('链接名称', max_length=50)
    url = models.CharField('链接地址', max_length=200)
    remark = models.CharField('备注', max_length=500, blank=True)
    user = models.ForeignKey(MyUser, on_delete=models.CASCADE, verbose_name='用户')

    def __str__(self):
        return str(self.name)

    class Meta:
        verbose_name = '友情链接管理'

    verbose_name_plural = '友情链接管理'

 再通过makemigrations,migrate,生成数据库表,

makemigrations link
migrate

 新建查询,添加以下数据:

INSERT INTO `link_linkinfo` (`id`, `name`, `url`, `remark`, `user_id`)
VALUES('1','java知识分享网','http://www.java1234.com/','好网站','1');
INSERT INTO `link_linkinfo` (`id`, `name`, `url`, `remark`, `user_id`)
VALUES('2','java开源博客','http://blog.java1234.com/index.html','好博客','1');

 link模块下新建mycontext.py

from link.models import LinkInfo

def getAllLink(request):
    """
    获取所有友情链接
    :param request:
    :return:
    """
    return {"linkList": LinkInfo.objects.all()}

 settings.py里配置下全局上下文, TEMPLATES里添加,

'link.mycontext.getAllLink'

 base.html修改:

<ul>
    {% for link in linkList %}
        <li><span><a href="{{ link.url }}" target="_blank">{{ link.name }}</a></span>
        </li>
    {% endfor %}
</ul>

 后续

持续开发中。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值