官网:https://www.djangoproject.com/ 博客:https://www.liujiangblog.com/ 本博客内容参考git:https://gitcode.net/mirrors/jackfrued/Python-100-Days 一些细节问题,大家可以查看git连接。本文主要的改变为把代码升级为django4.1版本。
Django静态文件问题备注: 参考: Django测试开发-20-settings.py中templates配置,使得APP下的模板以及根目录下的模板均可生效 解决django 多个APP时 static文件的问题 django配置app中的静态文件步骤 Django多APP加载静态文件 django.short包参考: 中间件的应用 Django 前后端分离(REST Framework)
可以提高开发效率:前后端可以并行开发,加快产品发布速度。 可以降低系统的耦合性:前后端各自独立开发,前端不需要考虑后端的具体实现细节,后端也不用考虑前端的展示方式。 更好的可扩展性:前后端分离架构可以轻松地扩展新功能或模块,而无需改变整个系统。 更好的跨平台兼容性:前后端分离开发可以为多个平台提供服务,如 Web、Android、iOS 等。 更好的用户体验:通过前后端分离,可以更好地处理数据和 UI 展现,提升用户体验。
开发难度较大:前后端分离需要开发者具备更多的技术能力和经验,同时需要更多的协调和沟通工作。 系统复杂度增加:前后端分离会增加系统的网络请求次数和数据交互,对于一些简单的应用来说可能会影响系统性能。 需要额外的工具支持:前后端分离需要使用一些额外的工具,如 Webpack、Babel 等,增加了开发成本。 安全性风险:前后端分离架构需要将数据和逻辑分别部署在不同的服务器上,可能会面临一些安全性问题。
接下来我们就用前后端分离的方式来改写之前的投票应用。为了避免影响原有的案例,现在新建一个应用polls2,然后在polls2应用中,完成前后端分离的应用,同时也体现了django的可插拔应用设计。
django-admin startapp polls2
注册应用到INSTALLED_APPS
INSTALLED_APPS = [
# ...
'polls2', # 新增
]
新增
from django.http import JsonResponse
from django.shortcuts import render
from polls.models import Subject
# Create your views here.
def show_subjects(request):
queryset = Subject.objects.all()
subjects = []
for subject in queryset:
subjects.append({
'no': subject.no,
'name': subject.name,
'intro': subject.intro,
'isHot': subject.is_hot
})
return JsonResponse(subjects, safe=False,json_dumps_params={'ensure_ascii':False})
# json_dumps_params={'ensure_ascii':False} 可以在前端显示中文,否则显示为转义后的值 读者可以尝试去掉这个参数
上面的代码中,我们通过循环遍历查询学科得到的QuerySet
对象,将每个学科的数据处理成一个字典,在将字典保存在名为subjects
的列表容器中,最后利用JsonResponse
完成对列表的序列化,向浏览器返回JSON格式的数据。由于JsonResponse
序列化的是一个列表而不是字典,所以需要指定safe
参数的值为False
才能完成对subjects
的序列化,否则会产生TypeError
异常。
from polls2 import views as polls2_views
urlpatterns = [
# ...
path('api/subjects',polls2_views.show_subjects), # 新增
]
运行项目
python manage.py runserver
测试
127.0.0.1:8000/api/subjects
未添加json_dumps_params={‘ensure_ascii’:False}参数
添加 json_dumps_params={‘ensure_ascii’:False} 参数
可能大家已经发现了,自己写代码将一个对象转成字典是比较麻烦的,如果对象的属性很多而且某些属性又关联到一个比较复杂的对象时,情况会变得更加糟糕。为此我们可以使用一个名为bpmappers
的三方库来简化将对象转成字典的操作,这个三方库本身也提供了对Django框架的支持。
bpmappers
。pip install bpmappers
from bpmappers.djangomodel import ModelMapper
from polls.models import Subject # 复用polls中的models模型
class SubjectMapper(ModelMapper):
class Meta:
model = Subject
def show_subjects(request):
queryset = Subject.objects.all()
subjects = []
for subject in queryset:
# subjects.append({
# 'no': subject.no,
# 'name': subject.name,
# 'intro': subject.intro,
# 'isHot': subject.is_hot
# })
subjects.append(SubjectMapper(subject).as_dict())
return JsonResponse(subjects, safe=False,json_dumps_params={'ensure_ascii':False})
127.0.0.1:8000/api/subjects
5.定制SubjectMapper映射器
如果希望将是否为热门学科对应的键取名为isHot
(默认的名字是is_hot
),如果希望在JSON数据中不显示原有的is_hot
属性,可以在映射器中排除is_hot
属性;也可以通过修改映射器来做到。具体的做法如下所示:
from bpmappers.djangomodel import ModelMapper
from polls.models import Subject # 复用polls中的models模型
from bpmappers import RawField # 新增
class SubjectMapper(ModelMapper):
isHot = RawField('is_hot') # 新增
class Meta:
model = Subject
exclude = ('is_hot', ) # 新增
127.0.0.1:8000/api/subjects
关于bpmappers
详细的使用指南,请参考它的官方文档,这个官方文档是用日语书写的,可以使用浏览器的翻译功能将它翻译成你熟悉的语言即可。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>学科信息</title>
<style>
/* 此处省略层叠样式表 */
#container {
width: 80%;
margin: 10px auto;
}
.user {
float: right;
margin-right: 10px;
}
.user>a {
margin-right: 10px;
}
#main>dl>dt {
font-size: 1.5em;
font-weight: bold;
border: 1px solid red;
}
#main>dl>dd {
font-size: 1.2em;
}
a {
text-decoration: none;
color: darkcyan;
}
</style>
</head>
<body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.min.js"></script>
<div id="container">
<h1>所有学科</h1>
<hr>
<div id="main">
<dl v-for="subject in subjects">
<dt>
<a :href="'/static/html/api_teachers.html?sno=' + subject.no">
[[subject.name]] <!-- 原先为 {{subject.name}}-->
</a>
<img v-if="subject.isHot" src="/static/images/hot-icon-small.png">
</dt>
<dd>[[subject.intro]] </dd> <!-- 原先为 {{subject.intro}}-->
</dl>
</div>
</div>
<script>
let app = new Vue({
el: '#main',
delimiters: ["[[", "]]"], // ***修改处*** vue 的与django模板语法冲突
data: {
subjects: []
},
created() {
fetch('http://127.0.0.1:8000/api/subjects')
.then(resp => resp.json())
.then(json => {
console.log(json)
this.subjects = json
})
}
})
</script>
</body>
</html>
运行
python manage.py runserver
测试
http://127.0.0.1:8000/static/html/api_subjects.html
前后端分离的开发需要将前端页面作为静态资源进行部署,项目实际上线的时候,我们会对整个Web应用进行动静分离,静态资源通过Nginx或Apache服务器进行部署,生成动态内容的Python程序部署在uWSGI或者Gunicorn服务器上,对动态内容的请求由Nginx或Apache路由到uWSGI或Gunicorn服务器上。
在开发阶段,我们通常会使用Django自带的测试服务器,如果要尝试前后端分离,可以先将静态页面放在之前创建的放静态资源的目录下。
本文主要是Django系列博客。本文是Django前后端分离开发。 步骤如下:
1.创建应用polls2 2.在settings.py中注册polls2 3.在polls2的views.py中添加视图函数 4.在urls.py中添加路由 5.运行测试 6.基于bpmappers简化对象转换为json 7.基于vue修改前端页面 8.把前端代码部署在服务器上 如果你看到这里,且博客有帮助,可以关注,点赞,收藏,评论哈💯