IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> 开发牛逼,Django框架一周极速开发博客系统 -> 正文阅读

[Python知识库]开发牛逼,Django框架一周极速开发博客系统

众所周知,Python是最容易上手的语言

众所周知,Django是Python功能最全的Web框架之一

Django一开始其实就是专门为了CMS而开发出来的,这就意味着用Django开发一个博客将变得非常容易。

本文就带大家快速的实现一个简单的博客系统:

本系统将包含博客的三个核心功能模块:文章管理,用户注册登录管理以及评论管理。

废话不多说,下面直接开始:

工欲善其事必先利其器,首先我们先准备下开发软件和环境。

开发环境准备

  • 服务端:Python 3.8
  • Web框架:Django 3.2
  • 数据库:MySQL mysql-8.0.13-winx64
  • 开发工具: Pycharm

创建Django博客项目

1.新建一个空白Pycharm项目文件夹比如:E:\PycharmProjects

2.打开Pycharm,从Pycharm打开我们刚刚创建的空白文件夹:PycharmProjects

3.在Pycharm的命令行输入界面输入创建Django项目的命令:

django-admin startproject DjangoBlog

?至此我们创建一个新的项目: DjangoBlog

数据库创建和连接配置

1. 数据库创建

Django只能操作到数据表级别,不能操作到数据库级别,所以需要手工创建一个数据库:djangoblog

我们可以通过命令行创建一个数据库:

1) 进入mysql安装文件夹的bin 子文件夹目录:

比如:D:\Program Files\mysql-8.0.13-winx64\bin

2) 连接数据库:

mysql -u root -p Enter password:******

3) 连接登录成功后通过命令创建一个数据库:?djangoblog

CREATE DATABASE IF NOT EXISTS?djangoblog?DEFAULT CHARSET utf8;

或者通过其他的数据库管理工具,比如SQLlog工具创建一个数据库: djangoblog

创建完成后可以通过SQLlog看到对应数据库。

?

2.?Django数据库连接配置

Django使用MySQL需要mysql 驱动,如果你没安装 mysql 驱动,可以执行以下命令安装:

pip install pymysql

?1) 进入DjangoBlog 项目下的DjangoBlog文件夹,打开setting.py 文件,找到DATABASES配置项:

2) 修改DATABSES配置项为如下内容:

DATABASES = {
 'default': {
 'ENGINE': 'django.db.backends.mysql', # 数据库引擎
 'NAME': 'djangoblog', # 数据库名称
 'HOST': '127.0.0.1', # 数据库地址,本机 ip 地址 127.0.0.1 
 'PORT': 3306, # 端口 
 'USER': 'root', # 数据库用户名
 'PASSWORD': '123456', # 数据库密码
 }
}

3) Django 使用 pymysql 模块连接 mysql 数据库:

在与 settings.py 同级目录下的 __init__.py 中引入模块和进行配置

import pymysql 
pymysql.install_as_MySQLdb()

?至此,我们创建了一个Django项目DjangoBlog用于我们后续的博客系统开发的程序编写,同时为此项目创建了一个MySQL数据库:djangoblog用于我们程序开发过程中的数据存放和处理。

实现文章管理功能

文章管理包括如下几个功能:

  • 文章列表显示
  • 文章详情查看
  • 文章的创建
  • 文章的更新和删除

创建APP

在Django中的一个app代表一个功能模块,Django 规定,如果要使用模型,必须要创建一个 app。

在命令行中输入python manage.py startapp article指令,创建名为article的app:

python manage.py startapp article

用于实现文章管理功能

?

注册APP

在 settings.py 中找到INSTALLED_APPS这一项,将新创建的article添加到项目的App列表,如下:

?

定义模型

我们之前创建了一个空白的数据库djangoblog,这一步我们通过Django的模型来完成数据库表的创建.

因为Django对模型和目标数据库之间有自身的映射规则,如果自己在数据库中创建数据表,可能不一定符合Django的建表规则,从而导致模型和目标数据库无法建立通信联系.

所以最好我们在Django项目中还是通过Django模型来创建对应数据库表

本步骤我们定义两个模型:

打开article/models.py文件,输入如下代码:

from django.db import models
# 导入内建的User模型。
from django.contrib.auth.models import User
# timezone 用于处理时间相关事务。
from django.utils import timezone

# 博客文章数据模型
class ArticlePost(models.Model):
    # 文章作者。参数 on_delete 用于指定数据删除的方式
    author = models.ForeignKey(User, on_delete=models.CASCADE)

    # 文章标题。models.CharField 为字符串字段,用于保存较短的字符串,比如标题
    title = models.CharField(max_length=100)

    # 文章正文。保存大量文本使用 TextField
    body = models.TextField()

    # 文章创建时间。参数 default=timezone.now 指定其在创建数据时将默认写入当前的时间
    created = models.DateTimeField(default=timezone.now)

    # 文章更新时间。参数 auto_now=True 指定每次数据更新时自动写入当前时间
    updated = models.DateTimeField(auto_now=True)

    # 内部类 class Meta 用于给 model 定义元数据
    class Meta:
        # ordering 指定模型返回的数据的排列顺序
        # '-created' 表明数据应该以倒序排列
        ordering = ('-created',)

    # 函数 __str__ 定义当调用对象的 str() 方法时的返回值内容
    def __str__(self):
        # return self.title 将文章标题返回
        return self.title

接着在命令行中输入命令让 Django知道我们自定义模型有一些变更,并根据我们自定义app的模型生成创建数据表的脚本:

python manage.py makemigrations

最后通过命令创建app模型对应的数据库表:

python manage.py migrate

?执行成功后我们可以在数据库表中看到Django自动生成了数据库表如下图:

?至此,我们已经成功创建好了APP并完成了用于文章管理的数据库表创建,下面我们利用Django函数和模板分别实现文章管理的各个具体的功能。

Django 中视图的概念是「一类具有相同功能和模板的网页的集合。

比如,在一个博客应用中,你可能会创建如下几个视图:

博客首页:展示最近的几项内容。

内容“详情”页:详细展示某项内容。

评论处理器:用于响应为一项内容添加评论的操作。

这些需求都靠视图(View)来完成。

网页都是从视图派生而来。每一个视图表现为一个简单的Python函数,它必须要做的只有两件事:返回一个包含被请求页面内容的 HttpResponse对象,或者抛出一个异常,比如 Http404 。

视图函数中的request与网页发来的请求有关,里面包含get或post的内容、用户浏览器、系统等信息。Django调用article_list函数时会返回一个含字符串的 HttpResponse对象。

文章列表显示

定义视图函数

在article/views.py文件中创建article_list视图函数用于文章列表展示:

from django.shortcuts import render
# 导入数据模型ArticlePost
from .models import ArticlePost

def article_list(request):
    # 取出所有博客文章
    articles = ArticlePost.objects.all()
    # 需要传递给模板(templates)的对象
    context = { 'articles': articles }
    # render函数:载入模板,并返回context对象
    return render(request, 'article/list.html', context)

?配置访问路由URL

url可以理解为访问网站时输入的网址链接,配置好url后Django才知道怎样定位app。

打开DjangoBlog目录下的urls.py,增加以下代码:

from django.contrib import admin
# 记得引入include
from django.urls import path, include

# 存放映射关系的列表
urlpatterns = [
    path('admin/', admin.site.urls),

    # 新增代码,配置app的url
    path('article/', include('article.urls', namespace='article')),
]

以上代码通过path将根路径为article的访问都分发给article这个app去处理。但是app通常有多个页面地址,因此还需要app自己也有一个路由分发。

接着在article文件夹中创建urls.py,在里面输入:

from django.urls import path
# 引入views.py
from . import views

# 正在部署的应用的名称
app_name = 'article'

urlpatterns = [
    # path函数将url映射到视图
    path('article-list/', views.article_list, name='article_list'),
]

?模板和前端静态资源准备及配置

本文前后端不分离,前端框架选用当前比较受欢迎的Bootstrap.

最新版本的Bootstrap :下载地址并解压。

在项目根目录下新建一个文件夹static用于存放前端模板静态资源,同时将相关前端资源导入文件夹.

把刚才解压出来的css和js两个文件夹复制进去。

因为bootstrap.js依赖 jquery.js 和 popper.js 才能正常运行,因此这两个文件我们也需要一并下载保存。

附上官网下载链接(进入下载页面,复制粘贴代码到新文件即可):

jquery.js

popper.js

完成后Static文件夹结构如下图:

Django模板创建:

在根目录下的templates/中,新建三个文件:

  • base.html是整个项目的模板基础,所有的网页都从它继承;
  • header.html是网页顶部的导航栏;
  • footer.html是网页底部的注脚。

分别编写三个静态HTML文件代码如下:

templates/base.html:

<!--    载入静态文件-->
{% load static %}

<!DOCTYPE html>
<!-- 网站主语言 -->
<html lang="zh-cn">
<head>
    <!-- 网站采用的字符编码 -->
    <meta charset="utf-8">
    <!-- 预留网站标题的位置 -->
    <title>{% block title %}{% endblock %}</title>
    <!-- 引入bootstrap的css文件 -->
    <link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap.min.css' %}">
</head>

<body>
<!-- 引入导航栏 -->
{% include 'header.html' %}
<!-- 预留具体页面的位置 -->
{% block content %}{% endblock content %}
<!-- 引入注脚 -->
{% include 'footer.html' %}
<!-- bootstrap.js 依赖 jquery.js 和popper.js,因此在这里引入 -->
<script src="{% static 'jquery/jquery-3.6.0.js' %}"></script>

<!--
    popper.js 采用 cdn 远程引入,意思是你不需要把它下载到本地。
    在实际的开发中推荐静态文件尽量都使用 cdn 的形式。
    教程采用本地引入是为了让读者了解静态文件本地部署的流程。
-->
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1-lts/dist/umd/popper.min.js"></script>

<!-- 引入bootstrap的js文件 -->
<script src="{% static 'bootstrap/js/bootstrap.min.js' %}"></script>
</body>

</html>
templates/header.html:
<!-- 定义导航栏 -->
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
    <div class="container">
        <!-- 导航栏商标 -->
        <a class="navbar-brand" href="#">我的博客</a>
            <div class="form-inline">
                <form role="search" class="navbar-form-custom" method="post" action="#">
                    <div class="form-group">
                        <input type="text" placeholder="Search..." class="form-control" name="top-search" id="top-search">
                    </div>
                </form>
            </div>
        <!-- 导航入口 -->
        <div>
            <ul class="navbar-nav">
                <!-- 条目 -->
                <li class="nav-item">
                    <a class="nav-link" href="#">文章</a>
                </li>
            </ul>
        </div>
    </div>
</nav>

templates/header.html:

<!-- 定义导航栏 -->
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
    <div class="container">
        <!-- 导航栏商标 -->
        <a class="navbar-brand" href="#">我的博客</a>
            <div class="form-inline">
                <form role="search" class="navbar-form-custom" method="post" action="#">
                    <div class="form-group">
                        <input type="text" placeholder="Search..." class="form-control" name="top-search" id="top-search">
                    </div>
                </form>
            </div>
        <!-- 导航入口 -->
        <div>
            <ul class="navbar-nav">
                <!-- 条目 -->
                <li class="nav-item">
                    <a class="nav-link" href="#">首页</a>
                </li>
            </ul>
        </div>
    </div>
</nav>

templates/footer.html:

{% load static %}
<!-- Footer -->
<div>
    <br><br><br>
</div>
<footer class="py-3 bg-dark fixed-bottom">
    <div class="container">
        <p class="m-0 text-center text-white">Copyright &copy; DjangoBlog 2021</p>
    </div>
</footer>

上述三个文件是网站页面的通用组件模块,基本上每个页面都不会变,我们把他们独立出来。

我们编写Django模板时可以直接继承对应的通用模板组件。

下面我们编写一个博客列表的显示模板用于显示博客文章列表:

在templates文件夹中新建一个article文件夹用于存放文章展示相关的HTML模板,然后在article文件中创建一个list.html模板文件。

模板所在路径article/list.html 对应我们的之前在article/views中视图函数article_list定义的载入模板地址。

?模板article/list.html编写代码如下:

<!-- extends表明此页面继承自 base.html 文件 -->
{% extends "base.html" %}
{% load static %}

<!-- 写入 base.html 中定义的 title -->
{% block title %}
首页
{% endblock title %}

<!-- 写入 base.html 中定义的 content -->
{% block content %}
<!-- 定义放置文章标题的div容器 -->
<div class="container">
    {% for article in articles %}
    <div class="row mt-2">
        <!-- 文章内容 -->
        <div class="col-sm-12">
            <!-- 卡片容器 -->
            <div class="card h-100">
                <!-- 标题 -->
<!--                <h4 class="card-header">{{ article.title }}</h4>-->
                <!-- 摘要 -->
                <div class="card-body">
                    <h4 class="card-title">{{ article.title }}</h4>
                    <p class="card-text">{{ article.body|slice:'100' }}...</p>
                    <a href="{% url 'article:article_detail' article.id %}"  class="card-link">阅读本文</a>
                </div>
            </div>
        </div>
    </div>
    {% endfor %}
</div>

{% endblock content %}

代码说明:

当我们通过url访问list.html时,顶部的{% extends "base.html" %}告诉Django:“这个文件是继承自base.html”
Django会去渲染base.html文件:
其中的{% include 'header.html' %}表明这里需要加入header.html的内容
{% include 'footer.html' %}加入footer.html的内容
{% block content %}{% endblock content %}表明这里应该加入list.html中的对应块的内容

?

?博客文章新建功能

定义视图函数

在article/views.py文件中创建article_create视图函数用于新建文章:

def article_create(request):
    if request.method == 'POST':
        new_article_title = request.POST.get('title')
        new_article_body = request.POST.get('body')
        new_article_author = User.objects.get(id=1)
        models.ArticlePost.objects.create(title=new_article_title, body=new_article_body,author=new_article_author)
        return redirect("article:article_list")
    # 如果用户请求获取数据
    else:
        return render(request, 'article/create.html')

配置访问路由URL

在article/urls.py 中增加写文章的路由

urlpatterns = [
# 写文章
path('article-create/', views.article_create, name='article_create'),
]

创建前端模板

首先我们新建一个create.html的文件用于新建文章,在此文件中我们将定义一个新建文章的表单,用于调用我们前面定义的创建文章的视图函数,同时将数据传递到数据库。

<!-- extends表明此页面继承自 base.html 文件 -->
{% extends "base.html" %} {% load static %}
<!-- 写入 base.html 中定义的 title -->
{% block title %} 写文章 {% endblock title %}
<!-- 写入 base.html 中定义的 content -->
{% block content %}
<!-- 写文章表单 -->
<div class="container">
    <div class="row">
        <div class="col-12">
            <br>
            <!-- 提交文章的表单 -->
            <form method="post" action=".">
                <!-- Django中需要POST数据的地方都必须有csrf_token -->
                {% csrf_token %}
                <!-- 文章标题 -->
                <div class="form-group">
                    <!-- 标签 -->
                    <label for="title">文章标题</label>
                    <!-- 文本框 -->
                    <input type="text" class="form-control" id="title" name="title">
                </div>
                <!-- 文章正文 -->
                <div class="form-group">
                    <label for="body">文章正文</label>
                    <!-- 文本区域 -->
                    <textarea type="text" class="form-control" id="body" name="body" rows="12"></textarea>
                </div>
                <!-- 提交按钮 -->
                <button type="submit" class="btn btn-primary">完成</button>
            </form>
        </div>
    </div>
</div>
{% endblock content %}

接着我们在导航栏对应的模板header.html中添加一个创建文章的入口

<!-- 导航入口 -->
<div>
??? <ul class="navbar-nav">
??????? <li class="nav-item">
??????????? <a class="nav-link" href="{% url 'article:article_create' %}">创作</a>
??????? </li>
??????? <li class="nav-item">
??????????? <a class="nav-link" href="{% url 'article:article_list' %}">首页</a>
??????? </li>
??? </ul>
</div>

?

博客文章详情显示功能

?定义视图函数

在article/views.py文件中创建 article_detail 视图函数用于显示文章:

# 文章详情
def article_detail(request, id):
    # 取出相应的文章
    article = ArticlePost.objects.get(id=id)

    # 需要传递给模板的对象
    context = { 'article': article }
    # 载入模板,并返回context对象
    return render(request, 'article/detail.html', context)

配置访问路由URL

在article/urls.py 中显示文章的路由

urlpatterns = [
# 写文章
path('article-create/', views.article_create, name='article_create'),
# 文章详情
path('article-detail/<int:id>/', views.article_detail, name='article_detail'),
]

创建前端模板

首先我们新建一个detail.html的文件用于文章详情显示。

<!-- extends表明此页面继承自 base.html 文件 -->
{% extends "base.html" %}
{% load static %}

<!-- 写入 base.html 中定义的 title -->
{% block title %}
文章详情
{% endblock title %}

<!-- 写入 base.html 中定义的 content -->
{% block content %}
<!-- 文章详情 -->
<div class="container">
    <div class="row">
        <!-- 标题及作者 -->
        <h1 class="col-12 mt-4 mb-4">{{ article.title }}</h1>
        <div class="col-12 alert alert-primary">
            <a>作者:{{ article.author }}</a>
            <a>{{ article.created|date:'Y-m-d H:i:s' }}</a>
        </div>
        <!-- 文章正文 -->
        <div class="col-12">
            <p>{{ article.body }}</p>
        </div>
    </div>
</div>

?博客文章更新和删除

?定义视图函数

在article/views.py文件中创建article_create视图函数用于显示文章:

# 删文章
def article_delete(request, id):
    # 根据 id 获取需要删除的文章
    article = ArticlePost.objects.get(id=id)
    # 调用.delete()方法删除文章
    article.delete()
    # 完成删除后返回文章列表
    return redirect("article:article_list")

# 更新文章

def article_update(request, id):
    # # 获取需要修改的具体文章对象
    article = ArticlePost.objects.get(id=id)

    # 判断用户是否为 POST 提交表单数据
    if request.method == "POST":
        new_article_title = request.POST.get('title')
        new_article_body = request.POST.get('body')
        article.title = new_article_title
        article.body = new_article_body
        article.save()
        # 完成后返回到修改后的文章中。需传入文章的 id 值
        return redirect("article:article_detail", id=id)
    else:
        # 赋值上下文,将 article 文章对象也传递进去,以便提取旧的内容
        context = {'article': article}
        return render(request, 'article/update.html', context)

配置访问路由URL

在article/urls.py 中显示文章的路由

urlpatterns = [
    url(r'^$', views.article_list),
    # path函数将url映射到视图
    path('article-list/', views.article_list, name='article_list'),
    # 文章详情
    path('article-detail/<int:id>/', views.article_detail, name='article_detail'),
    # 写文章
    path('article-create/', views.article_create, name='article_create'),
    # 删除文章
    path('article-delete/<int:id>/', views.article_delete, name='article_delete'),
    # 更新文章
    path('article-update/<int:id>/', views.article_update, name='article_update'),
]

创建前端模板

首先我们新建一个update.html的文件用于文章更新。

{% extends "base.html" %} {% load static %}
{% block title %} 更新文章 {% endblock title %}
{% block content %}
<div class="container">
    <div class="row">
        <div class="col-12">
            <br>
            <form method="post" action=".">
                {% csrf_token %}
                <div class="form-group">
                    <label for="title">文章标题</label>
                    <!-- 在 value 属性中指定文本框的初始值为旧的内容,即 article 对象中的 title 字段 -->
                    <input type="text" class="form-control" id="title" name="title" value="{{ article.title }}">
                </div>
                <div class="form-group">
                    <label for="body">文章正文</label>
                    <!-- 文本域不需要 value 属性,直接在标签体中嵌入数据即可 -->
                    <textarea type="text" class="form-control" id="body" name="body" rows="12">{{ article.body }}</textarea>
                </div>
                <button type="submit" class="btn btn-primary">完成</button>
            </form>
        </div>
    </div>
</div>
{% endblock content %}

更新和删除文章的入口都包含在Detail.html 中,我们修改Detail.html代码如下:

<!-- extends表明此页面继承自 base.html 文件 -->
{% extends "base.html" %}
{% load static %}

<!-- 写入 base.html 中定义的 title -->
{% block title %}
文章详情
{% endblock title %}

<!-- 写入 base.html 中定义的 content -->
{% block content %}
<!-- 文章详情 -->
<div class="container">
    <div class="row">
        <!-- 标题及作者 -->
        <h1 class="col-12 mt-4 mb-4">{{ article.title }}</h1>
        <div class="col-12 alert alert-primary">
            <a>作者:{{ article.author }}</a>
            <a>{{ article.created|date:'Y-m-d H:i:s' }}</a>
            · <a href="#" data-toggle="modal" data-target="#myModal">删除文章</a>
            · <a href="{% url "article:article_update" article.id %}">编辑文章</a>
        </div>
        <!-- 文章正文 -->
        <div class="col-12">
            <p>{{ article.body }}</p>
        </div>
    </div>
</div>

<!-- 模态框 -->
<div class="modal fade " id="myModal">
    <div class="modal-dialog modal-dialog-centered modal-sm">
        <div class="modal-content">
            <!-- 模态框头部 -->
            <div class="modal-header">
                <h4 class="modal-title">确认删除</h4>
                <button type="button" class="close" data-dismiss="modal">&times;</button>
            </div>
            <!-- 模态框主体 -->
            <div class="modal-body">
                确认删除文章?
            </div>
            <!-- 模态框底部 -->
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
                <button type="button" class="btn btn-primary" data-dismiss="modal"
                        onclick="confirm_delete()">
                确定
                </button>
            </div>
        </div>
    </div>
</div>
<script>
    // 删除文章的函数
    function confirm_delete() {
             location.href='{% url "article:article_delete" article.id %}'
    }
</script>

{% endblock content %}

?


?至此,我们已经实现了博客管理系统文章的新建,更新,删除和展示功能。

接下来有时间我们继续更新用户注册,登录以及评论管理功能。

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-09-24 10:31:00  更:2021-09-24 10:33:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 16:42:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码