django生產(chǎn)環(huán)境搭建(uWSGI+django+nginx+python+MySQL)
1、系統(tǒng)環(huán)境,必要知識(shí)
#cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core) #uname -r 3.10.0-862.3.2.el7.x86_64
暫時(shí)關(guān)閉防護(hù)墻,關(guān)閉selinux:
#systemctl stop firewalld.service #setenforce 0 #getenforce Permissive
準(zhǔn)備知識(shí):
django:一個(gè)基于python的開源web框架。
uWSGI:一個(gè)基于自有的uwsgi協(xié)議,wsgi協(xié)議和http服務(wù)協(xié)議的web網(wǎng)關(guān)
nginx:高性能的代理web服務(wù)器
wsgi.py:django項(xiàng)目自帶的wsgi接口文件(位于:項(xiàng)目/項(xiàng)目名/wsgi.py)
整個(gè)項(xiàng)目流程:
首先客戶端通過瀏覽器訪問服務(wù)器資源;nginx作為對(duì)外服務(wù)的端口(80),nginx接收到客戶端http請(qǐng)求后會(huì)解包分析,如果是靜態(tài)文件就去配置的靜態(tài)文件中查找資源并返回給客戶端,如果是動(dòng)態(tài)資源,nginx就通過配置文件將請(qǐng)求傳遞給uwsgi處理,并轉(zhuǎn)發(fā)給uwsgi,wsgi根據(jù)請(qǐng)求調(diào)用django工程的文件和函數(shù),處理后django將返回值交給wsgi,wsgi將返回值進(jìn)行打包,轉(zhuǎn)發(fā)給uWSGI,uWSGI接收到數(shù)據(jù)后轉(zhuǎn)發(fā)給nginx,最終返回給客戶端。
2、安裝python3.6.5
(1)安裝python依賴包
yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel python-devel
(2)安裝python
#wget https://www.python.org/ftp/python/3.6.5/Python-3.6.5.tgz #mkdir -p /usr/local/python356 #tar zxvf Python-3.6.5.tgz #cd Python-3.6.5 #./configure --prefix=/usr/local/python356 #make #make install #ln -s /usr/local/python356/bin/python3 /usr/local/bin/python3 #ln -s /usr/local/python356/bin/pip3 /usr/local/bin/pip3 #pip3 install --upgrade pip #更新pip #pip3 install ipython #安裝ipython方便調(diào)試
測(cè)試安裝是否正常:
#python3 -V Python 3.6.5 #pip3 -V pip 10.0.1 from /usr/local/python356/lib/python3.6/site-packages/pip (python 3.6)
3、安裝Django
#pip3 install django #ln -s /usr/local/python356/bin/django-admin /usr/local/bin/django-admin
創(chuàng)建項(xiàng)目:
#django-admin startproject mysite
創(chuàng)建app:
#cd mysite/ #django-admin startapp app01
在項(xiàng)目路徑下創(chuàng)建模板文件目錄(templates)和靜態(tài)文件目錄(static),后面會(huì)用到
# cd mysite/ # mkdir templates static
配置setting.py文件,配置允許訪問主機(jī)名、將APP加入到項(xiàng)目、添加模板搜索路徑
# vim mysite/settings.py
ALLOWED_HOSTS = ["*"] #允許本機(jī)所有地址訪問
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01',#加入app名
]
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR,'templates')], #加入模板搜索路徑
......
]
在views.py文件中創(chuàng)建視圖函數(shù)
# vim app01/views.py from django.shortcuts import render def index(request): return render(request,"app01/index.html")
在templates目錄中新建測(cè)試模板文件
# mkdir -p templates/app01 # vim templates/app01/index.html <h1>test django server</h1>
在urls.py文件中建立路由
# vim mysite/urls.py
from django.contrib import admin
from django.urls import path,re_path #添加
from app01 import views #添加
urlpatterns = [
path('admin/', admin.site.urls),
re_path('^$',views.index,name='index'), #添加的路由
]
檢查配置是否有錯(cuò)誤:
# python3 manage.py check System check identified no issues (0 silenced).
運(yùn)行測(cè)試服務(wù)器,測(cè)試服務(wù)是否正常
# python3 manage.py runserver 0:8000 #在瀏覽器中測(cè)試是否正常顯示網(wǎng)頁(yè)內(nèi)容 #注意防火墻和selinux是否關(guān)閉或允許相關(guān)端口訪問 #curl 127.0.0.1:8000 <h1>test django server</h1>
4、安裝uWSGI
使用python的pip工具包安裝:
#pip3 install uwsgi #ln -s /usr/local/python356/bin/uwsgi /usr/local/bin/uwsgi #建立軟鏈接 #uwsgi --version #檢查安裝成功 2.0.17
先在項(xiàng)目目錄下建立一個(gè)測(cè)試文件:
# vim foobar.py
def application(env,start_response):
start_response('200 ok',[('Content-Type','text/html')])
return [b"Hello World"]
然后采用測(cè)試腳本方式啟動(dòng)服務(wù):
# uwsgi --http :9000 --wsgi-file foobar.py #通過瀏覽器訪問http://ip:9000能看到hello world說明成功 #然后停止服務(wù)
接下來配置uwsgi部署django服務(wù):
#運(yùn)行測(cè)試服務(wù),--http指定服務(wù)端口,--chdir指定django項(xiàng)目目錄,--wsgi-file指定項(xiàng)目中的wsgi.py文件 # uwsgi --http :9000 --chdir /opt/mysite/ --wsgi-file mysite/wsgi.py --master --ocesses 4 --threads 2 --stats 127.0.0.1:9191 #通過瀏覽器http://ip:9000 #如能訪問到diango模板中的html文件中的內(nèi)容就算成功 #我的上面django模板中配置的內(nèi)容是 test django server
建立uWSGI的配置文件,在django項(xiàng)目中建立uwsgi.ini文件,并配置好django項(xiàng)目,此處使用socket鏈接,后面通過nginx反向代理
#注意此處的配置指定用戶nginx必須存在 [uwsgi] socket = 127.0.0.1:9090 chdir = /djproject/mysite module = mysite.wsgi #這里填的是相對(duì)路徑 master = true processes = 2 threads = 2 max-requests = 2000 vacuum = true daemonize = /djproject/mysite/uwsgi.log stats = 127.0.0.1:9001 post-buffering = 65535 buffer-size = 65535 harakiri-verbose = true harakiri = 300 uid = nginx pidfile = /djproject/mysite/uwsgi.pid
參數(shù)說明:
socket:使用套接字鏈接
http:通過http加端口的方式
wsgi-file:指定加載的wsgi文件
chdir:指定工程的絕對(duì)路徑,如Django的項(xiàng)目路徑
module:指定web應(yīng)用的入口模塊,如Django項(xiàng)目下的wsgi.py接口文件
master:?jiǎn)?dòng)主進(jìn)程
processes:?jiǎn)?dòng)進(jìn)程數(shù)
threads:?jiǎn)?dòng)線程數(shù)
max-requests:最大請(qǐng)求數(shù)
daemonize:指定uWSGI日志文件路徑
stats:指定狀態(tài)查詢端口,如:127.0.0.1:9001
wsgi-file:指定啟動(dòng)的文件
post-buffering:設(shè)置緩沖區(qū)
buffer-size:設(shè)置緩沖區(qū)文件大小
harakiri-verbose:設(shè)置超時(shí)true為開啟
harakiri:設(shè)置超時(shí)時(shí)間
uid、gid:設(shè)置用戶和組
pidfile:指定啟動(dòng)時(shí)的pid文件路徑
vacuum = true #當(dāng)服務(wù)器退出的時(shí)候自動(dòng)刪除unix socket文件和pid文件
uwsgi信號(hào)控制:
HUP :優(yōu)雅的重新加載所有進(jìn)程和配置,同(--reload)一樣
TERM ?。簭?qiáng)制重新加載主進(jìn)程和配置
INT :立即殺死整個(gè)uWSGI;同于:--stop
QUIT :立即殺死真?zhèn)€uWSGI
重新啟動(dòng)實(shí)例:
#kill -HUP `cat /tmp/project-mast.pid` #uwsgi --reload /tmp/project-master.pid
還可以在python程序中使用uwsgi.reload()重新加載
停止服務(wù)器:
#uwsgi --stop /tmp/project-master.pid #kill -INT `cat /tmp/project-master.pid`
編寫啟動(dòng)腳本:
#vim /etc/init.d/uwsgi
#!/bin/bash
#this is uwsgi server script
. /etc/init.d/functions
uwsgi=/usr/local/bin/uwsgi
uwsgi_pid=/djangoproject/mysite/uwsig.pid
uwsgi_conf=/djangoproject/mysite/uwsigconf.ini
uwsgi_pn=`ps -ef|grep -v "grep"|grep -c "uwsgi"`
ERVAL=0
start(){
$uwsgi --ini $uwsgi_conf >& /dev/unll
ERVAL=$?
if [ $ERVAL -eq 0 ];then
action "uwsgid starting ..." /bin/true
else
action "uwsgid start is error" /bin/false
fi
}
stop(){
$uwsgi --stop $uwsgi_pid >& /dev/null
ERVAL=$?
if [ $ERVAL -eq 0 ];then
action "uwsgid stoping ..." /bin/true
else
action "uwsgid stop is error" /bin/false
fi
}
case "$1" in
start)
if [ $uwsgi_pn -ge 5 ];then
action "uwsgi is running!" /bin/false
else
start
ERVAL=0
fi
;;
stop)
if [ $uwsgi_pn -ge 5 ];then
stop
ERVAL=0
else
action "uwsgi no running!" /bin/false
fi
;;
reload)
if [ $uwsgi_pn -ge 5 ];then
$uwsgi --reload $uwsgi_pid >&/dev/null
ERVAL=$?
[ $ERVAL -eq 0 ] && action "uwsgi reloading ..." /bin/true
else
action "uwsgi reload error" /bin/false
fi
;;
restart)
stop
sleep 2
start
;;
*)
echo $"Usage: $0 {start|stop|restart|reload|status}"
ERVAL=2
esac
exit $ERVAL
centOS7 system系統(tǒng)服務(wù)腳本:
#cat /usr/lib/systemd/system/uwsgi.service [Unit] Description=uwsgi service After=network.target [Service] Type=forking PIDFile=/run/uwsgi.pid ExecStartPre=/usr/bin/rm -f /run/uwsgi.pid ExecStart=/usr/local/python356/bin/uwsgi --ini /djproject/mysite/uwsgi.ini ExecReload=/bin/kill -s HUP $MAINPID KillSignal=SIGQUIT TimeoutStopSec=5 KillMode=process PrivateTmp=true [Install] WantedBy=multi-user.target
centOS7建立system啟動(dòng)腳本后需要加載下:
systemctl daemon-reload
測(cè)試服務(wù):
#uwsgi --ini /djproject/mysite/uwsgi.ini #啟動(dòng)服務(wù) #ps -ef|grep "uwsgi"#查看進(jìn)程 root 1035961 2 16:02 ? 00:00:00 /usr/local/python356/bin/uwsgi --ini /djproject/mysite/uwsgi.ini root 103598 103596 0 16:02 ? 00:00:00 /usr/local/python356/bin/uwsgi --ini /djproject/mysite/uwsgi.ini root 103599 103596 0 16:02 ? 00:00:00 /usr/local/python356/bin/uwsgi --ini /djproject/mysite/uwsgi.ini #netstat -lntp|grep "uwsgi" tcp 00 127.0.0.1:9090 0.0.0.0:*LISTEN103596/uwsgi tcp 00 127.0.0.1:9001 0.0.0.0:*LISTEN103596/uwsgi
看上面進(jìn)程是少了一個(gè)主進(jìn)程,通過systemctl 查看就清楚了:
#systemctl status -l uwsgi.service ● uwsgi.service - uwsgi service Loaded: loaded (/usr/lib/systemd/system/uwsgi.service; disabled; vendor preset: disabled) Active: active (running) since 五 2018-05-25 16:02:06 CST; 4min 14s ago Process: 103593 ExecStart=/usr/local/python356/bin/uwsgi --ini /djproject/mysite/uwsgi.ini (code=exited, status=0/SUCCESS) Process: 103591 ExecStartPre=/usr/bin/rm -f /run/uwsgi.pid (code=exited, status=0/SUCCESS) Main PID: 103596 (uwsgi) CGroup: /system.slice/uwsgi.service ├─103596 /usr/local/python356/bin/uwsgi --ini /djproject/mysite/uwsgi.ini ├─103598 /usr/local/python356/bin/uwsgi --ini /djproject/mysite/uwsgi.ini └─103599 /usr/local/python356/bin/uwsgi --ini /djproject/mysite/uwsgi.ini 5月 25 16:02:06 ZPY systemd[1]: Starting uwsgi service... 5月 25 16:02:06 ZPY uwsgi[103593]: [uWSGI] getting INI configuration from /djproject/mysite/uwsgi.ini 5月 25 16:02:06 ZPY systemd[1]: PID file /run/uwsgi.pid not readable (yet?) after start. 5月 25 16:02:06 ZPY systemd[1]: Started uwsgi service. #通過查看uwsgi的日志,如沒報(bào)錯(cuò),就接著下一步,部署nginx
5、安裝nginx
這里采用yum安裝nginx:
yum -y install nginx
配置nginx反向代理uwsgi服務(wù):
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfileon;
tcp_nopush on;
tcp_nodelayon;
keepalive_timeout65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
server {
listen 80;
server_name localhost;
charset utf-8;
access_log/var/log/nginx/nginx_access.log main;
error_log /var/log/nginx/nginx_error.log;
client_max_body_size 75M;
location /static {
alias /djproject/mysite/static/ckeditor/; #指定django的靜態(tài)文件
}
location / {
include /etc/nginx/uwsgi_params; #加載uwsgi模塊
uwsgi_pass 127.0.0.1:9090;#所有請(qǐng)求轉(zhuǎn)到9090端口交給uwsgi處理
}
}
}
此處記錄下配置uwsgi和nginx套接字通信的坑:
第一個(gè),nginx日志報(bào)錯(cuò):
connect() to unix:///tmp/uwsgi.sock failed (2: No such file or directory) while connecting to upstream ......
可以明明uwsgi配置sock套接字通信在/tmp目錄下明明有uwsgi.sock文件,而且/tmp目錄是777權(quán)限,為什么nginx找不到套接字文件,經(jīng)過google,百度查資料終于在stackoverflow上找到答案:是因?yàn)閏entOS7系統(tǒng)中/tmp臨時(shí)目錄,使用了命名空間的臨時(shí)目錄,對(duì)于每個(gè)服務(wù)只能訪問自己創(chuàng)建的臨時(shí)文件,所以我們不應(yīng)該將sock文件放入/tmp目錄,而因該放入/run目錄下
第二個(gè),uwsgi日志報(bào)錯(cuò):
bind(): Permission denied [core/socket.c line 230]
經(jīng)過第一個(gè)錯(cuò)誤折騰,終于可以了,但放入/run目錄后,uwsgi啟動(dòng)不了了,權(quán)限不夠,這個(gè)問題解決簡(jiǎn)單,只需給/run目錄,有uwsgi服務(wù)用戶也就是uid指定的用戶有寫入權(quán)限即可,或者直接給/run目錄777的權(quán)限但這樣不安全。
#chmod o+w /run #我的解決方法
下面是uwsgi和nginx的配置:
#vim /uwsgi.ini [uwsgi] socket = /run/uwsgi.sock #使用sock文件 chdir = /mysite/myblog module = myblog.wsgi master = true processes = 2 threads = 2 max-requests = 2000 vacuum = true home = /mysite daemonize = /var/log/uwsgi/uwsgi.log stats = 127.0.0.1:9001 post-buffering = 65535 buffer-size = 65535 harakiri-verbose = true harakiri = 300 pidfile = /run/uwsgi.pid vacuum = true
#vim /etc/ningx/nginx.conf
...
server {
......
location /static {
alias /opt/mysite/static;
}
location / {
include /etc/nginx/uwsgi_params;
uwsgi_pass unix:///run/uwsgi.sock;#指定sock文件
}
}
...
6、MySQL安裝配置
#下載二進(jìn)制包安裝 wget https://downloads.mysql.com/archives/get/file/mysql-5.5.32-linux2.6-x86_64.tar.gz tar zxvf mysql-5.5.32-linux2.6-x86_64.tar.gz mv mysql-5.5.32-linux2.6-x86_64 /usr/local/mysql-5.5.32 ln -s /usr/local/mysql-5.5.32 /usr/local/mysql useradd -s /sbin/nologin -M mysql mkdir /mysql/data -p chown -R mysql.mysql /mysql/data cd /usr/local/mysql #添加配置文件和啟動(dòng)腳本 cp support-files/my-small.cnf /etc/my.cnf cp support-files/mysql.server /etc/init.d/mysqld #初始化數(shù)據(jù)庫(kù) ./scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql --datadir=/mysql/data/ echo $? #修改啟動(dòng)腳本路徑 sed -i 's#^basedir=#basedir=/usr/local/mysql#g' /etc/init.d/mysqld sed -i 's#^datadir=#datadir=/mysql/data#g' /etc/init.d/mysqld chmod +x /etc/init.d/mysqld #啟動(dòng)和關(guān)閉MySQL /etc/init.d/mysqld start /etc/init.d/mysqld stop #方法2: /usr/local/mysql/bin/msyql_safe & #后臺(tái)啟動(dòng) mysqladmin shutdown #優(yōu)雅關(guān)閉MySQL服務(wù) #查看運(yùn)行狀態(tài) #netstat -lntup|grep 3306 tcp 00 0.0.0.0:33060.0.0.0:*LISTEN70099/mysqld #添加系統(tǒng)自啟動(dòng) chkconfig --add mysqld chkconfig --level 345 mysqld on #添加環(huán)境變量 echo "PATH=/usr/local/mysql/bin:$PATH" >> /etc/profile source /etc/profile #修改初始化密碼 mysqladmin -uroot password '123456' #建立一個(gè)數(shù)據(jù)庫(kù),后面要用到 MySQL [(none)]> create database django; Query OK, 1 row affected (0.00 sec) #centOS7下通過epel源yum安裝MySQL # yum install epel-release # yum -y install mariadb mariadb-devel mariadb-server # systemctl enable mariadb # systemctl start mariadb# mysql -e "select version();" +----------------+ | version()| +----------------+ | 5.5.60-MariaDB | +----------------+
#建立個(gè)數(shù)據(jù)庫(kù)后面要用到 MariaDB [(none)]> create database django charset 'utf8'; MariaDB [(none)]> grant all on django.* to 'admin'@'127.0.0.1' identified by '123.com'; MariaDB [(none)]> flush privileges;
(1)配置Django鏈接MySQL:
在setting中,Django默認(rèn)使用的是sqlite數(shù)據(jù)庫(kù):
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
修改成MySQL數(shù)據(jù)庫(kù)配置:
DATABASES = {
'default':{
'ENGINE': 'django.db.backends.mysql',
'NAME': 'django',
'USER': 'root',
'PASSWORD': '123.com',
'HOST': '127.0.0.1',
'PORT': '3306',
}
}
ENGINE : 指定數(shù)據(jù)庫(kù)驅(qū)動(dòng),不同的數(shù)據(jù)庫(kù)這個(gè)字段不同,下面是常見的集中數(shù)據(jù)庫(kù)的ENGINE的寫法:
django.db.backends.postgresql # PostgreSQL django.db.backends.mysql # mysql django.db.backends.sqlite3 # sqlite django.db.backends.oracle# oracle
NAME: 指定的數(shù)據(jù)庫(kù)名,如果是sqlite的話,就需要填數(shù)據(jù)庫(kù)文件的絕對(duì)位置
USER: 數(shù)據(jù)庫(kù)登錄的用戶名,mysql一般都是root
PASSWORD:登錄數(shù)據(jù)庫(kù)的密碼,必須是USER用戶所對(duì)應(yīng)的密碼
HOST: 由于一般的數(shù)據(jù)庫(kù)都是C/S結(jié)構(gòu)的,所以得指定數(shù)據(jù)庫(kù)服務(wù)器的位置,我們一般數(shù)據(jù)庫(kù)服務(wù)器和客戶端都是在一臺(tái)主機(jī)上面,所以一般默認(rèn)都填127.0.0.1
PORT:數(shù)據(jù)庫(kù)服務(wù)器端口,mysql默認(rèn)為3306
HOST和PORT都可以不填,使用默認(rèn)的配置,但是如果你有更改默認(rèn)配置的話,就需要填入更改后的
配置完這,下面就需要裝python連接mysql數(shù)據(jù)庫(kù)的驅(qū)動(dòng)程序,首先,需要安裝mysql的開發(fā)包
#yum install mysql-devel#安裝MySQL插件 #pip3 install mysqlclient #安裝MySQL驅(qū)動(dòng)
#測(cè)試django配置 # python3 manage.py check
環(huán)境搭建到此就完成了,下面開始開發(fā)項(xiàng)目
7、編寫一個(gè)簡(jiǎn)單的博客系統(tǒng)
(1)數(shù)據(jù)建模,規(guī)劃博客內(nèi)容字段
#首先裝兩個(gè)包django-ckeditor、pillow分別用來添加富文本和縮略圖用
# pip3 install django-ckeditor pillow
#vim app01/models.py
from django.db import models
from django.utils import timezone #導(dǎo)入時(shí)間模板
from django.contrib.auth.models import User #導(dǎo)入用戶
from ckeditor_uploader.fields import RichTextUploadingField #導(dǎo)入富文本模板
class blog_articles(models.Model):
title = models.CharField(max_length=300,verbose_name="文章標(biāo)題")
author = models.ForeignKey(User,on_delete=models.CASCADE,related_name="blog_posts",verbose_name="文章作者")
body = RichTextUploadingField(verbose_name="文章內(nèi)容")
description = RichTextUploadingField(verbose_name="文章描述")
publish = models.DateTimeField(default=timezone.now,verbose_name="發(fā)表時(shí)間")
picture = models.ImageField(upload_to="images") #圖片
class Meta:
ordering = ("-publish",)#按時(shí)間倒序排列
def __str__(self):
return self.title#顯示文章標(biāo)題
(2)配置setting.py
#vim mysite/settings.py INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01', 'ckeditor',#加入模塊到項(xiàng)目 'ckeditor_uploader', #加入模板 ] LANGUAGE_CODE = 'zh-hans'#配置中文 TIME_ZONE = 'Asia/Shanghai' #配置時(shí)區(qū) USE_I18N = True USE_L10N = True USE_TZ = False #關(guān)閉UTC時(shí)間 STATIC_URL = '/static/' STATICFILES_DIRS = [os.path.join(BASE_DIR,"static"),] #配置靜態(tài)文件路徑 MEDIA_URL = '/media/' #媒體文件路由 MEDIA_ROOT = os.path.join(BASE_DIR,"static") #媒體文件路徑 STATIC_ROOT = os.path.join(BASE_DIR,"static/ckeditor") #配置收集靜態(tài)文件路徑 CKEDITOR_UPLOAD_PATH = 'uploads/' #指定媒體上傳目錄的相對(duì)路徑 CKEDITOR_IMAGE_GACKEND = 'pillow' #使用pillow模板啟用縮略圖功能 #具體的ckedito配置文檔:https://pypi.org/project/django-ckeditor/
(3)配置admin.py后臺(tái)
# vim app01/admin.py from django.contrib import admin from .models import blog_articles#導(dǎo)入數(shù)據(jù) admin.site.register(blog_articles) #加載到后臺(tái)
(4)配置url.py路由
# vim mysite/urls.py
from django.contrib import admin
from django.urls import path,re_path,include
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
re_path('^$',views.index,name='index'),
path(r'ckeditor/',include('ckeditor_uploader.urls')) #添加ckeditor路由
]
(5)收集靜態(tài)文件,生成數(shù)據(jù)并遷移
# python3 manage.py check
# python3 manage.py collectstatic
# python3 manage.py makemigrations
# python3 manage.py migrate
#執(zhí)行此處會(huì)有一個(gè)警告信息,需要配置mysql嚴(yán)格模式,在setting.py文件中的DATABASES中的數(shù)據(jù)引擎中添加以下配置:
'OPTIONS': {
'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
},
(5)創(chuàng)建后臺(tái)賬戶并驗(yàn)證后臺(tái)添加文章
# python3 manage.py creatsuperuser Unknown command: 'creatsuperuser'. Did you mean createsuperuser? Type 'manage.py help' for usage. [root@PJYC7 mysite]# python3 manage.py createsuperuser 用戶名 (leave blank to use 'root'): admin 電子郵件地址: admin@admin.com Password: Password (again): 密碼長(zhǎng)度太短。密碼必須包含至少 8 個(gè)字符。 Bypass password validation and create user anyway? [y/N]: y Superuser created successfully. #重啟uwsgi和nginx服務(wù) # systemctl restart uwsgi # systemctl restart nginx


(6)模板展示文章
修改views.py:
#vim app01/views.py
from django.shortcuts import render,get_object_or_404
from .models import blog_articles
def index(request): #主頁(yè)
blogs = blog_articles.objects.all()
return render(request,"app01/index.html",{"blogs":blogs})
def center(request,article_id):#詳情頁(yè)
article = get_object_or_404(blog_articles,id=article_id)
pub = article.publish
return render(request,"app01/content.html",{"article":article,"publish":pub})
建立模板文件:index.html,content.html
# vim templates/app01/index.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>{% block title %}個(gè)人博客{% endblock %}</title>
<meta name="keywords" content="個(gè)人博客" />
<meta name="description" content="個(gè)人博客模板" />
<link href="/static/ckeditor/css/base.css" rel="external nofollow" rel="stylesheet">
<link href="/static/ckeditor/css/index.css" rel="external nofollow" rel="stylesheet">
<script src="/static/ckeditor/js/scrollReveal.js"></script>
</head>
<body>
<div>
<ul class="cbp_tmtimeline">
{% for i in blogs %}
<li>
<time class="cbp_tmtime"><span>{{ i.publish.month }}-{{ i.publish.day }}</span><span>{{ i.publish.year }}</span></time>
<div class="cbp_tmicon"></div>
<div class="cbp_tmlabel" data-scroll-reveal="enter right over 1s" >
<h2>{{ i.title }}</h2>
<p><span class="blogpic"><a href="{{ i.id }}" rel="external nofollow" rel="external nofollow" ><img src="/static/{{ i.picture }}"></a></span>{{ i.description|safe }}</p>
<a href="{{ i.id }}" rel="external nofollow" rel="external nofollow" target="_blank" class="readmore">閱讀全文>></a>
</div>
</li>
{% endfor %}
</ul>
</div>
# vim templates/app01/content.html
<dev>
<h2>{{ article.title }}</h2>
<p><span class="blogpic"><img src="/static/{{ article.picture }}"></span></p>
<span>{{ article.body|safe }}</span>
</dev>
修改路由:urls.py
from django.contrib import admin
from django.urls import path,re_path,include
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
re_path('^$',views.index,name='index'),
path(r'ckeditor/',include('ckeditor_uploader.urls')),
re_path(r'(?P<article_id>\d)/$',views.center), #詳情頁(yè)獲取ID顯示頁(yè)面
]
#重啟uwsgi和nginx服務(wù)....
#查看顯示頁(yè):點(diǎn)擊詳情頁(yè)驗(yàn)證!!!
添加后臺(tái)過濾器:
#vim app01/admin.py
from django.contrib import admin
from .models import blog_articles
class BlogArticlesAdmin(admin.ModelAdmin):
list_display = ("title","author","publish")
list_filter = ("publish","author")
search_fields = ('title','body')
raw_id_fields = ("author",)
date_hierarchy = "publish"
admin.site.register(blog_articles,BlogArticlesAdmin)
(7)表單示例
通過template模版與MySQL實(shí)現(xiàn)簡(jiǎn)單表單交互
在app目錄下的models文件中創(chuàng)建model類用于生成數(shù)據(jù)表:
#cat app01/models.py from django.db import models # Create your models here. class userinfo(models.Model): name = models.CharField(max_length=32) password = models.CharField(max_length=32) age = models.IntegerField() salary = models.IntegerField()
設(shè)置setting.py文件,將app加入到INSTALLED_APPS中:
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01' ]
根據(jù)model類創(chuàng)建數(shù)據(jù)庫(kù)表:
#cmd進(jìn)入django項(xiàng)目路徑下 #python manage.py migrate #創(chuàng)建表結(jié)構(gòu),非model類的其他表,django所需要的 #python manage.py makemigrations app名 #做數(shù)據(jù)遷移的準(zhǔn)備 如:python manage.py makemigrations app01 app01是項(xiàng)目中的app名字 #python manage.py migrate # 執(zhí)行遷移,創(chuàng)建medel表結(jié)構(gòu)
在templages下建立模版文件:
#cat templates/app01/home.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test</title>
<style>
body{
background-image: url('/static/78556.jpg');
}
</style>
</head>
<body>
<form action="" method="post">#提交數(shù)據(jù)給自身
<p><input type="text" name="username"/></p>
<p><input type="text" name="password"/></p>
<p><input type="text" name="age"/></p>
<p><input type="text" name="salary"/></p>
<p><input type="submit" value="提交"/></p>
</form>
<table border="1">
<thead>
<tr>
<th>用戶名</th>
<th>密碼</th>
<th>年齡</th>
<th>工資</th>
</tr>
</thead>
<tbody>
{% for item in data %} #循環(huán)獲取傳入字典數(shù)據(jù)
<tr>
<td>{{item.name}}</td>
<td>{{item.password}}</td>
<td>{{item.age}}</td>
<td>{{item.salary}}</td>
</tr>
{% endfor %}
</tbody>
</table>
<h1>this is test file</h1>
<script src="/static/jquery-3.3.1.js"></script>
</body>
</html>
在app下新建視圖函數(shù),與數(shù)據(jù)庫(kù)交互:
#cat app01/views.py
from django.shortcuts import render
from django.http import HttpResponse
from app01 import models#引入數(shù)據(jù)類模版
# Create your views here.
def home(request):#創(chuàng)建home函數(shù)處理請(qǐng)求
if request.method == "POST":#判斷是否為post提交
#print(request.POST)
models.userinfo.objects.create( #提交表單的數(shù)據(jù)到數(shù)據(jù)庫(kù)
name = request.POST['username'],
password = request.POST['password'],
age = request.POST['age'],
salary = request.POST['salary'],
)
data = models.userinfo.objects.all()#獲取數(shù)據(jù)庫(kù)數(shù)據(jù)
return render(request,'app01/home.html',{'data':data}) #渲染模版文件并傳遞數(shù)據(jù)庫(kù)表給模版
#此處是以post方式提交,需要修改Django項(xiàng)目setting設(shè)置中的MIDDLEWARE,將csrf安全機(jī)制注銷了:
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', #'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ]
#建立路由:
#cat mysite/urls.py
from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('home/',views.home),
]
重新啟動(dòng)uWSGI:
#uwsgi --stop uwsgi.pid #uwsgi --ini uwsgi.ini
#瀏覽器訪問:http://192.168.146.139/home
#提交數(shù)據(jù)到數(shù)據(jù)庫(kù)后并返回給瀏覽器客戶端

虛擬環(huán)境搭建實(shí)例:
echo 'PS1="[\[\e[32;40m\]\u\[\e[0m\]@\[\e[32;40m\]\h\[\e[0m\]@\[\e[33;40m\]\A\[\e[0m\]\[\e[36;40m\]\W\[\e[0m\]\[\e[35;40m\]<\#>\[\e[0m\]]\\$"' ~/.bashrc
. ~/.bashrc
#配置epel源:
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
yum clean all
yum makecache
#按照依賴包
yum install libffi-devel openssl openssl-devel zlib-devel bzip2-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel python-devel
#安裝Python3.7
wget https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tar.xz
tar xvf Python-3.7.0.tar.xz
mkdir -p /usr/local/python37
cd Python-3.7.0
./configure --prefix=/usr/local/python37/
make && make install
ln -s /usr/local/python37/bin/python3 /usr/local/bin/python3
ln -s /usr/local/python37/bin/pip3 /usr/local/bin/pip3
pip3 install --upgrade pip
#配置國(guó)內(nèi)python源
mkdir -p ~/.pip
cat > ~/.pip/pip.conf << EFO
[global]
timeout=60
index-url=https://pypi.tuna.tsinghua.edu.cn/simple
[install]
trusted-host=https://pypi.tuna.tsinghua.edu.cn
EFO
#創(chuàng)建虛擬環(huán)境
python3 -m venv /mysite
cd mysite/
git clone git://github.com/kennethreitz/autoenv.git
echo 'source /mysite/autoenv/activate.sh' >> ~/.bashrc
source ~/.bashrc
echo "source /mysite/bin/activate" >/mysite/.env
#在虛擬環(huán)境中安裝Django
pip install django
django-admin.py startproject myblog
cd myblog/
#測(cè)試Django
vim /mysite/myblog/myblog/settings.py
ALLOWED_HOSTS = ["*"]
python manage.py runserver 0.0.0.0:8000
#在虛擬環(huán)境中安裝Uwsgi
pip install uwsgi
#測(cè)試uwsgi
#創(chuàng)建測(cè)試文件
cat test.py
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return [b"Hello World"]
uwsgi --http :9000 --wsgi-file test.py
#使用uwsgi測(cè)試django
uwsgi --http :9000 --module myblog.wsgi
#安裝nginx
yum install nginx
systemctl enable nginx
systemctl start nginx
#nginx配置django和uwsgi反向代理:
location /static {
alias /mysite/myblog;
}
location / {
uwsgi_pass 127.0.0.1:9000;
include /etc/nginx/uwsgi_params;
uwsgi_param UWSGI_DIR /mysite/myblog;
uwsgi_param UWSGI_MODULE myblog.wsgi;
uwsgi_param UWSGI_ENV /mysite;
}
#contOS7創(chuàng)建系統(tǒng)服務(wù)
cat /etc/systemd/system/uwsgi.service
[Unit]
Description=uWSGI Emperor
After=syslog.target
[Service]
ExecStart=/root/uwsgi/uwsgi --ini /etc/uwsgi/emperor.ini
# Requires systemd version 211 or newer
RuntimeDirectory=uwsgi
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all
[Install]
WantedBy=multi-user.target
#uwsgi配置文件:
[uwsgi]
socket = 127.0.0.1:9000
chdir = /root/mysite/myblog
module = myblog.wsgi
master = true
processes = 2
threads = 2
max-requests = 2000
vacuum = true
#home = /root/mysite
daemonize = /var/log/uwsgi/uwsgi.log
stats = 127.0.0.1:9001
post-buffering = 65535
buffer-size = 65535
harakiri-verbose = true
harakiri = 300
pidfile = /run/uwsgi.pid
venv = /root/mysite/.venv
#常用選項(xiàng):
--http在指定的地址上添加http端口
--http-socket 使用HTTP協(xié)議綁定到指定的UNIX/TCP套接字上
--wsgi-file 加載WSGI文件
--processes 指定進(jìn)程數(shù)
--threads 指定每個(gè)進(jìn)程的線程數(shù)
-M --master 啟用主進(jìn)程
--stats 指定狀態(tài)查詢綁定地址端口,如:127.0.0.1:9001
-s --socket 使用默認(rèn)協(xié)議綁定到指定的UNIX/TCP套接字
--chdir:指定工程的絕對(duì)路徑,如Django的項(xiàng)目路徑
--module:指定web應(yīng)用的API,如Django項(xiàng)目下的wsgi.py接口文件
--max-requests:最大請(qǐng)求數(shù)
--daemonize:指定uWSGI日志文件路徑
--post-buffering:設(shè)置緩沖區(qū)
--buffer-size:設(shè)置緩沖區(qū)文件大小
--harakiri-verbose:設(shè)置超時(shí)true為開啟
--harakiri:設(shè)置超時(shí)時(shí)間
--uid、--gid:設(shè)置用戶和組
--pidfile:指定啟動(dòng)時(shí)的pid文件路徑
--venv 指定python虛擬環(huán)境
到此這篇關(guān)于django生產(chǎn)環(huán)境搭建(uWSGI+django+nginx+python+MySQL)的文章就介紹到這了,更多相關(guān)django生產(chǎn)環(huán)境搭建內(nèi)容請(qǐng)搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!
版權(quán)聲明:本站文章來源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請(qǐng)保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非maisonbaluchon.cn所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場(chǎng),如有內(nèi)容涉嫌侵權(quán),請(qǐng)聯(lián)系alex-e#qq.com處理。
關(guān)注官方微信