这几天研究了一下vue + django 前后端分离框架,顺便在自己的阿里云上部署了一下,主要在django与nginx的交互上遇到了一些问题,在此做记录与分享
github地址 https://github.com/qianhaoq/django_with_vue
一. django + vue的一些问题
由于我使用了django +Vue 的前后端分离技术进行开发,在构建时会遇到一些问题,可以参考
https://zhuanlan.zhihu.com/p/25080236
第一步
pip3 install django-cors-headers
第二步
在settings.py 的 MIDDLEWARE 中加入corsheaders(注意顺序)
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',
]
第三步
在settings.py 中添加
CORS_ORIGIN_ALLOW_ALL = True
二. 在nginx 上配置django
1.nginx
安装nginx
sudo apt install nginx
nginx基本操作命令
# 启动nginx服务
sudo /etc/init.d/nginx start
# 关闭服务
sudo /etc/init.d/nginx stop
# 重启nginx服务( restart = stop + start )
sudo /etc/init.d/nginx restart
# 重新加载nginx配置文件
sudo /etc/init.d/nginx reload
# 注 service nginx reload 重新加载配置文件
# reload不用重启服务,直接重新加载配置文件,客户端感觉不到服务异常,平滑切换。
2.uwsgi
why django + uwsgi + nginx ?
概念说明:
- APP(应用程序),就是开发者写的应用程序,例如django,bottle这些。记录怎么处理客户端发来的请求的逻辑部分。
- WSGI,是一个协议,Python用于Web开发的协议
- uWSGI,是一个程序,充当Web服务器或中间件。
- 如果架构是Nginx+uWSGI+APP,uWSGI是一个中间件
- 如果架构是uWSGI+APP,uWSGI是一个服务器
- uwsgi,是uWSGI程序实现的一个自有的协议。
Web协议出现顺序:
CGI -> FCGI -> WSGI -> uwsgi
- CGI,最早的协议
- FCGI,比CGI快
- WSGI,Python专用的协议
- uwsgi,比FCGI和WSGI都快,是uWSGI项目自有的协议,主要特征是采用二进制来存储数据,之前的协议都是使用字符串,所以在存储空间和解析速度上,都优于字符串型协议.官方介绍
传输原理
web client <-> nginx <-> socket <-> uwsgi <-> django
安装uwsgi
sudo apt-get install build-essential python3-dev
sudo pip3 install uwsgi
为了测试uwsgi ,可以写一个test.py 如下
# test.py
def application(env, start_response):
start_response('200 ok', [('Content-Type', 'text/html')])
return ["Hello World"]
运行命令
uwsgi --http :8000 --wsgi-file test.py
然后打开浏览器,输入地址 http://127.0.0.1:8000
如果显示 "hello world",则运行成功,下面3个环节正常
web client <-> uWSGI <-> Python
这边有一个bug,记录一下,
uwsgi --http :8001 --wsgi-file test.py
*** Starting uWSGI 2.0.15 (64bit) on [Wed Jan 10 20:26:57 2018] ***
compiled with version: 5.4.0 20160609 on 08 January 2018 21:11:57
os: Linux-4.10.0-43-generic #47~16.04.1-Ubuntu SMP Wed Dec 13 19:23:27 UTC 2017
nodename: qh-G752VT
machine: x86_64
clock source: unix
detected number of CPU cores: 8
current working directory: /home/qh/test
detected binary path: /usr/local/bin/uwsgi
!!! no internal routing support, rebuild with pcre support !!!
*** WARNING: you are running uWSGI without its master process manager ***
关键为!!! no internal routing support, rebuild with pcre support !!!
需要先卸载uwsgi,安装pcre路由
sudo pip3 uninstall uwsgi
sudo apt install libpcre3 libpcre3-dev
sudo pip3 install uwsgi
测试django与uwsgi是否正常
首先切换到django项目根目录下(即manage.py 所在目录)
通过uwsgi 运行django
我的项目目录树
comic
├── backend
├── comic
├── comic_uwsgi.ini
├── db.sqlite3
├── frontend
├── manage.py
├── media
├── nginx.conf
├── static
└── test.py
# 注意,此处的comic,即你的项目名称
uwsgi --http :8000 --module comic.wsgi
运行以上命令后,访问http://127.0.0.1:8000 查看django是否正常运行
3. 配置nginx
默认nginx配置文件为/etc/nginx/sites-enabled/default,它是指向sites-available/default的一个软链接
default -> /etc/nginx/sites-available/default
我们可以删除这个软链接,然后建一个自己的nginx.conf,再在sites-enabled下软链接到自己的配置文件
或者,也可以直接写改default(通常不建议这样做,也可以先备份一下然后直接修改)
此处贴一下我的nginx.conf
upstream django {
server unix:////home/qh/git/django_with_vue/comic/comic.sock;
# server 127.0.0.1:8001;
}
# Default server configuration
#
server {
listen 80;
charset utf-8;
server_name .example.com;
#root /home/qh/git/django_with_vue/comic;
location /media {
alias /home/qh/git/django_with_vue/comic/media;
}
location /static {
alias /home/qh/git/django_with_vue/comic/static;
}
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
# try_files $uri $uri/ =404;
uwsgi_pass django;
include /etc/nginx/uwsgi_params;
}
}
注意,修改完配置后需要用
sudo /etc/init.d/nginx reload
重载配置文件,最好再restart一下
sudo /etc/init.d/nginx restart
4. django端配置
部署static文件
在django的settings.py文件中加入下一行内容
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
然后运行
python3 manage.py collectstatic
顺便贴一下我的comic/wsgi.py
# wsgi.py
import os
import sys
from os.path import dirname,abspath
from django.core.wsgi import get_wsgi_application
PROJECT_DIR = dirname(dirname(abspath(__file__)))
sys.path.insert(0,PROJECT_DIR)
os.environ["DJANGO_SETTINGS_MODULE"] = "comic.settings"
application = get_wsgi_application()
以及在django的settings.py文件中配置ALLOWED_HOSTS,关闭debug模式
DEBUG = False
ALLOWED_HOSTS = ['*']
测试uwsgi是否能拉起django app
# 若权限为664,可能出现502的情况,最好配置为666
uwsgi --socket comic.sock --module comic.wsgi --chmod-socket=666
打开浏览器,访问http://127.0.0.1,查看django项目是否正常运行(因为我的配置文件里用的80端口,所以不用额外指定端口)
若可以正常运行,则可以通过ini配置文件来指定这一切
在manage.py 的相同目录下,写一个comic_uwsgi.ini
# comic_uwsgi.ini file
[uwsgi]
# Django-related settings
# the base directory (full path)
chdir = /home/qh/git/django_with_vue/comic
# Django's wsgi file
module = comic.wsgi
# the virtualenv (full path)
#home = /path/to/virtualenv
# process-related settings
# master
master = true
# maximum number of worker processes
processes = 2
# the socket (use the full path to be safe
socket = /home/qh/git/django_with_vue/comic/comic.sock
# ... with appropriate permissions - may be needed
chmod-socket = 666
# clear environment on exit
vacuum = true
运行方式为
uwsgi --ini comic_uwsgi.ini
如果要开机启动的话,添加到/etc/rc.local 中即可
由于用到了mongoDB,restful API,django_filters, 需要额外安装以下依赖
sudo pip3 install mongoengine
sudo pip3 install django-rest-framework-mongoengine
sudo pip3 install django-rest-framework
sudo pip3 install django_filters django_filter
同时还要注意mongodb的安装与配置
sudo apt install mongo
导入json
mongoimport --db comic --collection pokemon --file items.json
vue前端文件有改动以后需要重新执行下列语句生效
python3 manage.py collectstatic