QCon北京开幕在即|与全球 140+ 顶尖工程师共同解构 AI 时代的技术浪潮 了解详情
写点什么

教你如何使用 Django + Vue.js 快速构建项目

  • 2019-11-13
  • 本文字数:6038 字

    阅读完需:约 20 分钟

教你如何使用 Django + Vue.js 快速构建项目

目录

一、我为什么要选择 Django 与 VueJS?

二、Django 和 VueJS 是如何结合起来的?

三、实际操作

  1. 创建 Django 项目

  2. 创建 Django App 做为后端

  3. 创建 VueJS 项目作为前端

  4. 使用 Webpack 处理前端代码

  5. 配置 Django 模板的搜索路径

  6. 配置 Django 静态文件搜索路径

  7. 开发环境

  8. 生产环境(部署到 UCloud)

我为什么要选择 Django 与 VueJS?

首先介绍一下我看重的点:


Django (MVC 框架) -


The Web framework for perfectionists with deadlines


— Python


— ORM


— 简单、清晰的配置


— Admin app


Django 仅因为 Python 的血统,就已经站在了巨人的肩膀上,配置管理( SaltStack、Ansible ),数据分析( Pandas ),任务队列( Celery ),Restful API( Django REST framework ),HTTP 请求( requests ),再加上高度抽象的 ORM,功能强大的 Query Expressions,简单清晰的配置。


着重提一下堪称神器的自带 App—Admin,有了它你再也不用将一些经常变化的配置写在文件里面,每次增删改都重新发布一次,你只需要定义出配置的 data scheme ,只需要几行代码,Django Admin 便为你提供美观,并带有权限控制的增删改查界面,而且可以通过 ORM 为它生成的 API 来做到定制化的更新,比如直接读某个 wiki 上的配置,自动的写入数据库,伪代码如下:


import pandas as pdsettings = pd.read_html('http://某个gitlab的README 或者 某个redmine wiki')settings = clean(settings)update(settings)
复制代码


最后还可以使用 django-celery 的 celery-beat 按 Interval/crontab 的方式扔更新配置的任务到 celery 队列里面,最最重要的是,这些都可以在 Django Admin 后台直接配置哦,还不够优雅?


VueJS (MVVM 框架) - Vue.js


— 数据双向绑定


— 单文件组件


— 清晰的生命周期


— 学习曲线平滑


— vue-cli


前端是我的弱项,我需要一个 MVVM 框架来提升交互和节约时间,在试过 AngularJS ,ReactJS,VueJS 之后我选择了 VueJS,因为我觉得写 VueJS 代码的感觉最接近写 Python。


着重提一下单文件组件:



特别清晰,一个文件包含且仅包含三块:

1.< template> < /template > 前端渲染的模板

2. 专为此模板写渲染逻辑的 < script>< /script>

3. 专为此模板写样式的 < style>< /style>


这样可以达到什么效果呢?一个文件一个组件,每个组件有它自己的逻辑与样式,你不用关心什么 local 什么 global ,CSS 样式加载先后、覆盖问题,因为它是『闭包』的,而且『自给自足』。


当然组件之间也是可以通信的,举个例子,我有一个组件叫 ListULB ,使用表格展示了我拥有的所有 ULB (负载均衡),ListULB 做了一件事,从 API 获取 ULB 对象列表并 for 循环展现出来, ListULB 可以放到某个页面里,可以放到弹框里,放到模态框里,任何地方都可以,因为这个组件对外交互的只有 API。


如果我现在要写一个组件叫 AddVServer ,功能是可以为任意一个 ULB 对象添加 VServer,我的写法是将在 AddVServer 组件创建的时候,将 ULB 对象传给 AddVServer 组件,这样 AddVServer 组件拿到这个对象,就可以直接根据对象的 ID 等,创建出当前行的 ULB 的 VServer 了,伪代码如下:


<ListULB>  for **ulb_object** in ulbs_list:    {{ ulb_object.name }}    {{ ulb_object.id }}    <AddVServer :current_ulb='**ulb_object**'></AddVServer></ListULB>
复制代码


注意双星号包着的对象,在 ListULB 组件里面是每行的 ULB,传给 AddServer 组件之后,变成了 current_ulb 对象,拿到 id 为 current_ulb.id 尽情的为它创建 VServer 吧。如果我要为指定 VServer 创建 RServer 呢,一样的。


看出来了吧,进行开发之前,前端组件的结构与数据的结构对应起来可以省好多时间,数据驱动前端组件,棒吗?谁不喜欢优雅的代码呢, 『Data drive everything』 多么的省脑细胞。


以上就是我选择 Django 与 VueJS 的原因。

Django 与 VueJS 是如何结合起来?

首先我选择了 VueJS 的前端渲染,自然放弃了 Django 的后端模板引擎渲染。


然后业务逻辑放到了前端,放弃了 Django 的 View(其实也就是前后端分离必要的条件)。


保留了 Django 的 Controller (URLconf) 来实现前端路由的父级路由,可以达到不同页面使用不同的前端框架, 页面内部使用各自独有的前端路由的效果,万一老大给你配了前端呢,万一前端只想写 ReactJS 呢。


保留了 Django 的 Model ,前面说了 Django 的 ORM 太好用了,而且可以配合 Django Admin。


所以综合来说就是:


M(Django) + C(Django) + MVVM (VueJS) = M + MVVM + C = MMVVMC
复制代码


(为了容易理解,并没有使用 Django 自称的 MTV 模式理解,感兴趣看看我画的图)



总结:作为以改变世界为己任的 DevOps ,MVC 框架后端渲染的柔弱表现力与繁杂的交互已经不能满足我们了,所以我选择这样构建项目,代码块中的修改都会用双星号括起来,比如:


**changed**
复制代码


本文为了精简篇幅,默认您已经安装了必要的 命令行界面(CLI),比如 vue-cli 等。

实际操作

01 创建 Django 项目

命令:


django-admin startproject ulb_manager
复制代码


结构:


├── manage.py└── ulb_manager    ├── __init__.py    ├── settings.py    ├── urls.py    └── wsgi.py
复制代码

02 进入项目根目录,创建一个 app 作为项目后端

命令:


cd ulb_managerpython manage.py startapp backend
复制代码


即:app 名叫做 backend


结构:


├── backend│   ├── __init__.py│   ├── admin.py│   ├── migrations│   │   └── __init__.py│   ├── models.py│   ├── tests.py│   └── views.py├── manage.py└── ulb_manager    ├── __init__.py    ├── settings.py    ├── urls.py    └── wsgi.py
复制代码

03 使用 vue-cli 创建一个 vuejs 作为项目前端

命令:


vue-init webpack frontend
复制代码


即:项目名叫 frontend


结构:


├── backend│   ├── __init__.py│   ├── admin.py│   ├── migrations│   │   └── __init__.py│   ├── models.py│   ├── tests.py│   └── views.py├── frontend│   ├── README.md│   ├── build│   │   └── ....│   ├── config│   │   ├── dev.env.js│   │   ├── index.js│   │   ├── prod.env.js│   │   └── test.env.js│   ├── index.html│   ├── package.json│   ├── src│   │   ├── App.vue│   │   ├── assets│   │   │   └── logo.png│   │   ├── components│   │   │   └── Hello.vue│   │   └── main.js│   ├── static│   └── test│       └── ...├── manage.py└── ulb_manager    ├── __init__.py    ├── settings.py    ├── urls.py    └── wsgi.py
复制代码


结构总结

可以看到项目根目录有两个新文件夹,一个叫 backend ,一个叫 frontend,分别是:

backend Django 的一个 app

frontend Vuejs 项目

04 接下来我们使用 webpack 打包 VusJS 项目


命令:


cd frontendnpm installnpm run build
复制代码


结构:


我引入了一些包,比如 element-ui 等,你的 static 里面的内容会不同,没关系 index.html 和 static 文件夹相同就够了。


dist├── index.html└── static    ├── css    ├──    app.42b821a6fd065652cb86e2af5bf3b5d2.css├──app.42b821a6fd065652cb86e2af5bf3b5d2.css.map    ├── fonts    │   ├── element-icons.a61be9c.eot    │   └── element-icons.b02bdc1.ttf    ├── img    │   └── element-icons.09162bc.svg    └── js        ├── 0.8750b01fa7ffd70f7ba6.js        ├── vendor.804853a3a7c622c4cb5b.js        └── vendor.804853a3a7c622c4cb5b.js.map
复制代码


构建完成会生成一个 文件夹名字叫 dist,里面有一个 index.html 和一个 文件夹 static 。

05 使用 Django 的通用视图 TemplateView

找到项目根 urls.py (即 ulb_manager/urls.py),使用通用视图创建最简单的模板控制器,访问 『/』时直接返回 index.html。


urlpatterns = [    url(r'^admin/', admin.site.urls),    **url(r'^$', TemplateView.as_view(template_name="index.html")),**    url(r'^api/', include('backend.urls', namespace='api'))]
复制代码

06 配置 Django 项目的模板搜索路径

上一步使用了 Django 的模板系统,所以需要配置一下模板使 Django 知道从哪里找到 index.html,


打开 settings.py (ulb_manager/settings.py),找到 TEMPLATES 配置项,修改如下:


TEMPLATES = [    {        'BACKEND': 'django.template.backends.django.DjangoTemplates',        # 'DIRS': [],        **'DIRS': ['frontend/dist']**,        'APP_DIRS': True,        'OPTIONS': {            'context_processors': [          'django.template.context_processors.debug',         'django.template.context_processors.request',         'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages',            ],        },    },]
复制代码


注意这里的 frontend 是 VueJS 项目目录,dist 则是运行 npm run build 构建出的 index.html 与静态文件夹 static 的父级目录。


这时启动 Django 项目,访问 / 则可以访问 index.html,但是还有问题,静态文件都是 404 错误,下一步我们解决这个问题。

07 配置静态文件搜索路径

打开 settings.py (ulb_manager/settings.py),找到 STATICFILES_DIRS 配置项,配置如下:


# Add for vuejs
STATICFILES_DIRS = [ os.path.join(BASE_DIR, "frontend/dist/static"),]
复制代码


这样 Django 不仅可以将/ulb 映射到 index.html,而且还可以顺利找到静态文件,此时访问 /ulb 我们可以看到使用 Django 作为后端的 VueJS helloworld。

08 开发环境

因为我们使用了 Django 作为后端,每次修改了前端之后都要重新构建(你可以理解为不编译不能运行),


除了使用 Django 作为后端,我们还可以在 dist 目录下面运行以下命令来看效果:


hs(即: http server)



但是问题依然没有解决,我想过检测文件变化来自动构建,但是构建是秒级的,太慢了,所以我直接使用 VueJS 的开发环境来调试,npm run dev:



毫秒,但是有个新问题,使用 VueJS 的开发环境脱离了 Django 环境,访问 Django 写的 API,出现了跨域问题,有两种方法解决,一种是在 VueJS 层上做转发(proxyTable),另一种是在 Django 层注入 header,这里我使用后者,用 Django 的第三方包 django-cors-headers 来解决跨域问题。


安装


pip install django-cors-headers
复制代码


配置(两步)


  1. settings.py 修改


MIDDLEWARE = [    'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',    **'corsheaders.middleware.CorsMiddleware',** 'django.middleware.common.CommonMiddleware',    'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',]
复制代码


这里要注意中间件加载顺序,列表是有序的哦。


  1. settings.py 添加


CORS_ORIGIN_ALLOW_ALL = True
复制代码


至此,我的开发环境就搭建完成了。

09 生产环境部署(部署到 UCloud )

接下来我们尝试将项目部署到 UCloud 云主机上,主机管理列表,如下所示:



这里注意记住你的外网 IP,下面的 IP 替换成你的


环境搭建与部署


登录主机,用你刚填写的密码:


ssh root@120.132.**.75


CentOS 系统可以使用 yum 安装必要的包


# 如果你使用git来托管代码的话yum install git# 如果你要在服务器上构建前端yum install nodejsyum install npmyum install nginx
复制代码


我们使用 uwsgi 来处理 Django 请求,使用 nginx 处理 static 文件(即之前 build 之后 dist 里面的 static,这里默认前端已经打包好了,如果在服务端打包前端需要安装 nodejs,npm 等)。


安装 uWsgi


yum install uwsgi# 或者pip install uwsgi
复制代码


我们使用配置文件启动 uwsgi,比较清楚。


uwsgi 配置文件:


[uwsgi]socket = 127.0.0.1:9292stats = 127.0.0.1:9293workers = 4# 项目根目录chdir = /opt/inner_ulb_managertouch-reload = /opt/inner_ulb_managerpy-auto-reload = 1# 在项目跟目录和项目同名的文件夹里面的一个文件module= inner_ulb_manager.wsgipidfile = /var/run/inner_ulb_manager.piddaemonize = /var/log/inner_ulb_manager.log
复制代码


nginx 配置文件:


server {    listen 8888;    server_name 120.132.**.75;    root /opt/inner_ulb_manager;    access_log /var/log/nginx/access_narwhals.log;    error_log /var/log/nginx/error_narwhals.log;    location / {            uwsgi_pass 127.0.0.1:9292;            include /etc/nginx/uwsgi_params;    }    location /static/ {            root  /opt/inner_ulb_manager/;            access_log off;    }    location ^~ /admin/ {            uwsgi_pass 127.0.0.1:9292;            include /etc/nginx/uwsgi_params;    }}
复制代码


/opt/inner_ulb_manager/static 即为静态文件目录,那么现在我们静态文件还在 frontend/dist 怎么办,不怕,Django 给我们提供了命令:


先去 settings 里面配置:


STATIC_ROOT = os.path.join(BASE_DIR, "static")
复制代码


然后在存在 manage.py 的目录,即项目跟目录执行:


python manage.py collectstatic
复制代码


这样 frontend/dist/static 里面的东西就到了项目根目录的 static 文件夹里面了。


那么为什么不直接手动把构建好的 dist/static 拷过来呢,因为开始提过 Django 自带的 App:admin 也有一些静态文件(css,js 等),它会一并 collect 过来,毕竟 nginx 只认项目跟目录的静态文件,它不知道 django 把它自己的需求文件放到哪了。


开头说过 Django 配置灵活,那么我们专门为 Django 创建一个生产环境的配置 prod.py,prod.py 与 默认 settings.py 同目录。


# 导入公共配置from .settings import * # 生产环境关闭DEBUG模式DEBUG = False # 生产环境开启跨域CORS_ORIGIN_ALLOW_ALL = False # 特别说明,下面这个不需要,因为前端是VueJS构建的,它默认使用static作为静态文件入口,我们nginx配置static为入口即可,保持一致,没Django什么事:STATIC_URL = '/static/'
复制代码


如何使用这个配置呢,进入 wisg.py 即 uwsgi 配置里面的 module 配置修改为:


import osfrom django.core.wsgi import get_wsgi_applicationos.environ.setdefault("DJANGO_SETTINGS_MODULE", "**inner_ulb_manager.prod**")application = get_wsgi_application()
复制代码


启动 uwsgi:


uwsgi --ini inner_ulb_manager.ini
复制代码


启动 ngingx:


service nginx start
复制代码


至此,部署就完成了。

10 效果图

List 组件:



传单个 ULB 对象给 Detail 组件使用即可。


Detail 组件:



当然里面还实现了前面提到的 ULB 的 VServer 创建,VServer 的 RServer 的创建等。


本文转载自公众号 UCloud 技术(ID:ucloud_tech)。


原文链接:


https://mp.weixin.qq.com/s/VlSGrjIzMlNfOJUZSDaxSw


2019-11-13 16:492265

评论

发布
暂无评论
发现更多内容

互联网行业-镭速文件传输系统方案

镭速

Spring框架中的线程池

demo123567

spring 线程池

2023-06-15:说一说Redis的Key和Value的数据结构组织?

福大大架构师每日一题

redis 福大大架构师每日一题

原点安全助力金融机构消费者个人信息保护合规

原点安全

数据安全 金融机构 消费者个人信息保护

人体分割识别图像技术的原理及应用

数据堂

云计算架构设计原则

穿过生命散发芬芳

6 月 优质更文活动

微软增加100亿美元AI收入,Salesforce如何对垒?

B Impact

六大类型JavaScript题型

不叫猫先生

JavaScript 6 月 优质更文活动

首添机密计算创新成果!龙蜥首获 ACM SIGSOFT 杰出论文奖

OpenAnolis小助手

云原生 龙蜥社区 sig 机密计算 ICSE

UI自动化的稳定性和效率

QE_LAB

自动化测试 UI自动化测试 appium

华为云CodeArtBuild减负!云端编译构建,让你的开发省时省力!

华为云PaaS服务小智

云计算 代码 华为云 编译构建

HarmonyOS 极客马拉松2023 正式启动,诚邀极客们用键盘码出无限可能!

HarmonyOS开发者

HarmonyOS

阿里云斩获 4 项年度云原生技术服务优秀案例

阿里巴巴云原生

阿里云 云原生

人体分割识别图像技术的挑战和未来发展

数据堂

视频与图片检索中的多模态语义匹配模型 ——原理、启示、应用与展望

百度Geek说

企业号 6 月 PK 榜 模态 视频模拟 图片模拟 6 月 优质更文活动

百度文心一格x京东618:打造电商行业首个AI线下广告,节省80%制作成本

飞桨PaddlePaddle

百度 飞桨 AIGC 京东618

HarmonyOS 极客马拉松2023 正式启动,诚邀极客们用键盘码出无限可能!

说山水

你一定要悄悄学会怎么把Vimeo视频保存到手机相册,然后惊艳所有人!

frank

C语言代码封装MQTT协议报文,了解MQTT协议通信过程

DS小龙哥

6 月 优质更文活动

WeOpsV4.1重磅出击,日志监控功能横空出世!

嘉为蓝鲸

运维 日志 weops 嘉为蓝鲸

自动化回归测试平台 AREX 的 Mock 实现原理

AREX 中文社区

Java Mock测试框架 流量回放

云小课|RDS for MySQL参数模板一键导入导出,参数配置轻松搞定

华为云开发者联盟

数据库 后端 华为云 华为云开发者联盟 企业号 6 月 PK 榜

Django笔记四十三之使用uWSGI部署Django系统

Hunter熊

Python django 部署 uwsgi

TrafficRoute:一体化的DNS解析和流量调度套件

火山引擎边缘云

技术 流量 解析 火山引擎边缘云

洞察开源代码平台“创新力”|2023开放原子全球开源峰会开源协作平台分论坛成功举办

开放原子开源基金会

开源 开放原子全球开源峰会 开放原子 开源协作平台

开源教育决定未来|2023开放原子全球开源峰会开源教育与人才分论坛成功召开

开放原子开源基金会

开源 开放原子全球开源峰会 开放原子 开源教育与人才

GOTC峰会Sermant发布1.1.0-beta版本,带来哪些提升?

华为云开源

#云原生 #开源 流量治理 #微服务

把数字中国,建立在行业感知的底座上

脑极体

行业感知

C语言编程语法—排序算法

芯动大师

C语言 排序算法 6 月 优质更文活动

vivo 帐号服务稳定性建设之路-平台产品系列06

vivo互联网技术

帐号 服务稳定性 架构优化

共建、共享开源EDA核心共性技术框架|2023开放原子全球开源峰会开源EDA分论坛成功举办

开放原子开源基金会

开源 开放原子全球开源峰会 开放原子 开源EDA

教你如何使用 Django + Vue.js 快速构建项目_文化 & 方法_高远_InfoQ精选文章