前端Python应用指南(四)Django实战:创建一个简单的博客系统
《写给前端的python应用指南》系列:
- (一)快速构建 Web 服务器 - Flask vs Node.js 对比
- (二)深入Flask:理解Flask的应用结构与模块化设计
- (三)Django vs Flask:哪种框架适合构建你的下一个Web应用?
在前几篇博文中,我们讨论了Flask和Django这两大Python Web框架,并通过对比分析了它们的优缺点和适用场景。在本篇博文中,我将通过实际操作,使用Django框架创建一个简单的博客系统。这个系统将包含基本的功能,如文章展示、文章发布、编辑和删除。通过这篇博文,你将更深入地理解Django框架的核心功能,并能够上手开发自己的Web应用。
一、项目简介
目标是创建一个简单的博客系统,具备以下功能:
- 文章展示:展示所有博客文章。
- 文章创建:允许用户创建新的文章。
- 文章编辑:用户可以编辑已有的文章。
- 文章删除:用户可以删除文章。
在此过程中,将使用Django的MVC(Model-View-Controller)架构来组织代码,利用Django的内置功能快速搭建系统。
二、创建项目和应用
2.1 安装Django
首先,你需要确保已安装了Django。如果尚未安装,可以通过以下命令安装:
pip install django
2.2 创建Django项目
在终端中执行以下命令,创建一个新的Django项目:
django-admin startproject blog_project
cd blog_project
这将会创建一个名为blog_project
的文件夹,并在其中生成Django项目的基本结构。
2.3 创建Django应用
在Django中,应用(App)是一个可以独立工作的模块,可以包含模型、视图、URL配置等。接下来我们创建一个名为blog
的应用来处理博客的相关逻辑:
python manage.py startapp blog
执行后,Django将在项目目录下生成一个blog
目录,其中包含了应用的基本文件结构。
2.4 注册应用
在项目的settings.py
文件中,找到INSTALLED_APPS
列表,并将blog
应用添加到该列表中:
INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','blog', # 添加这行
]
三、定义数据模型
在Django中,模型(Model)是数据库的映射,它定义了数据库表的结构以及与数据交互的方式。接下来,我们将定义一个简单的Post
模型,用来表示博客文章。
3.1 编辑模型
在blog/models.py
文件中,添加以下代码来定义Post
模型:
from django.db import modelsclass Post(models.Model):title = models.CharField(max_length=200) # 文章标题content = models.TextField() # 文章内容created_at = models.DateTimeField(auto_now_add=True) # 文章创建时间updated_at = models.DateTimeField(auto_now=True) # 文章更新时间def __str__(self):return self.title
title
: 存储文章标题,使用CharField
,并设置最大长度。content
: 存储文章内容,使用TextField
,适合存储较长的文本。created_at
: 存储文章的创建时间,使用DateTimeField
并设置auto_now_add=True
,这样在创建文章时会自动记录时间。updated_at
: 存储文章的更新时间,使用DateTimeField
并设置auto_now=True
,每次更新文章时会自动更新该字段。
3.2 迁移数据库
模型定义完成后,Django需要将这些模型映射到数据库表中。首先,运行以下命令来生成迁移文件:
python manage.py makemigrations
然后,执行迁移操作将模型应用到数据库中:
python manage.py migrate
四、创建视图和URL路由
Django的视图(View)用于处理用户请求并返回响应。接下来,将创建视图函数来处理展示、创建、编辑和删除博客文章的功能。
4.1 创建视图
在blog/views.py
中,添加如下视图函数:
from django.shortcuts import render, redirect, get_object_or_404
from .models import Post
from .forms import PostForm# 文章列表视图
def post_list(request):posts = Post.objects.all() # 获取所有文章return render(request, 'blog/post_list.html', {'posts': posts})# 文章详细视图
def post_detail(request, pk):post = get_object_or_404(Post, pk=pk) # 获取指定id的文章return render(request, 'blog/post_detail.html', {'post': post})# 创建文章视图
def post_create(request):if request.method == 'POST':form = PostForm(request.POST)if form.is_valid():form.save()return redirect('post_list') # 创建成功后跳转到文章列表else:form = PostForm()return render(request, 'blog/post_form.html', {'form': form})# 编辑文章视图
def post_edit(request, pk):post = get_object_or_404(Post, pk=pk)if request.method == 'POST':form = PostForm(request.POST, instance=post)if form.is_valid():form.save()return redirect('post_detail', pk=post.pk) # 编辑成功后跳转到文章详情else:form = PostForm(instance=post)return render(request, 'blog/post_form.html', {'form': form})# 删除文章视图
def post_delete(request, pk):post = get_object_or_404(Post, pk=pk)post.delete()return redirect('post_list') # 删除成功后跳转到文章列表
4.2 配置URL路由
在blog/urls.py
文件中,添加以下代码来配置路由:
from django.urls import path
from . import viewsurlpatterns = [path('', views.post_list, name='post_list'), # 文章列表页面path('post/<int:pk>/', views.post_detail, name='post_detail'), # 文章详情页面path('post/new/', views.post_create, name='post_create'), # 创建文章页面path('post/<int:pk>/edit/', views.post_edit, name='post_edit'), # 编辑文章页面path('post/<int:pk>/delete/', views.post_delete, name='post_delete'), # 删除文章
]
4.3 在项目的URL配置中包含blog
应用的URL
在blog_project/urls.py
文件中,导入并包含blog
应用的URL配置:
from django.contrib import admin
from django.urls import path, includeurlpatterns = [path('admin/', admin.site.urls),path('', include('blog.urls')), # 包含blog应用的URL配置
]
五、创建表单
在Django中,我们使用表单(Form)来处理用户输入的数据。接下来,我们创建一个表单来实现文章的创建和编辑。
5.1 创建表单
在blog/forms.py
文件中,创建一个PostForm
类:
from django import forms
from .models import Postclass PostForm(forms.ModelForm):class Meta:model = Postfields = ['title', 'content'] # 只显示标题和内容字段
这个表单类基于Post
模型,Django会自动为我们生成表单字段,并进行数据验证。
六、创建模板
Django使用模板引擎来渲染HTML页面。我们需要为博客系统创建几个模板来展示文章列表、文章详情、文章表单等。
6.1 文章列表页面(post_list.html
)
在blog/templates/blog/
目录下创建post_list.html
文件,内容如下:
<!DOCTYPE html>
<html>
<head><title>博客列表</title>
</head>
<body><h1>博文列表</h1><a href="{% url 'post_create' %}">创建博文</a><ul>{% for post in posts %}<li><a href="{% url 'post_detail' post.pk %}">{{ post.title }}</a><a href="{% url 'post_edit' post.pk %}">Edit</a><a href="{% url 'post_delete' post.pk %}">Delete</a></li>{% endfor %}</ul>
</body>
</html>
6.2 文章详情页面(post_detail.html
)
在blog/templates/blog/
目录下创建post_detail.html
文件,内容如下:
<!DOCTYPE html>
<html>
<head><title>{{ post.title }}</title>
</head>
<body><h1>{{ post.title }}</h1><p>{{ post.content }}</p><a href="{% url 'post_edit' post.pk %}">编辑</a><a href="{% url 'post_delete' post.pk %}">删除</a><a href="{% url 'post_list' %}">返回列表</a>
</body>
</html>
6.3 文章表单页面(post_form.html
)
在blog/templates/blog/
目录下创建post_form.html
文件,内容如下:
<!DOCTYPE html>
<html>
<head><title>编辑博文</title>
</head>
<body><h1>编辑博文</h1><form method="post">{% csrf_token %}{{ form.as_p }}<button type="submit">保存</button></form>
</body>
</html>
七、运行项目
至此,博客系统的基本功能已经完成。现在,我们可以启动Django开发服务器,查看应用效果。
python manage.py runserver
在浏览器中访问 http://127.0.0.1:8000/,你应该能够看到博客文章的列表,并且可以创建、编辑、删除文章。
八、总结
通过本篇博文,使用Django创建了一个简单的博客系统,学习了如何:
- 创建Django项目和应用
- 定义数据模型并进行数据库迁移
- 创建视图和URL路由
- 使用Django表单处理用户输入
- 编写模板渲染数据
通过这些基本的操作,你可以在Django框架的基础上扩展更多的功能,如用户认证、评论系统、标签分类等。希望这篇教程能帮助你快速上手Django框架,创建自己的Web应用!
相关文章:
前端Python应用指南(四)Django实战:创建一个简单的博客系统
《写给前端的python应用指南》系列: (一)快速构建 Web 服务器 - Flask vs Node.js 对比(二)深入Flask:理解Flask的应用结构与模块化设计(三)Django vs Flask:哪种框架适…...
webrtc获取IceCandidate流程
在WebRTC(Web Real-Time Communication)中,ICECandidate是一个关键概念,它用于描述在建立点对点(P2P)连接时可以考虑的潜在通信端点。以下是关于WebRTC中ICECandidate的详细解释: 一、ICECandidate的定义 ICECandidate对象通常包含以下关键属性: foundation:用于唯一…...
快速入门Spring AI Alibaba
文章目录 前言一、环境准备二、获取API Key三、代码示例pomapplication.ymlcontroller 前言 Spring Cloud Alibaba AI 以 Spring AI 为基础,并在此基础上,基于 Spring AI 0.8.1 版本 API 完成同义系列大模型的接入实现阿里云同义系列大模型全面适配。 在…...
【mysql】MVCC及实现原理
【mysql】MVCC及实现原理 【一】介绍【1】什么是MVCC【2】什么是当前读和快照读【3】当前读,快照读和MVCC的关系【4】MVCC 能解决什么问题,好处(1)数据库并发场景有三种,分别为:(2)M…...
C++ —— 模板类与函数
C —— 模板类与函数 模板类可以用于函数的参数和返回值,有三种形式: 普通函数,参数和返回值是模板类的实例化版本。函数模板,参数和返回值是某种的模板类。函数模板,参数和返回值是任意类型(支持普通类和…...
【笔记】下载mysql5.7
MySQL5.7安装超详细步骤(保姆级教程)_mysql5.7下载安装-CSDN博客 下载与安装 初次登录以及改密码 MySQL 5.7 安装教程(全步骤图解教程)_mysql5.7的安装教程-CSDN博客...
让 AMD GPU 在大语言模型推理中崭露头角:机遇与挑战
在当今科技飞速发展的时代,大语言模型(LLM)的兴起彻底改变了人工智能领域的格局。从智能客服到文本生成,从知识问答到代码编写辅助,大语言模型的应用无处不在,深刻影响着我们的生活和工作。然而,…...
Linux运维常见命令
vi/vim快捷键使用 1)拷贝当前行 yy ,拷贝当前行向下的5行 5yy,并粘贴(输入p)。 2)删除当前行 dd ,删除当前行向下的5行5dd 3)在文件中查找某个单词 [命令行下 /关键字,回车查找 ,输入n就是查找下一个 ] 4)设置文件的行号&…...
前端真实面试题自用
一、写在前面 笔者,经过计算机学硕考研的失败后,想谋求一份前端工作实在是太难了。一方面,确实曾经学习过的东西很久没有拾起,另一方面,对于前端面经还是记忆不深刻,特地写此贴记录笔者在真实前端面试中遇…...
人工智能与云计算的结合:如何释放数据的无限潜力?
引言:数据时代的契机 在当今数字化社会,数据已成为推动经济与技术发展的核心资源,被誉为“21世纪的石油”。从个人消费行为到企业运营决策,再到城市管理与国家治理,每个环节都在生成和积累海量数据。然而,数…...
初始 ShellJS:一个 Node.js 命令行工具集合
一. 前言 Node.js 丰富的生态能赋予我们更强的能力,对于前端工程师来说,使用 Node.js 来编写复杂的 npm script 具有明显的 2 个优势:首先,编写简单的工具脚本对前端工程师来说额外的学习成本很低甚至可以忽略不计,其…...
benchmarksql5.0 测试工具如何在达梦上能够跑起来?
(1)添加驱动程序文件: lib文件夹下创建一个dm文件夹,并在dm文件夹下放置达梦数据库的驱动程序:DmJdbcDriver8.jar (2)引用驱动程序文件所在目录: 在文件benchmarksql-5.0/run/funcs.sh中的function setCP()函数中; 也就是在文件…...
amazon广告授权
amazon授权资料地址 Amazon Advertising Advanced Tools Center postman地址:Amazon Advertising Advanced Tools Center...
设计模式与游戏完美开发(2)
更多内容可以浏览本人博客:https://azureblog.cn/ 😊 该文章主体内容来自《设计模式与游戏完美开发》—蔡升达 第二篇 基础系统 第四章 游戏主要类——外观模式(Facade) 一、游戏子功能的整合 一个游戏程序常常由内部数个不同的…...
WebRTC服务质量(10)- Pacer机制(02) RoundRobinPacketQueue
WebRTC服务质量(01)- Qos概述 WebRTC服务质量(02)- RTP协议 WebRTC服务质量(03)- RTCP协议 WebRTC服务质量(04)- 重传机制(01) RTX NACK概述 WebRTC服务质量(…...
VSCode调试
目录 C/C远程本地调试插件配置参考 C/C远程本地调试 测试源码:https://github.com/jrhee17/ssl-study 插件 Remote - SSH C/C 配置 .vscode/launch.json {"version": "0.2.0","configurations": [{"name": "afte…...
【ES6复习笔记】解构赋值(2)
介绍 解构赋值是一种非常方便的语法,可以让我们更简洁地从数组和对象中提取值,并且可以应用于很多实际开发场景中。 1. 数组的解构赋值 数组的解构赋值是按照一定模式从数组中提取值,然后对变量进行赋值。下面是一个例子: con…...
01 - 初识 Spring
初识Spring 企业级应用 企业级应用是指那些为商业组织、⼤型企业而创建并部署的解决⽅案及应用。这些⼤型的企业级应用结构复 杂、涉及的外部资源众多,事务密集,数据规模⼤,用户数量多,有较强的安全性考虑和较⾼的性能要求。 …...
重装荣耀X14笔记本电脑踩坑记
这几天趁着有国补搞了台荣耀 X14笔记本电脑。到手后第一件事情对我来说当然是要重装成Windows 11 LTSC版。所以按以往的经验做了个USB启动安装盘,但发现上电后按F12能进入启动设备选择,可是USB分类下没有任何设备。重启按F2进入设置界面,关闭…...
华为管理变革之道:奋斗文化与活力
目录 企业文化是什么? 为什么活下去是华为的文化? 活下来,是华为公司的最低纲领,也是华为公司的最高纲领! 资源终会枯竭,唯有文化才能生生不息 企业文化之一:以客户为中心 企业文化之二&a…...
代码随想录算法训练营第十五天-二叉树-110.平衡二叉树
所谓平衡二叉树是指任意子树的高度差不超过1目前所学习的有关二叉树的问题,都是基于二叉树的遍历顺序来实现的 #include <iostream> #include <sstream> #define LEN 10009struct TreeNode {int val;TreeNode* left;TreeNode* right;TreeNode(): val(0…...
各种网站(学习资源、常用工具及其他,持续更新中~)
欢迎围观笔者的个人博客~ 也欢迎通过RSS网址https://kangaroogao.github.io/atom.xml进行订阅~ 大学指南 上海交通大学生存手册中国科学技术大学人工智能与数据科学学院本科进阶指南USTC不完全入学指南大学生活质量指北科研论 信息搜集 AI信息搜集USTC飞跃网站计算机保研 技…...
【gunicorn -k gevent 参数gevent说明,主要CPU密集和I/O密集型】
CPU 密集型和I/O 密集型是两种不同的计算任务类别,它们的性能瓶颈来源不同: 1. CPU 密集型 定义 CPU 密集型任务是指主要消耗 CPU 计算资源 的任务。这类任务需要大量的计算操作,而很少涉及 I/O 操作(如网络或磁盘的读写&#x…...
快速理解24种设计模式
简单工厂模式 建立产品接口类,规定好要实现方法。 建立工厂类,根据传入的参数,实例化所需的类,实例化的类必须实现指定的产品类接口 创建型 单例模式Singleton 保证一个类只有一个实例,并提供一个访问他它的全局…...
5G -- 5G网络架构
5G组网场景 从4G到5G的网络演进: 1、UE -> 4G基站 -> 4G核心网 * 部署初中期,利用存量网络,引入5G基站,4G与5G基站并存 2、UE -> (4G基站、5G基站) -> 4G核心网 * 部署中后期,引入5G核心网&am…...
硬件开发笔记(三十二):TPS54331电源设计(五):原理图BOM表导出、元器件封装核对
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/144753092 长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV…...
UE5 崩溃问题汇总!!!
Using bundled DotNet SDK version: 6.0.302 ERROR: UnrealBuildTool.dll not found in "..\..\Engine\Binaries\DotNET\UnrealBuildTool\UnrealBuildTool.dll" 在你遇到这种极奇崩溃的BUG ,难以解决的时候。 尝试了N种方法,都不行的解决方法。…...
美国站群服务器如何帮助实现有效的多域名管理?
国站群服务器以其丰富的IP资源、高性能硬件和灵活的配置选项,成为多域名管理的理想选择。特别是在需要针对不同域名实现SEO优化、业务分离或多站点运营的场景中,美国站群服务器提供了高效且实用的解决方案。以下是如何利用美国站群服务器实现有效的多域名…...
VMware的三种网络模式——在NAT模式下开放接口为局域网内其他主机提供服务
众所周知 VMware 有三种常用的网络通讯模式,分别是:Bridged(桥接模式)、NAT(网络地址转换模式)、Host-Only(仅主机模式),它们各有不同的用法。 Bridged 桥接模式是与主机…...
【漏洞复现】灵当CRM datapdf.php 任意文件读取漏洞
免责声明 请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,作者不为此承担任何责任。工具来自网络,安全性自测,如有侵权请联系删除。本次测试仅供学习使用,如若非法他用,与平台和本文作…...
MySql详细教程-从入门到进阶(超实用)
基础篇 通用语法及分类 DDL: 数据定义语言,用来定义数据库对象(数据库、表、字段)DML: 数据操作语言,用来对数据库表中的数据进行增删改DQL: 数据查询语言,用来查询数据库中表的记录DCL: 数据控制语言,用…...
【C语言练习(17)—输出杨辉三角形】
C语言练习(17) 文章目录 C语言练习(17)前言题目题目解析整体代码 前言 杨辉三角形的输出可以分三步,第一步构建一个三角形、第二步根据规律将三角形内容填写、第三步将三角形以等腰的形式输出 题目 请输出一个十行的…...
服务器压力测试怎么做
在部署任何Web应用程序或服务之前,进行服务器压力测试(也称为负载测试)是确保系统能够处理预期用户流量的关键步骤。通过模拟大量并发请求,可以评估服务器的性能、稳定性和响应时间,识别潜在瓶颈,并优化资源…...
深度学习中的正则化
深度学习中的正则化(regularization)旨在防止过拟合并提高模型对未知数据的泛化能力。正则化是一种通过在给定的训练集上适当地拟合函数并避免过度拟合来减少误差的技术。 通过对模型参数添加约束,正则化鼓励模型学习更简单、更稳健的模式,从而降低其对噪…...
深入了解 React:从入门到高级应用
深入了解 React:从入门到高级应用 React 是由 Facebook 开发并维护的一个开源 JavaScript 库,用于构建用户界面。自2013年发布以来,React 在前端开发领域迅速崛起,成为最受欢迎的 UI 构建工具之一。无论是小型的单页应用…...
华为云环境下LVS/DR架构的故障诊断优化
本文作者:刘涛 文章目录 前言1.LVS/DR集群的问题2.华为云环境3.问题排查3.1 检查LVS/DR模式配置3.1.1 RS服务器3.1.2 DS服务器 3.2 继续分析抓包结果3.2.1 调整tcpdump抓包过滤条件3.2.2 client向集群VIP发包3.2.3 DS服务器arp消息 3.3 查看丢包3.3.1 监控DS和RS服…...
Effective C++ 条款 22:将成员变量声明为 private
文章目录 条款 22:将成员变量声明为 private核心思想示例代码注意事项结论 条款 22:将成员变量声明为 private 核心思想 成员变量的封装性 将成员变量声明为 private 是面向对象设计的重要原则,有助于保持封装性。 为何使用 private&#x…...
ShardingSphere(分库分表)
ShardingSphere 高性能架构模式 读写分离架构: 基本原理是将数据库读写操作分散到不同的节点上,主库负责处理事务性的增删改操作,从库负责处理查询操作。避免由数据更新导致的行锁,来提升性能。 一主一从:可以将查…...
Visual Studio Code(VS Code)配置C/C++环境
一、Visual Studio Code安装 Visual Studio Code,下文中简称为VS Code的详细安装方法请参考VSCode安装教程(超详细)-CSDN博客 二、MinGW编译器下载与配置 1、MinGW介绍 MinGW(Minimalist GNU for Windows)是一款用于Windows 平台的轻…...
使用 OpenCV 在图像中添加文字
在图像处理任务中,我们经常需要将文本添加到图像中。OpenCV 提供了 cv2.putText() 函数,可以很方便地在图像上绘制文本,支持多种字体、颜色、大小和位置等参数。 本文将详细介绍如何使用 OpenCV 在图像中添加文字,介绍 cv2.putTe…...
高校网络安全_网络安全之道
需要对学校的网络进行安全防护,主要有这么几个痛点: 传统本地化产品难以及时更新情报库,应对新型攻击。 近年来,黑客和黑产团伙攻击手 段呈现多样化实战化,除传统僵木蠕外,各类新型、复杂甚至未知威胁高发…...
『大模型笔记』评估大型语言模型的指标:ELO评分,BLEU,困惑度和交叉熵介绍以及举例解释
评估大型语言模型的指标:ELO评分,BLEU,困惑度和交叉熵介绍以及举例解释 文章目录 一. ELO Rating大模型的elo得分如何理解1. Elo评分的基本原理2. 示例说明3. 大模型中的Elo得分总结3个模型之间如何比较计算,给出示例进行解释1. 基本原理扩展到三方2. 示例计算第一场: A A…...
kafka的配置
server.properties server.properties模板 # broker id,多个broker服务器的话,每个broker id必须不同 broker.id1# kafka broker所在节点的 hostnamehostname10.1.1.1.3:9092# 处理网络请求的线程数 num.network.threads 8# 执行磁盘IO的线程数 num.io…...
Linux下Java通过JNI调用C++
以下为Demo流程 1.创建Java文件 public class HelloWord {// 声明本地方法public native void sayHello();static {// 加载本地库System.loadLibrary("hello");}public static void main(String[] args) {new HelloWord().sayHello();} } 2.编译生成.h头文件 在H…...
家政预约小程序数据库设计
目录 1 如何设计表结构1.1 用户表1.2 服务分类表1.3 服务表1.4 服务规格表1.5 订单表1.6 服务人员表1.7 评价表1.8 促销活动表1.9 投诉表1.10 年卡表1.11 派单表1.12 支付记录表1.13 通知记录表1.14 优惠券表1.15 用户优惠券表1.16 消息模板表1.17 积分记录表 经过一系列的设计…...
【Git学习】windows系统下git init后没有看到生成的.git文件夹
[问题] git init 命令后看不到.git文件夹 [原因] 文件夹设置隐藏 [解决办法] Win11 win10...
云手机群控能用来做什么?
随着云手机的发展,云手机群控技术逐渐从小众的游戏多开工具,发展为涵盖多个领域的智能操作平台。不论是手游搬砖、短视频运营,还是账号养成等场景,云手机群控都展现出了强大的应用潜力。本文将为大家详细解析云手机群控的应用场景…...
go下载依赖提示连接失败
1、现象 Go下载模块提示连接失败 dial tcp 142.251.42.241:443: connectex: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.…...
在线excel编辑(luckysheet)
项目地址:Luckysheet: 🚀Luckysheet ,一款纯前端类似excel的在线表格,功能强大、配置简单、完全开源。 可以下载项目使用npm安装运行,也可以用cdn 加载excel文件(使用luckyexcel): …...
2024国赛A题第一问
第一问 板凳龙等距螺线匀速运动模型的建立 坐标系的建立 根据题意,舞龙队沿螺距为55cm的螺线顺时针进入,进入位置为螺线第16圈点A处,即整个螺线的最外侧点,设定其为 ( x 0 , y 0 ) (x_0,y_0) (x0,y0)。为了便于计算出题目要…...