drf是django rest_framework的缩写,顾名思义是django的rest_framework风格设计,能帮助我们用很少的代码就能实现增删改查功能。vue则是当前比较流行的一个前端框架。
django:3.0.3
node.js:v12.13.1(本项目依赖node.js,使用vue-cli搭建vue项目)
python:3.7
django下载:
pip install django
node.js下载:
进入官网下载:
http://nodejs.cn/download/
使用cmd进入你想创建django项目的文件夹,输入以下命令新建一个django项目:
命令解释:(django-admin startproject “项目名”)
django-admin startproject Mydrf
然后进入项目目录创建一个名为book的app:
D:\PycharmProjects\Mydrf>python manage.py startapp book
现在的目录结构如下:
本项目使用mysql,所以要在settings.py中配置mysql信息(在settings.py中修改即可):
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'db_name', # 你的数据库名
'PASSWORD': 'password', # 你的数据库密码
'USER': 'user', # 你的数据库用户名
'HOST': '127.0.0.1', # 数据库所在地址
'PORT': '3306', # 端口
}
}
要实现drf写端口,需要下载相关包:
pip install djangorestframework
在settings.py中引用:
INSTALLED_APPS = [
''''''
'rest_framework',
'book', # 之前创建的app也要引入才能使用
]
book目录下的models.py中写入如下代码:
book/models.py
from django.db import models
# Create your models here.
class BookInfo(models.Model):
btitle = models.CharField(max_length=20, verbose_name='名称')
bpub_date = models.DateField(verbose_name='发布日期', null=True)
bread = models.IntegerField(default=0, verbose_name='阅读量')
bcomment = models.IntegerField(default=0, verbose_name='评论量')
image = models.ImageField(upload_to='booktest',verbose_name='图片',null=True)
然后输入以下命令进行数据迁移(第一句命令是创建数据库迁移文件;第二句命令是根据数据库迁移文件生成对应SQL语句并执行):
python manage.py makemigrations
python manage.py migrate
之后会在数据库里面新建了如下表:
drf的核心是数据的序列化和反序列化,于是我们要创建一个序列化器。book目录下的新建一个serializers.py并写入如下代码:
book/serializers.py
from rest_framework import serializers
from book.models import BookInfo
class BookInfoSerializer(serializers.ModelSerializer):
"""图书数据序列化器"""
class Meta:
model = BookInfo # 生成序列化器对应的模型类
fields = '__all__' # 需要进行序列化的字段,这里拿所有字段
然后创建视图,在book目录下的views.py中写入如下代码:
book/views.py
from rest_framework.mixins import ListModelMixin
from rest_framework.generics import GenericAPIView
from book.models import BookInfo
from book.serializers import BookInfoSerializer
# Create your views here.
class BookListView(ListModelMixin, GenericAPIView):
queryset = BookInfo.objects.all() # 获取对象
serializer_class = BookInfoSerializer # 获取序列化器
# get请求时返回的数据
def get(self, request):
"""
继承ListModelMixin并调用其中的list方法
"""
return self.list(request)
最后添加路径,在book目录下新建一个urls.py文件,并输入如下代码:
book/urls.py
from django.urls import path
from book.views import BookListView
urlpatterns = [
path('allbook/', BookListView.as_view()),
]
在Mydrf目录下的urls.py添加如下代码:
Mydrf/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('book/', include('book.urls'))
]
最后输入python manage.py runserver运行项目:
在浏览器中输入地址http://127.0.0.1:8000/book/allbook/(数据库数据自己造),能看到如下结果说明成功:
别人的教程,亲测有效:
https://www.jianshu.com/p/02b12c600c7b
创建之后文件目录如下:
在components下创建BookList.vue,相当于创建一个页面
然后配置路由,在router/index.js里面配置,修改后的index.js如下:
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import BookList from '../components/BookList.vue'
Vue.use(Router)
export default new Router({
mode: 'history',
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
},
{
path: '/allBook',
name: 'BookList',
component: BookList
},
]
})
main.js也要修改
import Vue from 'vue'
import App from './App'
import router from './router'
import 'element-ui/lib/theme-chalk/index.css'
import axios from 'axios'
import ElementUI from 'element-ui'
// Vue.config.productionTip = false
Vue.use(ElementUI)
Vue.prototype.$axios = axios;
Vue.prototype.GLOBAL_URL = 'http://127.0.0.1:8000' //设置后端接口全局变量
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: {
App },
template: ' '
})
App.vue相当于所有vue的模板页,也做一定的修改,注释多余的部分,修改后的App.vue如下:
<template>
<div id="app">
<!-- <img src="./assets/logo.png"> -->
<router-view/>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
最后,在BookList.vue里面编写代码请求数据并展示,代码如下:
components/BookList.vue
<template>
<div>
<el-table :data="bookdata" border style="width: 100%">
<el-table-column prop="btitle" label="书名" align="center"></el-table-column>
<el-table-column prop="bpub_date" label="出版时间" align="center"></el-table-column>
<el-table-column prop="bread" label="阅读量" align="center"></el-table-column>
<el-table-column prop="bcomment" label="评论数" align="center"></el-table-column>
</el-table>
</div>
</template>
<script>
export default {
name: "BookList",
data(){
return{
bookdata: []
}
},
mounted () {
this.getData()
},
methods: {
getData(){
this.$axios.get(this.GLOBAL_URL + "/book/allbook/")
.then(res => {
this.bookdata = res.data;
console.log(this.bookdata)
});
}
}
}
</script>
由于前后端的分离,要进行跨域请求,后端出于安全考虑,也会对于跨域有限制。所以要解决对应的跨域问题
django的跨域请求解决方法:
安装django-cors-headers
pip install django-cors-headers
配置settings.py文件
INSTALLED_APPS = [
...
'corsheaders',
...
]
MIDDLEWARE_CLASSES = (
...
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware', # 注意顺序
...
)
# 跨域增加忽略
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
# 跨域请求允许的请求方式
CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
'VIEW',
)
# 跨域请求允许的请求头类型
CORS_ALLOW_HEADERS = (
'XMLHttpRequest',
'X_FILENAME',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
'Pragma',
)
输入命令运行django项目:
python manage.py runserver
输入命令运行vue项目:
npm run dev
在浏览器中输入网址http://localhost:8080/allbook/会看到如下结果:
能正常获取数据,大功告成。
本博客目的时对vue获取drf接口数据的过程做展示,所以只做了一个获取所有数据的接口。
在某些部分内容涉及了element-ui、drf、vue的相关知识点,我在这里就不展开说明,感兴趣的读者可以在网上自行学习。