前言

众所周知,Django对于网站快速开发非常友好,这得益于框架为我们做了很多事情,让我们只需要做一些简单的配置和逻辑即可把网站的功能开发出来。但是,在使用Django的过程中,有一个地方一直是比较难受的,那就是使用Django自带的模版,这种通常需要自己利用HTML+CSS+Jquery的方式总感觉是上一个时代的做法,前后端分离无论对于开发效率、多端支持等等都是很有好处的。所以,本文希望通过一个简单的demo,讲一讲基于Django+Vue的前后端分离开发,将Django作为一个纯后端的服务,为前端Vue页面提供数据支持。

本文采用的django版本号2.2.5,Vue版本2.9.6。

如果文章太长,可先收藏关注一波~

本文demo代码已上传github,关注公众号"进击的程序人"回复"代码"即可获取~

项目准备

  1. 对于django和Vue的安装这里就略过了~
  2. 创建前后端项目:创建一个文件夹,然后命令行创建项目即可,如下图~

3. 测试:

命令行进入后端文件夹book_demo,输入下面命令,浏览器登陆127.0.0.1:8000看见欢迎页即成功。

python manage.py runserver

再进入前端文件夹appfront,输入下面命令,浏览器登陆127.0.0.1:8080看见欢迎页即成功。

npm run dev

上面两个命令也是对应前后端项目的启动命令,后面就直接将过程说成启动前/后端项目。

后端实现

为了方便后端的实现,作为django做后端api服务的一种常用插件,django-rest-framework(DRF)提供了许多好用的特性,所以本文demo中也应用一下,命令行输入命令安装:

pip install django-rest-framework

进入book_demo目录,创建一个新的名为books的应用,并在新应用中添加urls.py文件,方便后面的路由配置,命令行输入:

python manage.py startapp books
cd books
touch urls.py

现在的目录结构如下:

下面开始做一些简单的配置:

将DRF和books配置到django项目中,打开项目中的settings.py文件,添加:

# book_demo/settings.py
INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles',# demo add'rest_framework','books',
]

对整个项目的路由进行配置,让访问api/路径时候转到books应用中的urls.py文件配置进行处理。

# book_demo/settings.py
from django.contrib import admin
from django.urls import path, includeurlpatterns = [path('admin/', admin.site.urls),path('api/', include('books.urls')), # demo add
] 

下面在books应用中写简单的逻辑,demo只最简单涉及对书本的增删改查。因为这一部分不是本文重点,所以这里只介绍写代码流程和贴代码,对代码不做详细解释:

在models.py文件中写简单数据类Books:

# books/models.py
from django.db import modelsclass Books(models.Model):name = models.CharField(max_length=30)author = models.CharField(max_length=30, blank=True, null=True)

在books文件夹中创建serializer.py文件,并写对应序列化器BooksSerializer:

# books/serializer.py
from rest_framework import serializersfrom books.models import Booksclass BooksSerializer(serializers.ModelSerializer):class Meta:model = Books #序列化的对象名fields = '__all__' #序列化的字段名,或者指定字段 fields = ("id","name","age")

在views.py文件中写对应的视图集BooksViewSet来处理请求:

# books/views.py
from rest_framework import viewsetsfrom books.models import Books
from books.serializer import BooksSerializerclass BooksViewSet(viewsets.ModelViewSet):queryset = Books.objects.all()serializer_class = BooksSerializer

在urls.py文件中写对应的路由映射:

# books/urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouterfrom books import viewsrouter = DefaultRouter()
router.register('books', views.BooksViewSet)urlpatterns = [path('', include(router.urls)),
]

对于books应用中的内容,如果对DRF和Django流程熟悉的同学肯定知道都干了些什么,篇幅关系这里只能简单解释,DRF通过视图集ViewSet的方式让我们对某一个数据类Model可以进行增删改查,而且不同的操作对应于不同的请求方式,比如查看所有books用get方法,添加一本book用post方法等,让整个后端服务是restful的。如果实在看不懂代码含义,只需知道这样做之后就可以通过不同的网络请求对后端数据库的Books数据进行操作即可,后续可以结合Django和DRF官方文档对代码进行学习,或关注本人未来分享的内容。

到这里,可以运行一下后端项目看看效果,命令行运行:

python manage.py makemigrations
python manage.py migrate
python manage.py runserver

得益于DRF提供的api可视化界面,浏览器访问127.0.0.1:8000/api/books/,如果出现了以下界面并添加数据正常,则说明后端的基本逻辑已经ok了~下图为添加了一条数据之后的效果。

前端实现

接下来的工作以appfront项目目录为根目录进行,开始写一点前端的展示和表单,希望达到两个目标,一是能从后端请求到所有的books列表,二是能往后端添加一条book数据。说白了就是希望把上面的页面用Vue简单实现一下,然后能达到相同的功能。对于Vue项目中各个文件的功能这里也不多解释,可以参考其文档系统学习。这里只需要知道欢迎页面中的样式是写在App.vue和components/HelloWorld.vue中即可。

这里直接用HelloWorld.vue进行修改,只求功能不追求页面了~

// appfront/src/components/HelloWorld.vue
<template><div class="hello"><h1>{{ msg }}</h1><!-- show books list --><ul><li v-for="(book, index) in books" :key="index" style="display:block">{{index}}-{{book.name}}-{{book.author}}</li></ul><!-- form to add a book --><form action="">输入书名:<input type="text" placeholder="book name" v-model="inputBook.name"><br>输入作者:<input type="text" placeholder="book author" v-model="inputBook.author"><br></form><button type="submit" @click="bookSubmit()">submit</button></div>
</template><script>
export default {name: 'HelloWorld',data () {return {msg: 'Welcome to Your Vue.js App',// books list databooks: [{name: 'test', author: 't'},{name: 'test2', author: 't2'}],// book data in the forminputBook: {"name": "","author": "",}}},methods: {loadBooks () {...}, // load books list when visit the pagebookSubmit () {...} // add a book to backend when click the button},created: function () {this.loadBooks()}
}
</script>
...

启动前端项目,浏览器访问127.0.0.1:8080,可以看到刚写的页面已经更新上去了,丑是丑了点,意思到了就行~如下图:

前后端联调

敲黑板,重点来了!!上面的页面中数据其实是写死在前端页面的模拟数据,这一节希望通过从后端拿数据并展示在前端页面的方式来完成前后端联调。前后端联调,涉及最多的就是跨域的问题,为了保证安全,通常需要遵循同源策略,即“协议、域名、端口”三者都相同,具体可以看看相关的博客,这里只需知道上述三者相同才算同源即可。

后端部分,对于django的跨域问题,网上比较常用的做法就是利用django-cors-headers模块来解决,这里也不能免俗,操作如下。

先在命令行中进行对应模块的安装:

pip install django-cors-headers

然后在项目中添加该模块:

# books_demo/settings.py
INSTALLED_APPS = [...# demo'corsheaders',...
]MIDDLEWARE = ['corsheaders.middleware.CorsMiddleware', # 需注意与其他中间件顺序,这里放在最前面即可...
]# 支持跨域配置开始
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True 

后端部分告于段落,接下来需要补充一下前端的逻辑,Vue框架现在一般都用axios模块进行网络请求,这里沿用这种方式,下面是在前端项目中操作:

首先命令行安装axios模块,如果没有安装cnpm就还是用npm安装:

cnpm install axios

为了方便管理api请求的各种逻辑,在前端项目的src目录下创建api目录,然后创建api.js和index.js文件。index.js文件是对axios做配置:

// appfront/src/api/index.js
import Vue from 'vue'
import Axios from 'axios'const axiosInstance = Axios.create({withCredentials: true
})// 通过拦截器处理csrf问题,这里的正则和匹配下标可能需要根据实际情况小改动
axiosInstance.interceptors.request.use((config) => {config.headers['X-Requested-With'] = 'XMLHttpRequest'const regex = /.*csrftoken=([^;.]*).*$/config.headers['X-CSRFToken'] = document.cookie.match(regex) === null ? null : document.cookie.match(regex)[1]return config
})axiosInstance.interceptors.response.use(response => {return response},error => {return Promise.reject(error)}
)Vue.prototype.axios = axiosInstanceexport default axiosInstance

api.js文件是对后端进行请求,可以看到,获取books列表和添加一本book各对应于一个请求:

// appfront/src/api/api.js
import axiosInstance from './index'const axios = axiosInstanceexport const getBooks = () => {return axios.get(`http://localhost:8000/api/books/`)}export const postBook = (bookName, bookAuthor) => {return axios.post(`http://localhost:8000/api/books/`, {'name': bookName, 'author': bookAuthor})}

然后更新HelloWorld.vue中的处理逻辑:

// appfront/src/components/HelloWorld.vue
<script>
import {getBooks, postBook} from '../api/api.js'
export default {...methods: {loadBooks () {getBooks().then(response => {this.books = response.data})}, // load books list when visit the pagebookSubmit () {postBook(this.inputBook.name, this.inputBook.author).then(response => {console.log(response)this.loadBooks()})} // add a book to backend when click the button},...
}
</script>

至此,一个极其简陋的查询和添加书籍的功能算是完成了~如下图:

可以看到,列表里面的数据是从后端读取到的,同时前端的提交数据库也能有对应的操作,所以前后端至此是打通了。

打包

现阶段是前后端分开开发,但是当最后要用的时候,还需要把代码合在一起。

首先对前端项目进行打包,这里用Vue的自动打包:

npm run build

可以看到前端项目中多出了一个dist文件夹,这个就是前端文件的打包结果。需要把dist文件夹复制到books_demo项目文件夹中。

然后对settings.py文件进行相应的修改,其实就是帮django指定模版文件和静态文件的搜索地址:

# books_demo/books_demo/settings.py
...
TEMPLATES = [{'BACKEND': 'django.template.backends.django.DjangoTemplates','DIRS': [os.path.join(BASE_DIR, 'dist')], # demo add...},
]
...
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'dist/static'),
]
..

最后在根urls.py文件中配置一下入口html文件的对应路由:

# books_demo/books_demo/urls.py
...
from django.views.generic.base import TemplateViewurlpatterns = [...path('', TemplateView.as_view(template_name='index.html'))
]

重新启动项目,这次用浏览器访问127.0.0.1:8000,即django服务的对应端口即可。

可以看到,项目的交互是正常的,符合我们的预期。

总结

本文以一个非常简单的demo为例,介绍了利用django+drf+vue的前后端分离开发模式,基本可以算是手把手入门。有了这个小demo之后,不管是前端页面还是后端功能,都可以做相应的扩展,从而开发出更加复杂使用的网站。

码字不易,如果觉得本文还有点帮助,一键三连点波关注哈~

手把手Django+Vue前后端分离开发入门(附demo)相关推荐

  1. Python学习教程(技术干货):关于前后端分离开发入门

    前后端分离开发入门 在传统的Web应用开发中,大多数的程序员会将浏览器作为前后端的分界线.将浏览器中为用户进行页面展示的部分称之为前端,而将运行在服务器,为前端提供业务逻辑和数据准备的所有代码统称为后 ...

  2. python后端教程_Python学习教程(技术干货):关于前后端分离开发入门

    原标题:Python学习教程(技术干货):关于前后端分离开发入门 对于程序员来说,其实Tab和空格远远不只是"立场"问题那么简单. 在不同的编辑器里tab的长度可能不一致,所以在一 ...

  3. SpringBoot + Vue前后端分离开发:全局异常处理及统一结果封装

    SpringBoot + Vue前后端分离开发:全局异常处理及统一结果封装 文章目录 SpringBoot + Vue前后端分离开发:全局异常处理及统一结果封装 前后端分离开发中的异常处理 统一结果封 ...

  4. 视频教程-SpringBoot+Security+Vue前后端分离开发权限管理系统-Java

    SpringBoot+Security+Vue前后端分离开发权限管理系统 10多年互联网一线实战经验,现就职于大型知名互联网企业,架构师, 有丰富实战经验和企业面试经验:曾就职于某上市培训机构数年,独 ...

  5. springboot flask php,使用Vue,Spring Boot,Flask,Django 完成Vue前后端分离开发(二)

    使用Vue完成前后端分离开发(二) Bravery never goes out of fashion. 勇敢永远不过时. 前面简单说了一下 Vue 项目的搭建和项目的大致页面,这里讲一下 Djang ...

  6. springboot+Mybatis+vue前后端分离开发:作业管理系统

    1.功能设计 本系统功能设计如下: 按照需求分为教师端和学生端,教师端发布作业,查看自己发布的作业,查看学生名单,添加学生. 学生端查看作业.提交或修改作业. 2.数据库设计 student表: 字段 ...

  7. vue+django进行前后端分离开发

    目录 一.vue项目的创建 二.Django项目的创建 三.vue+django结合要解决的问题 四.总结 一.vue项目的创建 通过vue_cli创建一个vue项目,所有的代码可以在VSCODE中编 ...

  8. 记一次Spring boot 和Vue前后端分离的入门培训

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达今日推荐:2020年7月程序员工资统计,平均14357元,又跌了,扎心个人原创100W+访问量博客:点击前往,查看更多 作者 ...

  9. 太赞了,SpringBoot+Vue前后端分离完整入门教程!

    最近很多小伙伴都在学习前后端分离的知识,苦于找不到好的基础资料,于是我翻箱倒柜,找了一份好的Vue入门视频和笔记pdf,然后更是亲自录制了SpringBoot + Vue的前后端分离的综合项目,现在统 ...

最新文章

  1. MPB:南土所褚海燕组-小麦相关微生物的野外采样与样品保存
  2. 级联人脸检测--Detecting Faces Using Inside Cascaded Contextual CNN
  3. firefox 中碰到的一个小坑
  4. 如何使用 ClickHouse 每天玩转千亿数据,纯PPT干货
  5. BZOJ 1012 [JSOI2008]最大数maxnumber
  6. python中turtle介绍_python中turtle库的简单介绍
  7. LeetCode 10 Regular Expression Matching(字符串匹配)
  8. AAC Explicit or Implicit SBR PS issue
  9. jquery 引号问题
  10. MVC控制器取参数值
  11. Security+ 学习笔记31 云计算参考架构
  12. DevExpress WinForm控件入门指南——数据管理控件
  13. python中字符串中文乱码_Python中文乱码的处理
  14. 修改Android手机的分辨率和屏幕密度
  15. 怎么在服务器上显示u盘启动,电脑服务器怎么设置U盘启动
  16. 【Java进阶】到底什么是抽象?
  17. 用计算机技术辅助语文教学,利用计算机技术辅助拼音学习“潜力无限”
  18. 基于matlab实现双路音频信号的AM调制与解调
  19. 用php搭建微信公众号,用PHP搭建一个自己的微信公众号
  20. 解决锚点定位刷新页面的问题

热门文章

  1. 计算机网络之DHCP详解
  2. mysql sql rowcount_ORACLE中的SQL%ROWCOUNT与MySQL中的ROW_COUNT()的一点异同-阿里云开发者社区...
  3. JavaUtil_01_MD5加密
  4. 学习使我快乐 第五天
  5. HTML——头部引入网页图标
  6. setTimeout执行时间
  7. 日语中的不好意思、对不起是怎么表达的呀-怎么使用的
  8. c语言wsastartup源代码,c – 可以从几个线程调用WSAStartup()导致死锁吗?
  9. js字符串split
  10. 超详细讲解搭建guacamole实现远程桌面