解决问题:
1、开发时会使用django环境进行一些初始化操作,这些程序一般只执行几次,但是需要django中的环境变量。
2、使用django运行阻塞监听的程序,比如Rabbitmq监听,放在主程序中就阻塞住了,需要另外开命令执行
一、使用 django环境运行单独命令
在创建的app下创建文件夹management,在management文件夹下创建文件夹commands,将要执行的文件放到文件将爱下,记得把__init__.py文件一并创建了,init.py是声明这个文件夹是一个包。然后在主目录(就是manage.py文件所在目录)执行 python manage.py 文件名即可
比如,在我这个项目中,目录结构
.
├── aiprogram
│ ├── celery.py
│ ├── gunicorn_config.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── apps
│ ├── docsManage
│ │ ├── admin.py
│ │ ├── apps.py
│ │ ├── __init__.py
│ │ ├── migrations
│ │ ├── models.py
│ │ ├── task.py
│ │ ├── tests.py
│ │ └── views.py
│ ├── __init__.py
│ ├── intelligentAduit
│ │ ├── admin.py
│ │ ├── apps.py
│ │ ├── __init__.py
│ │ ├── management # 这个就是创建的 management 文件夹
│ │ │ ├── commands # commands文件夹
│ │ │ │ ├── init_mq.py # python manage.py init_mq 执行这个文件的内容
│ │ │ │ ├── __init__.py
│ │ │ │ ├── intelligentAduit_listener.py # python manage.py intelligentAduit_listener 执行这个文件的内容
│ │ ├── migrations
│ │ ├── models.py
│ │ ├── __pycache__
│ │ ├── serializers.py
│ │ ├── task.py
│ │ ├── tests.py
│ │ └── views.py
........
然后看看 init_mq.py 文件的内容
from django.core.management.base import BaseCommand
class Command(BaseCommand):
def handle(self, *args, **options):
from untils.Rabbitmqserver import RabbitmqClient
from untils.logs import Logger
logger = Logger("init_mq")
logger.infolog("init_mq", "开始初始化Rabbitmq队列")
try:
RabbitmqClient.connent()
RabbitmqClient.channel.queue_declare(queue='send_result', durable=True)
RabbitmqClient.channel.queue_declare(queue='backend', durable=True)
RabbitmqClient.channel.queue_declare(queue='intelligent', durable=True)
RabbitmqClient.channel.queue_declare(queue='resume', durable=True)
logger.infolog("init_mq", "初始化Rabbitmq队列成功")
except Exception as e:
logger.errlog("init_mq",e,"队列初始化失败")
要执行的命令就是 def handle(self, *args, **options): 方法下的内容,我这里用这个命令进行Rabbitmq管道初始化声明,也可以做其他事情,比如初始化数据库的数据,向数据库插入内容等
在命令行中执行 python manage.py init_mq
(venv) D:\AI-zhiwenben\backend\aiprogram>python manage.py init_mq
[init_mq][init_mq]Info,时间:2019-02-22 21:06:12,开始初始化Rabbitmq队列
[init_mq][init_mq]Info,时间:2019-02-22 21:06:13,初始化Rabbitmq队列成功
二、在django项目中使用 Rabbitmq消息队列
在python中使用rabbitmq,需要
pip install pika
为了使用方便,首先先写了一个rabbitmq类
import pika
import sys
import time
if __name__ != '__main__': # 测试服务是否能启动时使用
from django.conf import settings
class RabbitmqServer(object):
def __init__(self,username,password,serverip,port):
self.username =username
self.password = password
self.serverip = serverip
self.port = port
def connent(self):
user_pwd = pika.PlainCredentials(self.username, self.password)
s_conn = pika.BlockingConnection(pika.ConnectionParameters(host= self.serverip,port=self.port, credentials=user_pwd)) # 创建连接
self.channel = s_conn.channel()
def productMessage(self,queuename,message):
self.channel.queue_declare(queue=queuename, durable=True)
self.channel.basic_publish(exchange='',
routing_key=queuename,#写明将消息发送给队列queuename
body=message, #要发送的消息
properties=pika.BasicProperties(delivery_mode=2,)#设置消息持久化,将要发送的消息的属性标记为2,表示该消息要持久化
)
def expense(self,queuename,func):
"""
:param queuename: 消息队列名称
:param func: 要回调的方法名
"""
self.channel.basic_qos(prefetch_count=1)
self.channel.basic_consume(func,
queue=queuename,
)
self.channel.start_consuming()
def callback(ch, method, properties, body):
print(" [消费者] Received %r" % body)
time.sleep(1)
print(" [消费者] Done")
ch.basic_ack(delivery_tag=method.delivery_tag)# 接收到消息后会给rabbitmq发送一个确认
if __name__ != '__main__':
username = settings.RABBITMQCONFIG.get("username")
password = settings.RABBITMQCONFIG.get("password")
severip = settings.RABBITMQCONFIG.get("severip")
port = settings.RABBITMQCONFIG.get("port")
RabbitmqClient = RabbitmqServer(username,password,severip,port)
if __name__ == '__main__':
import json
RabbitmqClient = RabbitmqServer("username", "password", "host",port)
RabbitmqClient.connent()
data = {"code":3}
RabbitmqClient.productMessage("test3",json.dumps(data))
RabbitmqClient.expense("test3",callback)
这个类单独放到一个文件下,起名Rabbitmqserver.py,运行:
[消费者] Received b'{"code": 3}'
[消费者] Done
其他地方使用时,可以将RabbitmqClient 这个实例引用过去,比如:
def sendtoparse_one(file_name, file_id, file_url, rule_list, userid):
data = json.dumps(
{"file_name": file_name, "file_id": file_id, "file_url": file_url, "rule_list": rule_list, "userid": userid,
"request_type": "sample"})
# rabbitmq
logger.infolog("AduitOneParseView", "开始发送消息到算法端:data:{}".format(str(data)))
RabbitmqClient.connent()
RabbitmqClient.productMessage("intelligent", data)
# 发送消息通知算法端解析
logger.infolog("AduitOneParseView", "文件发送完成")
执行到这个方法时,就会将消息发送到“intelligent”队列中去
三、django中使用Rabbitmq监听端进行阻塞监听
这个就用到前两条,需要使用django命令启动Rabbitmq监听程序,比如
from django.core.management.base import BaseCommand
class Command(BaseCommand):
def handle(self, *args, **options):
from untils.Rabbitmqserver import RabbitmqClient
from django.conf import settings
import json
from untils.logs import Logger
from intelligentAduit.models import OneUploadResultTable, BatchUploadResultTable
from django_redis import get_redis_connection
from django.db import connection
from django.db.utils import OperationalError
# 监听算法端返回的消息,将结果存入数据库并更改数据库中文件状态
def parse_result_func(ch, method, properties, body):
### 逻辑程序
ch.basic_ack(delivery_tag=method.delivery_tag) # 接收到消息后会给rabbitmq发送一个确认
logger.infolog("parse_result_func", "开始监听审计结果")
RabbitmqClient.connent()
RabbitmqClient.expense("intelligent", parse_result_func)
然后,在项目主目录下执行 python manage.py intelligentAduit_listener 就会看到,说明执行成功
"开始监听审计结果"