【python】使用Django搭建web服务器并部署

前言

【玛卡巴卡】需要搭建一个用于响应requests请求的web服务器用于挣钱,现在尝试用Django一步一步实现,并部署。此篇文档不涉及浏览器实际访问web页面的任何东西,只是响应后台请求。

1、创建虚拟环境

如果你不在意自己的虚拟机(服务器)上只有一个django环境,请跳过这一步。

sudo apt install python3-venv #安装venv

mkdir django_server #新建一个目录

cd django_server #进入新建的目录

python3 -m venv venv #创建新的虚拟环境,在名为venv的目录

大致内容如下:

xx@xx:~/xxx/django_server/venv$ ls -l
total 20
drwxrwxr-x 3 xx xx 4096 Nov 25 14:50 bin
drwxrwxr-x 2 xx xx 4096 Nov 25 14:48 include
drwxrwxr-x 3 xx xx 4096 Nov 25 14:48 lib
lrwxrwxrwx 1 xx xx     3 Nov 25 14:48 lib64 -> lib
-rw-rw-r-- 1 xx xx 69 Nov 25 14:48 pyvenv.cfg
drwxrwxr-x 3 xx xx 4096 Nov 25 14:48 share
xx@xx:~/xxx/django_server/venv$

source venv/bin/activate #开始使用此虚拟环境,通过运行activate脚本来激活

deactivate #停用虚拟环境,返回正常shell

原创链接:https://www.cnblogs.com/gaoshaonian/p/15604008.html

2、安装django及其项目创建

(venv) xxx:~/xx/django_server$ pip3 install django #注意这里是安装到虚拟环境里

python -m django --version # 查看版本

django-admin startproject djangoMailServer #创建项目

目录结构如下:

djangoMailServer/
├── db.sqlite3
├── djangoMailServer
│   ├── asgi.py
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-36.pyc
│   │   ├── settings.cpython-36.pyc
│   │   ├── urls.cpython-36.pyc
│   │   └── wsgi.cpython-36.pyc
│   ├── settings.py  #object的设置
│   ├── urls.py  #地址
│   └── wsgi.py #部署时会用到
└── manage.py

2 directories, 11 files

python3 manage.py startapp mail # 创建应用

目录结构如下:

mail/
├── admin.py #后台相关的设置
├── apps.py  #app相关的设置文件
├── __init__.py
├── migrations  #数据库变更相关
│   └── __init__.py
├── models.py  #数据库模型相关
├── tests.py  #写测试代码的地方
└── views.py  #业务逻辑实现的地方

1 directory, 7 files

此时基本的框架就已经搭建完成,非常简单,接下来就要进行个性化,用于实现自己的功能

3、服务启动测试

object增加app

打开 settings.py

# Application definition
 
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
 
    'mail',   # 注意添加了这一行,用于obj找app资源
]

...

ALLOWED_HOSTS = ['*']  #记得修改这个选项,此处代表任何地址,默认只能本机访问,可以根据自己的需要进行修改

定义网址

根据网址的不同,可以访问不同的内容

打开obj中的urls.py

"""MailBaitObj URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/3.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from mailbaitapp import views

urlpatterns = [
    path('admin/', admin.site.urls), #自带的管理页面
    path('mail/', views.recv_mailmsg), #我自己新加的地址,即 http://xxxx:xx/mail/
                                       #views 代表views.py recv_mailmsg代表定义的函数
]

响应请求

打开views.py

from django.http import HttpResponse
 
def recv_mailmsg(request):
    return HttpResponse("hello world!")

启动服务

python3 manage.py runserver 0.0.0.0:8000
上面的 0.0.0.0:8000 代表监听所有ip:8000端口,访问地址就是 http://服务器IP:8000/mail/,不加这个的话,只能本机访问 http://127.0.0.1:8000/mail/ ,这些其实都不太重要,后面部署的时候,会有专门的服务管理

此时访问地址的话,已经可以看到hello world.

参考链接

4、实现C/S实际功能

服务端

服务端就是recv_mailmsg 这个函数了,只列出几个关键参数,其他的可以根据业务来搞。

def recv_mailmsg(request):
  if request.method == 'POST': # 响应post请求
    info = request.POST.get('info') #获取参数
    filename = request.FILES.get('files', None) #获取文件

  JsonResponse({'msg':'hehe', ...}) #此处是响应json数据,和上面提到的HttpResponse相比,更丰富一些

客户端

客户端就是一个request请求

import requests

def send_mailmsg():
  info = {      #拼接json数据
      'msg':'hehe',
      ...
  }

  payload = {'info': json.dumps(info)} # !!! 注意,如果是post参数中混合了json和文件,必须把json转成string,然后由`data=`发送,否则服务端取不到json

  f = open(filename, 'rb')

  response = requests.post(cloud_bait_url, headers = {}, timeout=30, verify=False, data = payload, files= {'files': f})

想要发送一些编码为表单形式的数据(HTML表单),只需简单地传递一个 dict 给 data 参数。你的数据字典在发出请求时会自动编码为表单形式;想要发送的数据并非编码为表单形式的。传递一个 string 而不是一个dict ,数据会被直接按照流发送出去。

requests快速上手
requests高级用法
Response 对象

TODO:总结下 headers 中的参数

5、部署

这一步还挺麻烦的,但是只需要理解一次就行

由于不涉及实际的浏览器访问页面,所以暂时不考虑http问题,只需考虑django服务问题。此处使用 uwsgisupervisord 这两个来部署,下面详细介绍下。

uwsgi

安装

sudo pip install uwsgi

配置

既然我们要用uwsgi来管理django服务,那么首先创建对应的配置文件,例如我这里在要被管理的obj目录下,创建了ini配置文件

touch djangoMailServer.ini

具体内容如下:

# the obj port
http = :8000

# virtual path
home=/home/xxx/venv

# the base directory (full path),obj根目录
chdir           = /home/xxx/

# Django s wsgi file, 这个是创建obj时自动生成发的
module          = djangoMailServer.wsgi

# 并发处理进程数
listen = 64

# 后台运行,并输出日志,自己定
daemonize = /home/xxx/uwsgi.log

...

# 还有一些其他的

可以参开这个博客:
uwsgi常用参数介绍

然后用uwsgi启动django项目:

uwsgi --ini djangoMailServer.ini

当然了,可以直接通过命令行测试uwsgi能否正常启动django服务

uwsgi --http :8000 --chdir /home/xxx/djangoMailServer/ --home=/home/xxx/venv --module djangoMailServer.wsgi

可以看到,上面 --home 指定了虚拟环境

一般情况就能正常启动了,如果报错,根据报错信息进行修改,再附上一些有价值的参考链接:

如何用 uWSGI 托管 Django
django 部署

supervisord

安装

pip3 install supervisor

配置

生成配置文件:

echo_supervisord_conf > /etc/supervisord.conf

创建 /etc/supervisord.d 目录,并在配置文件supervisord.conf里加上

[include]
files = supervisord.d/*.ini

当然了,你可以直接把所有要被supervisord 管理的内容全部写进supervisord.conf里,那样比较乱就是了。

在supervisord.d/ 目录下创建uwsgi配置文件:

[program:uwsgi]
directory=/home/xxx/djangoMailServer/
command=/usr/local/bin/uwsgi --ini djangoMailServer.ini
autostart=true
autorestart=true
startretries=10
redirect_stderr=true
stdout_logfile=/home/xxx/supervisord_uwsgi.log

supervisor配置文件

最后启动:

supervisorctl -c /etc/supervisord.conf

大功告成

附上一些报错问题:
Supervisorctl error: unix:///var/run/supervisord.sock refused connection? [closed]

原文地址:https://www.cnblogs.com/gaoshaonian/p/15604008.html