1、 JsonResponse
return JsonResponse(data, safe=False, json_dumps_params={'ensure_ascii': False})
2、 HttpResponse
return HttpResponse(json.dumps(data, ensure_ascii=False))
3、 类视图
类视图: 结构清晰
更强的复用性
需要继承View: from django.views import View
from django.views import View
from django.http import JsonResponse
class Index(View):
def get(self, request):
# 获取数据时使用get方法
return JsonResponse({'msg': 'OK', 'code': 200})
def post(self, request):
# 添加数据使用post
pass
from django.urls import path
from . import views
urlpatterns = [
path('index/', views.Index.as_view())
]
二、今日内容
1、静态路由
urlpatterns属性
urlpatterns是路由文件中的一个全局变量,用来存放路由及视图函数的映射关系
用户发起的请求URL
都会首先进入主控制目录下的这个urls.py
文件中进行查找匹配
- 首先找到
urls.py
下的urlpatterns
全局变量,这是一个路由规则实例的列表数据。 - 按照先后定义顺序,进行路由匹配。
- 找到第一个匹配项时停止匹配,执行匹配到的视图函数。
- 遍历完全,未发现匹配,
django
进行异常处理
其中urlpatterns
中的每一个路由映射规则可以由path
或re_path
进行构造
注意:Django
的路由不考虑HTTP
请求方式,仅根据URL进行路由;即,只要URL
相同,无论POST
、GET
等哪种请求方式都指向同一个操作函数
path方法
path(str, view, kwargs=None, name=None)
'''
str:一个匹配对应url地址的规则字符串
view:路由对应的视图函数,并且会自动封装HttpRequest作为第一个参数给这个视图函
kwargs:视图函数的关键字参数
name:该路由的全局命名,可以让我们方便的在django项目中任意部分显示的使用,相当于为url取变量名,接下来全局使用该命名值即可;当对应url路由改变之后,结合路由反向解析使用的地方不需要更改路由
'''
re_path
re_path(regex, view, kwargs=None, name=None)
'''
regex:一个匹配对应url地址的规则字符串
view:路由对应的视图函数,并且会自动封装HttpRequest作为第一个参数给这个视图函
kwargs:视图函数的关键字参数
name:该路由的全局命名,可以让我们方便的在django项目中任意部分显示的使用,相当于为url取变量名,接下来全局使用该命名值即可;当对应url路由改变之后,结合路由反向解析使用的地方不需要更改路由
'''
案例
新闻 分类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FvZ69aLq-1622556921706)(C:\Users\lenovo\Desktop\image-20210601104902723.png)]
1、新建django项目
使用pycharm创建项目
file—newProject
使用命令创建项目
django-admin startproject projectname
2、 新建app
python manage.py startapp app01
**3、 配置settings.py,在settings.py中配置app,切换语言和时区,切换数据库为mysql, **
INSTALLED_APPS = [
...
'app01.apps.App01Config',
]
LANGUAGE_CODE = 'zh-hans' # 语言
TIME_ZONE = 'Asia/Shanghai' # 时区
USE_TZ = False # 让修改的时区生效
# 配置数据库
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # 引擎,使用 mysql
'NAME': 'day04', # 数据库名称
'USER': 'root', # 数据库的登录用户名
'PASSWORD': 'root1234', # 数据库的登录的密码
'HOST': '127.0.0.1', # 数据库所在的主机
'PORT': 3306, # 数据库使用的端口号
}
}
需要在settings.py所在的目录下init.py中,写入以下内容
import pymysql
pymysql.install_as_MySQLdb()
4、 在后端进行跨域配置
什么是跨域问题?
指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器施加的安全限制。
所谓同源是指,域名,协议,端口均相同,只要有一个不同,就是跨域。
django后端跨域
-
安装django-cors-headers
pip install django-cors-headers # pip show 模块名, 查看某个模块是否安装过 pip show django-cors-headers
-
在settings.py下的INSTALLED_APPS中进行配置
INSTALLED_APPS = [ # 第三方包 'corsheaders', # 跨域 'app01.apps.App01Config', ]
-
在settings.py下的MIDDLEWARE中配置
MIDDLEWARE = [ 'django.contrib.sessions.middleware.SessionMiddleware', # 在这里进行配置跨域 , 在中间件第三行 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', # 注释掉csrf这一行,第五行 # 'django.middleware.csrf.CsrfViewMiddleware', ]
-
在settings.py中添加变量,允许所有的 源访问
CORS_ALLOW_ALL_ORIGINS = True # 允许所有的源进行访问
5、 在主路由下配置app,做路由分发
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('app01/', include('app01.urls'))
]
# app01/urls.py
from django.urls import path
from . import views
urlpatterns = [
]
6、 在models.py中设计新闻分类表
from django.db import models# Create your models here.# 在models.py下每新建一个类,就代表在数据库新建一张表class Cate(models.Model): # 类下面的属性,是表中字段 name = models.CharField(max_length=32) def __str__(self): return self.name
7、 生成迁移文件和执行迁移文件
python manage.py makemigrationspython manage.py migrate
9、 添加分类接口
from django.views import Viewfrom django.http import JsonResponsefrom .models import Cateclass CateView(View): def post(self, request): # 获取网页提交数据 name = request.POST.get('name') # None # 判断数据是否完整 没有拿到数据的话,返回消息,数据不完整 if not name: return JsonResponse({'msg': '数据不完整', 'code': 400}, json_dumps_params={'ensure_ascii': False}) # 如果拿到数据,添加 Cate.objects.create(name=name) return JsonResponse({'msg': '添加成功', 'code': 200}, json_dumps_params={'ensure_ascii': False})
10、 添加路由
from django.urls import pathfrom . import viewsurlpatterns = [ path('cate/', views.CateView.as_view()), # 分类增删改查]
11、 分类接口文档
请求地址: http://127.0.0.1:8000/app01/cate/
请求方法: post
请求参数:
字段 | 类型 | 必填 |
---|---|---|
name | string | true |
返回数据:
# 请求失败,数据为空时的提示{ 'msg': '数据不完整', 'code': 400}# 请求成功{ 'msg': '添加成功', 'code': 200}
12、 在vue下新建AddCate.vue页面,实现页面表单功能
创建vue:
vue init webpack myvue
安装axios:
cnpm install --save axios
1、 配置全局axios
在src文件夹下main.js当中,进行配置
import axios from 'axios'Vue.prototype.axios = axiosaxios.defaults.baseURL = 'http://127.0.0.1:8000'
2、 在src下的components下新建AddCate.vue页面
<template> <div> <!-- 在这里写添加分类的表单 --> <div> <form action=""> <p>分类名称: <input type="text" v-model="name"></p> <p><button>添加</button></p> </form> </div> </div></template><script>export default { data() { return { name: '' } }, methods: { }, created() { }}</script><style scoped></style>
13、django+vue+浏览器执行 流程讲解
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-smtrResV-1622556921710)(images/image-20210601150329792.png)]
展示数据
1、展示数据接口
class CateView(View): def get(self, request): # 1、 获取所有的数据 cate_list = Cate.objects.all() # 2、把获取出来的数据转成列表 cate_data = [{'id': i.id, 'name': i.name} for i in cate_list] # 3、 返回数据以json形式返回 return JsonResponse(cate_data, safe=False, json_dumps_params={'ensure_ascii': False})
2、 展示数据接口文档
请求地址: http://127.0.0.1:8000/app01/cate/
请求方法: get
请求参数: 无
请求示例: http://127.0.0.1:8000/app01/cate/
接口格式: json
返回数据格式:
[ { 'id': 1, 'name': '军事' }, { 'id': 2, 'name': '财经' }]
3、 新建vue页面,请求数据,并展示
<template> <div> <table class="t1"> <tr> <td>编号</td> <td>名称</td> <td>操作</td> </tr> <tr v-for="cate in cate_list" :key="cate.id"> <td>{{cate.id}}</td> <td>{{cate.name}}</td> <td> <button>编辑</button> <button>删除</button> </td> </tr> </table> </div></template><script>export default { data() { return { cate_list: [] } }, methods: { // 获取分类的方法 getCate() { // 在这里执行分类的方法的逻辑 // 向后台请求数据 this.axios({ // axios默认请求是get,所以可以不用写method: get url: '/app01/cate/' }).then(res => { console.log(res.data) this.cate_list = res.data }) } }, created() { // 在页面加载完成之前调用 this.getCate() }}</script><style scoped>.t1 { width: 50%; margin: 30px auto;}</style>
2、动态路由
去详情页面
跳转路由,确定要获取的详情的信息
1、 点击名称,跳转页面,使用router-link
<router-link :to="{name: 'Detail', query: {'cate_id': cate.id}}">{{cate.name}}</router-link>
2、 在详情页面进行操作
-
获取路由当中的分类id
<script>export default { data() { return { // 1、获取路由当中的分类id cate_id: this.$route.query.cate_id } },}</script>
-
通过获取到的分类id,去后台查询所对应的数据
<script>export default { data() { return { // 1、获取路由当中的分类id cate_id: this.$route.query.cate_id } }, methods: { getDetail() { this.axios({ url: '/app01/detail/?cate_id=' + this.cate_id }).then(res => { console.log(res.data) }) } }, created() { this.getDetail() }}</script>
-
展示数据
<template> <div> {{cate.id}} ------ {{cate.name}} </div></template><script>export default { data() { return { // 1、获取路由当中的分类id cate_id: this.$route.query.cate_id, cate: {} } }, methods: { getDetail() { this.axios({ url: '/app01/detail/?cate_id=' + this.cate_id }).then(res => { console.log(res.data) this.cate = res.data }) } }, created() { this.getDetail() }}</script><style scoped></style>
动态路由传参
有的时候,我们设置的路由不是一成不变的,如: 我们需要跳转到详情,需要通过某个分类查看该分类的下所有的商品等,那么这样的路由其实对应的都应该是一个视图函数,用以展示页面内容,那么如何设计这样的路由,就要涉及到动态路由及路由传参
1、通过分类id获取分类的详情信息
**2、 动态路由配置 **
路由通过尖括号进行分组匹配,使用int以及str内置转换器将连接对应部分的值进行转换;并将匹配到的结果传递到视图函数对应的参数位置上;
访问: http://127.0.0.1:8000/app01/detail/1/
其中1将作为cate_id的参数被接收。
- 其他内置Path转换器,可以将我们的路由参数规定为指定类型
'''str:匹配除了路径分隔符(`/`)之外的非空字符串,这是默认的形式int:匹配正整数,包含0slug:匹配字母、数字以及横杠、下划线组成的字符串uuid:匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00path:匹配任何非空字符串,包含了路径分隔符'''
动态路由传参与GET传参的异同
- 动态路由传参,参数需要参与路由匹配,在路由匹配中获取参数
- GET参数,参数部分不需要参与路由匹配,在视图中获取参数
3、 路由分发
路由分发的概念
我们的路由编写都是在项目主要目录下的urls.py
文件中,但是如果app
有很多的话,这么多路由都写到一起,明显是一件很不方便管理的事情
其实在之前的练习中,我们使用的方式均是路由分发,每个子app
都拥有自己独立的urls.py
路由映射文件,而主控路由文件里只需要使用include
函数导入子app
下路由文件即可,这就是路由分发
include路由分发实现
from django.contrib import adminfrom django.urls import path,includeurlpatterns = [ path('admin/', admin.site.urls), path('app01/',include("app01.urls")) # 使用include 实现路由分发,找到子app下的路由文件]
路由分发为我们带来的好处有很多,可以让我们在多个app
的项目中更加方便有效的管理每一个路由
并且也可以让我们的用户在访问时看到浏览器中的URL
地址更加赏心悦目