django生产环境搭建(uWSGI+django+nginx+python+MySQL)

目录
  • 1、系统环境,必要知识
  • 2、安装python3.6.5
  • 3、安装Django
  • 4、安装uWSGI
  • 5、安装nginx
  • 6、MySQL安装配置
  • 7、编写一个简单的博客系统

1、系统环境,必要知识

#cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core)
#uname -r
3.10.0-862.3.2.el7.x86_64

暂时关闭防护墙,关闭selinux:

#systemctl stop firewalld.service
#setenforce 0
#getenforce
Permissive

准备知识:

django:一个基于python的开源web框架。

uWSGI:一个基于自有的uwsgi协议,wsgi协议和http服务协议的web网关

nginx:高性能的代理web服务器

wsgi.py:django项目自带的wsgi接口文件(位于:项目/项目名/wsgi.py)

整个项目流程:

首先客户端通过浏览器访问服务器资源;nginx作为对外服务的端口(80),nginx接收到客户端http请求后会解包分析,如果是静态文件就去配置的静态文件中查找资源并返回给客户端,如果是动态资源,nginx就通过配置文件将请求传递给uwsgi处理,并转发给uwsgi,wsgi根据请求调用django工程的文件和函数,处理后django将返回值交给wsgi,wsgi将返回值进行打包,转发给uWSGI,uWSGI接收到数据后转发给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方便调试

测试安装是否正常:

#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

创建项目:

#django-admin startproject mysite

创建app:

#cd mysite/
#django-admin startapp app01

在项目路径下创建模板文件目录(templates)和静态文件目录(static),后面会用到

# cd mysite/
# mkdir templates static

配置setting.py文件,配置允许访问主机名、将APP加入到项目、添加模板搜索路径

# vim mysite/settings.py

ALLOWED_HOSTS = ["*"]  #允许本机所有地址访问

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文件中创建视图函数

# vim app01/views.py
from django.shortcuts import render

def index(request):
    return render(request,"app01/index.html")

在templates目录中新建测试模板文件

# 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'),  #添加的路由
]

检查配置是否有错误:

# python3 manage.py check
System check identified no issues (0 silenced).

运行测试服务器,测试服务是否正常

# python3 manage.py runserver 0:8000
#在浏览器中测试是否正常显示网页内容
#注意防火墙和selinux是否关闭或允许相关端口访问
#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

先在项目目录下建立一个测试文件:

# vim foobar.py
def application(env,start_response):
    start_response('200 ok',[('Content-Type','text/html')])
    return [b"Hello World"]

然后采用测试脚本方式启动服务:

# uwsgi --http :9000 --wsgi-file foobar.py
#通过浏览器访问http://ip:9000能看到hello world说明成功
#然后停止服务

接下来配置uwsgi部署django服务:

#运行测试服务,--http指定服务端口,--chdir指定django项目目录,--wsgi-file指定项目中的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文件中的内容就算成功
#我的上面django模板中配置的内容是
test django server

建立uWSGI的配置文件,在django项目中建立uwsgi.ini文件,并配置好django项目,此处使用socket链接,后面通过nginx反向代理

#注意此处的配置指定用户nginx必须存在

[uwsgi]
socket = 127.0.0.1:9090
chdir = /djproject/mysite
module = mysite.wsgi    #这里填的是相对路径
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

参数说明:

socket:使用套接字链接

http:通过http加端口的方式

wsgi-file:指定加载的wsgi文件

chdir:指定工程的绝对路径,如Django的项目路径

module:指定web应用的入口模块,如Django项目下的wsgi.py接口文件

master:启动主进程

processes:启动进程数

threads:启动线程数

max-requests:最大请求数

daemonize:指定uWSGI日志文件路径

stats:指定状态查询端口,如:127.0.0.1:9001

wsgi-file:指定启动的文件

post-buffering:设置缓冲区

buffer-size:设置缓冲区文件大小

harakiri-verbose:设置超时true为开启

harakiri:设置超时时间

uid、gid:设置用户和组

pidfile:指定启动时的pid文件路径

vacuum = true #当服务器退出的时候自动删除unix socket文件和pid文件

uwsgi信号控制:

HUP     :优雅的重新加载所有进程和配置,同(--reload)一样

TERM  :强制重新加载主进程和配置

INT  :立即杀死整个uWSGI;同于:--stop

QUIT  :立即杀死真个uWSGI

重新启动实例:

#kill -HUP `cat /tmp/project-mast.pid`

#uwsgi --reload /tmp/project-master.pid

还可以在python程序中使用uwsgi.reload()重新加载

停止服务器:

#uwsgi --stop /tmp/project-master.pid

#kill -INT `cat /tmp/project-master.pid`

编写启动脚本:

#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系统服务脚本:

#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启动脚本后需要加载下:

systemctl daemon-reload

测试服务:

#uwsgi --ini /djproject/mysite/uwsgi.ini    #启动服务

#ps -ef|grep "uwsgi"   #查看进程
root     103596      1  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        0      0 127.0.0.1:9090          0.0.0.0:*               LISTEN      103596/uwsgi
tcp        0      0 127.0.0.1:9001          0.0.0.0:*               LISTEN      103596/uwsgi

看上面进程是少了一个主进程,通过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的日志,如没报错,就接着下一步,部署nginx

5、安装nginx

这里采用yum安装nginx:

yum -y install nginx

配置nginx反向代理uwsgi服务:

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;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    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的静态文件
        }

    location / {
        include     /etc/nginx/uwsgi_params;  #加载uwsgi模块
        uwsgi_pass  127.0.0.1:9090;   #所有请求转到9090端口交给uwsgi处理
        }
    }
}

此处记录下配置uwsgi和nginx套接字通信的坑:

第一个,nginx日志报错:

connect() to unix:///tmp/uwsgi.sock failed (2: No such file or directory) while connecting to upstream ......

可以明明uwsgi配置sock套接字通信在/tmp目录下明明有uwsgi.sock文件,而且/tmp目录是777权限,为什么nginx找不到套接字文件,经过google,百度查资料终于在stackoverflow上找到答案:是因为centOS7系统中/tmp临时目录,使用了命名空间的临时目录,对于每个服务只能访问自己创建的临时文件,所以我们不应该将sock文件放入/tmp目录,而因该放入/run目录下

第二个,uwsgi日志报错:

bind(): Permission denied [core/socket.c line 230]

经过第一个错误折腾,终于可以了,但放入/run目录后,uwsgi启动不了了,权限不够,这个问题解决简单,只需给/run目录,有uwsgi服务用户也就是uid指定的用户有写入权限即可,或者直接给/run目录777的权限但这样不安全。

#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安装配置

#下载二进制包安装
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
#添加配置文件和启动脚本
cp support-files/my-small.cnf /etc/my.cnf
cp support-files/mysql.server /etc/init.d/mysqld
#初始化数据库
./scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql --datadir=/mysql/data/
echo $?

#修改启动脚本路径
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
#启动和关闭MySQL
/etc/init.d/mysqld start
/etc/init.d/mysqld stop
#方法2:
/usr/local/mysql/bin/msyql_safe &    #后台启动
mysqladmin shutdown  #优雅关闭MySQL服务
#查看运行状态
#netstat -lntup|grep 3306
tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN      70099/mysqld        

#添加系统自启动
chkconfig --add mysqld
chkconfig --level 345 mysqld on
#添加环境变量
echo "PATH=/usr/local/mysql/bin:$PATH" >> /etc/profile
source /etc/profile

#修改初始化密码
mysqladmin -uroot password '123456'

#建立一个数据库,后面要用到
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 |
+----------------+
#建立个数据库后面要用到
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默认使用的是sqlite数据库:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

修改成MySQL数据库配置:

DATABASES = {
        'default':{
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django',
        'USER': 'root',
        'PASSWORD': '123.com',
        'HOST': '127.0.0.1',
        'PORT': '3306',
        }
}

ENGINE : 指定数据库驱动,不同的数据库这个字段不同,下面是常见的集中数据库的ENGINE的写法:

django.db.backends.postgresql  # PostgreSQL
django.db.backends.mysql       # mysql
django.db.backends.sqlite3     # sqlite
django.db.backends.oracle      # oracle

NAME: 指定的数据库名,如果是sqlite的话,就需要填数据库文件的绝对位置
USER: 数据库登录的用户名,mysql一般都是root
PASSWORD:登录数据库的密码,必须是USER用户所对应的密码
HOST: 由于一般的数据库都是C/S结构的,所以得指定数据库服务器的位置,我们一般数据库服务器和客户端都是在一台主机上面,所以一般默认都填127.0.0.1
PORT:数据库服务器端口,mysql默认为3306
HOST和PORT都可以不填,使用默认的配置,但是如果你有更改默认配置的话,就需要填入更改后的
配置完这,下面就需要装python连接mysql数据库的驱动程序,首先,需要安装mysql的开发包

#yum install mysql-devel   #安装MySQL插件
#pip3 install mysqlclient    #安装MySQL驱动
#测试django配置
# python3 manage.py check

环境搭建到此就完成了,下面开始开发项目

7、编写一个简单的博客系统

(1)数据建模,规划博客内容字段

#首先装两个包django-ckeditor、pillow分别用来添加富文本和缩略图用

# pip3 install django-ckeditor pillow

#vim app01/models.py

from django.db import models
from django.utils import timezone  #导入时间模板
from django.contrib.auth.models import User  #导入用户
from ckeditor_uploader.fields import RichTextUploadingField  #导入富文本模板

class blog_articles(models.Model):
    title = models.CharField(max_length=300,verbose_name="文章标题")
    author = models.ForeignKey(User,on_delete=models.CASCADE,related_name="blog_posts",verbose_name="文章作者")
    body = RichTextUploadingField(verbose_name="文章内容")
    description = RichTextUploadingField(verbose_name="文章描述")
    publish = models.DateTimeField(default=timezone.now,verbose_name="发表时间")
    picture = models.ImageField(upload_to="images")  #图片
    class Meta:
        ordering = ("-publish",)   #按时间倒序排列

    def __str__(self):
        return self.title   #显示文章标题

(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',   #加入模块到项目
    'ckeditor_uploader',  #加入模板
]

LANGUAGE_CODE = 'zh-hans'   #配置中文

TIME_ZONE = 'Asia/Shanghai'  #配置时区

USE_I18N = True

USE_L10N = True

USE_TZ = False #关闭UTC时间

STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR,"static"),]  #配置静态文件路径

MEDIA_URL = '/media/'  #媒体文件路由
MEDIA_ROOT = os.path.join(BASE_DIR,"static")  #媒体文件路径

STATIC_ROOT = os.path.join(BASE_DIR,"static/ckeditor") #配置收集静态文件路径

CKEDITOR_UPLOAD_PATH = 'uploads/'  #指定媒体上传目录的相对路径
CKEDITOR_IMAGE_GACKEND = 'pillow'  #使用pillow模板启用缩略图功能

#具体的ckedito配置文档:https://pypi.org/project/django-ckeditor/

(3)配置admin.py后台

# vim app01/admin.py

from django.contrib import admin
from .models import blog_articles   #导入数据

admin.site.register(blog_articles)  #加载到后台

(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)收集静态文件,生成数据并迁移

# python3 manage.py check
# python3 manage.py collectstatic
# python3 manage.py makemigrations
# python3 manage.py migrate
#执行此处会有一个警告信息,需要配置mysql严格模式,在setting.py文件中的DATABASES中的数据引擎中添加以下配置:
'OPTIONS': {
            'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
        },

(5)创建后台账户并验证后台添加文章

# 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):
密码长度太短。密码必须包含至少 8 个字符。
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.

#重启uwsgi和nginx服务
# 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):    #主页
    blogs = blog_articles.objects.all()
    return render(request,"app01/index.html",{"blogs":blogs})

def center(request,article_id):   #详情页
    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 %}个人博客{% endblock %}</title>
<meta name="keywords" content="个人博客" />
<meta name="description" content="个人博客模板" />
<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),  #详情页获取ID显示页面
]
#重启uwsgi和nginx服务....

#查看显示页:点击详情页验证!!!

添加后台过滤器:

#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实现简单表单交互

在app目录下的models文件中创建model类用于生成数据表:

#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()

设置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'
        ]

根据model类创建数据库表:

#cmd进入django项目路径下
#python manage.py migrate #创建表结构,非model类的其他表,django所需要的
#python manage.py makemigrations app名 #做数据迁移的准备
如:python manage.py makemigrations app01 app01是项目中的app名字
#python manage.py migrate # 执行迁移,创建medel表结构

在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">   #提交数据给自身
      <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 %} #循环获取传入字典数据
                <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下新建视图函数,与数据库交互:

#cat app01/views.py

from django.shortcuts import render
from django.http import HttpResponse
from app01 import models   #引入数据类模版
# Create your views here.

def home(request):   #创建home函数处理请求
  if request.method == "POST":   #判断是否为post提交
    #print(request.POST)
    models.userinfo.objects.create(     #提交表单的数据到数据库
    name = request.POST['username'],
    password = request.POST['password'],
    age = request.POST['age'],
    salary = request.POST['salary'],
)
  data = models.userinfo.objects.all()   #获取数据库数据
  return render(request,'app01/home.html',{'data':data}) #渲染模版文件并传递数据库表给模版

#此处是以post方式提交,需要修改Django项目setting设置中的MIDDLEWARE,将csrf安全机制注销了:

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),
]

重新启动uWSGI:

#uwsgi --stop uwsgi.pid
#uwsgi --ini uwsgi.ini

#浏览器访问:http://192.168.146.139/home

#提交数据到数据库后并返回给浏览器客户端

虚拟环境搭建实例:

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

#配置国内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

#创建虚拟环境
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

#在虚拟环境中安装Django
pip install django
django-admin.py startproject myblog
cd myblog/

#测试Django
vim /mysite/myblog/myblog/settings.py
ALLOWED_HOSTS = ["*"]

python manage.py runserver 0.0.0.0:8000

#在虚拟环境中安装Uwsgi
pip install uwsgi
#测试uwsgi
#创建测试文件
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测试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创建系统服务
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

#常用选项:
--http      在指定的地址上添加http端口
--http-socket  使用HTTP协议绑定到指定的UNIX/TCP套接字上
--wsgi-file    加载WSGI文件
--processes    指定进程数
--threads 指定每个进程的线程数
-M --master 启用主进程
--stats  指定状态查询绑定地址端口,如:127.0.0.1:9001
-s --socket  使用默认协议绑定到指定的UNIX/TCP套接字
--chdir:指定工程的绝对路径,如Django的项目路径
--module:指定web应用的API,如Django项目下的wsgi.py接口文件
--max-requests:最大请求数
--daemonize:指定uWSGI日志文件路径
--post-buffering:设置缓冲区
--buffer-size:设置缓冲区文件大小
--harakiri-verbose:设置超时true为开启
--harakiri:设置超时时间
--uid、--gid:设置用户和组
--pidfile:指定启动时的pid文件路径
--venv  指定python虚拟环境

到此这篇关于django生产环境搭建(uWSGI+django+nginx+python+MySQL)的文章就介绍到这了,更多相关django生产环境搭建内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 解决Django生产环境无法加载静态文件问题的解决

    起步 线上部署时因设置了 settings.DEBUG = False 会导致静态文件都是 404 的情况.主要原因是应为关闭DEBUG模式后,Django 便不提供静态文件服务了. runserver 的启动 如果运行是通过 runserver 命令的方式,那简单,在启动 runserver 指令后追加 --insecure 选项能参数强制 django 处理静态文件. 其他方式启动 但如果是通过 uwsgi 或 daphne 等启动的话,追加选项的方式就不管用了.要解决这个问题,我们要手动去

  • Django + Uwsgi + Nginx 实现生产环境部署的方法

    如何在生产上部署Django? Django的部署可以有很多方式,采用nginx+uwsgi的方式是其中比较常见的一种方式. uwsgi介绍 uWSGI是一个Web服务器,它实现了WSGI协议.uwsgi.http等协议.Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换. 要注意 WSGI / uwsgi / uWSGI 这三个概念的区分. 1.WSGI是一种Web服务器网关接口.它是一个Web服务器(如nginx,uWSGI等服务器)与web应用(如用Flask框架

  • 详解Django+Uwsgi+Nginx的生产环境部署

    使用runserver可以使我们的django项目很便捷的在本地运行起来,但这只能在局域网内访问,如果在生产环境部署django,就要多考虑一些问题了.比如静态文件处理,安全,效率等等,本篇文章总结归纳了一下基于uwsgi+Nginx下django项目生产环境的部署 准备条件: 1.确保有一个能够用runserver正常启动的django项目 2.项目已上传到linux 3.linux上已部署好python环境,且已安装好项目所需的模块 安装uwsgi uwsgi是python的一个模块,安装u

  • Django 开发环境与生产环境的区分详解

    Django 开发环境与生产环境的设置 在常规的Django工程开发中,我们经常会遇到一类问题,即:本地开发环境跟远程服务器生产环境配置不一样.对于这些不同之处,以前的做法是直接修改生产环境中的配置.但是对于立志自动化体系的开发者来说,显然这是极其愚蠢的. 那么常规的做法是什么呢?既然是不同的环境,两份不同的配置文件是必须的. 准备配置文件 在新建的Django项目中与settings.py同级目录下,准备两份不同的settings: |____EveryDay | |____prd_setti

  • Django+Uwsgi+Nginx如何实现生产环境部署

    如何在生产上部署Django? Django的部署可以有很多方式,采用nginx+uwsgi的方式是其中比较常见的一种方式. uwsgi介绍 uWSGI是一个Web服务器,它实现了WSGI协议.uwsgi.http等协议.Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换. 要注意 WSGI / uwsgi / uWSGI 这三个概念的区分. WSGI是一种Web服务器网关接口.它是一个Web服务器(如nginx,uWSGI等服务器)与web应用(如用Flask框架写的

  • Django uwsgi Nginx 的生产环境部署详解

    配置生产环境 #setting.py 文件中 DEBUG = False # 生产环境 # 允许访问的域名,域名前加一个点表示允许访问该域名下的子域名,比如 www.zmrenwu.com. # test.zmrenwu.com 等二级域名同样允许访问.如果不加前面的点则只允许访问 zmrenwu.com ALLOWED_HOSTS = ["127.0.0.1",".blogzjl.site"] 创建Python虚拟环境 安装 virtualenv sudo pip

  • 详解Django+Uwsgi+Nginx 实现生产环境部署

    uwsgi介绍 uWSGI是一个Web服务器,它实现了WSGI协议.uwsgi.http等协议.Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换. 要注意 WSGI / uwsgi / uWSGI 这三个概念的区分. WSGI是一种Web服务器网关接口.它是一个Web服务器(如nginx,uWSGI等服务器)与web应用(如用Flask框架写的程序)通信的一种规范. uwsgi是一种线路协议而不是通信协议,在此常用于在uWSGI服务器与其他网络服务器的数据通信. 而u

  • django生产环境搭建(uWSGI+django+nginx+python+MySQL)

    目录 1.系统环境,必要知识 2.安装python3.6.5 3.安装Django 4.安装uWSGI 5.安装nginx 6.MySQL安装配置 7.编写一个简单的博客系统 1.系统环境,必要知识 #cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core) #uname -r 3.10.0-862.3.2.el7.x86_64 暂时关闭防护墙,关闭selinux: #systemctl stop firewalld.service

  • django项目环境搭建及在虚拟机本地创建django项目的教程

    1.Python虚拟环境创建 首先我们为什么要创建虚拟环境呢?因为不同的项目所依赖的环境不一样,他们需要不同的第三方库等等.为了避免冲突,所以我们要创建虚拟环境,在次此我用的的Linux ubuntu和pycharm. 在虚拟机上创建Python虚拟环境命令为: mkvirtualenv -p /usr/bin/python3 虚拟环境名字 (-p参数选择虚拟环境要用的Python解释器) 2.创建django项目 第一步:进入到你要创建项目的目录 cd ~/project 第二步:安装djan

  • LINUX 生产环境搭建推荐教程

    由于linux生产环境搭建步骤非常多,很繁琐而且又是必不可少的步骤.虽然已经做过很多次,但是由于步骤繁琐,很容易忘记,下面小编抽个时间把linux生产环境搭建步骤记录下来,分享在我们平台,以便需要之时使用 登录远程MySQL mysql -h 192.168.1.100 -u root -p 给MySQl非root账户分配权限 给账号user1 密码为123456 的用户testDB数据库的所有表的select,insert,update,delete权限: grant select,inser

  • 在Linux系统上通过uWSGI配置Nginx+Python环境的教程

    1.安装ubuntu有uwsgi的ppa: add-apt-repository ppa:stevecrozz/ppa apt-get update apt-get install uwsgi 2. 用uwsgi代替mod_wsgi Nginx 的整体配置这里不说了,假设已经明白 Nginx的基本配置,那么uwsgi就类似这么配置: location / { include uwsgi_params uwsgi_pass 127.0.0.1:9090 } 再比如django就是: .......

  • 在Windows系统上搭建Nginx+Python+MySQL环境的教程

    1 安装nginx 下载windows上的nginx最新版本,http://www.nginx.org/en/download.html. 解压后即可. 运行nginx.exe后本地打开http://localhost,将会看到欢迎页面,这证明nginx在本地运行良好,如果没有出现欢迎页面,请检查是否有进程占用了80端口. 2 安装flup 下载对应版本的flup,这里下载flup3.x版本,适合python3.2,下载地址:https://github.com/chxanders/flup3

  • 记一次Docker生产环境搭建的方法

    服务器配置: 服务器使用的是阿里云ECS标准型,普通的centos7和docker环境镜像. 搭建docker镜像加速: docker镜像源在docker.io在国外速度很慢,所以配置下加速,daocloud加速地址 选择linux加速配置命令,复制粘贴执行,直接执行可能有个逗号错误,我是碰到了.解决方法是修改daemon.json文件: cd /etc/docker ls cat daemon.json vi daemon.json 把尾部的逗号去掉就行vi编辑器 i进编辑模式 去掉然后 es

  • 详解python使用Nginx和uWSGI来运行Python应用

    uWSGI是一个Web应用服务器,它具有应用服务器,代理,进程管理及应用监控等功能.它支持WSGI协议,同时它也支持自有的uWSGI协议,该协议据说性能非常高,而且内存占用率低,为mod_wsgi的一半左右,我没有实测过.它还支持多应用的管理及应用的性能监控.虽然uWSGI本身就可以直接用来当Web服务器,但一般建议将其作为应用服务器配合Nginx一起使用,这样可以更好的发挥Nginx在Web端的强大功能.本文我们就来介绍如何搭建uWSGI+Ngnix环境来运行Python应用. 安装uWSGI

  • Spark在Windows下的环境搭建方法

    本文主要是讲解Spark在Windows环境是如何搭建的 一.JDK的安装 1.1 下载JDK 首先需要安装JDK,并且将环境变量配置好,如果已经安装了的老司机可以忽略.JDK(全称是JavaTM Platform Standard Edition Development Kit)的安装,去Oracle官网下载,下载地址是Java SE Downloads. 上图中两个用红色标记的地方都是可以点击的,点击进去之后可以看到这个最新版本的一些更为详细的信息,如下图所示: 下载完之后,我们安装就可以直

  • Mybatis环境搭建和使用实例代码

    Mybatis的简介: MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis .2013年11月迁移到Github. MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 J

随机推荐