测试抓图识别任务

This commit is contained in:
曹前明 2022-09-12 14:59:24 +08:00
parent 124c7f3086
commit 55aff64b5f
3 changed files with 40 additions and 7 deletions

View File

@ -10,6 +10,7 @@ from apps.develop.serializers import CleanDataSerializer, GenerateVoiceSerialize
from apps.develop.tasks import backup_database, backup_media, reload_web_git, reload_server_git, reload_server_only from apps.develop.tasks import backup_database, backup_media, reload_web_git, reload_server_git, reload_server_only
from rest_framework.exceptions import APIException from rest_framework.exceptions import APIException
from apps.ecm.service import check_not_in_place, create_remind, notify_event, snap_and_analyse from apps.ecm.service import check_not_in_place, create_remind, notify_event, snap_and_analyse
from apps.ecm.tasks import opl_task
from apps.opm.models import Opl from apps.opm.models import Opl
from apps.system.tasks import show from apps.system.tasks import show
from apps.third.clients import dhClient from apps.third.clients import dhClient
@ -22,6 +23,7 @@ from apps.utils.wx import wxClient
from apps.wf.models import State, Transition, Workflow from apps.wf.models import State, Transition, Workflow
from django.db import transaction from django.db import transaction
from apps.utils.snowflake import idWorker from apps.utils.snowflake import idWorker
from django.core.cache import cache
# Create your views here. # Create your views here.
@ -191,11 +193,13 @@ class TestViewSet(CustomGenericViewSet):
from apps.ecm.service import dispatch_dahua_event from apps.ecm.service import dispatch_dahua_event
data = {'id': None, 'category': 'alarm', 'method': 'alarm.msg', 'info': {'orgName': '河北省', 'alarmPictureSize': '885977', 'nodeCode': '1002182$1$0$0', 'deviceCode': '1002182', 'alarmCode': '{B55A1489-0064-8D42-B6F4-EFF2DE1DA9B1}', 'alarmPicture': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220831/1/dsf_3c4ef3fe-290f-11ed-884a-e4246c7d1635_55425449_56311426.jpg', 'nodeType': 2, 'deviceName': '192.168.10.155', data = {'id': None, 'category': 'alarm', 'method': 'alarm.msg', 'info': {'orgName': '河北省', 'alarmPictureSize': '885977', 'nodeCode': '1002182$1$0$0', 'deviceCode': '1002182', 'alarmCode': '{B55A1489-0064-8D42-B6F4-EFF2DE1DA9B1}', 'alarmPicture': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220831/1/dsf_3c4ef3fe-290f-11ed-884a-e4246c7d1635_55425449_56311426.jpg', 'nodeType': 2, 'deviceName': '192.168.10.155',
'alarmDate': '1661942981', 'alarmGrade': 2, 'isSave': True, 'unitType': 1, 'unitSeq': 0, 'extend': {'params': {'ObjectType': 'Human', 'GroupId': 30.0, 'ObjectSubType': ''}, 'objectSubType': ''}, 'alarmType': 964, 'channelSeq': 0, 'orgCode': '001', 'channelName': '192.168.10.155_视频通道_1', 'alarmStat': 1, 'isEvent': True}, 'subsystem': 'admin', 'userIds': None, 'sid': None, 'domainId': None, 'infoArray': None, 'protocol': None} 'alarmDate': '1661942981', 'alarmGrade': 2, 'isSave': True, 'unitType': 1, 'unitSeq': 0, 'extend': {'params': {'ObjectType': 'Human', 'GroupId': 30.0, 'ObjectSubType': ''}, 'objectSubType': ''}, 'alarmType': 964, 'channelSeq': 0, 'orgCode': '001', 'channelName': '192.168.10.155_视频通道_1', 'alarmStat': 1, 'isEvent': True}, 'subsystem': 'admin', 'userIds': None, 'sid': None, 'domainId': None, 'infoArray': None, 'protocol': None}
data = {'id': 1662026969203, 'category': 'alarm', 'method': 'alarm.msg', 'info': {'orgName': '曲阳县金隅水泥厂', 'nodeCode': '1000038$1$0$24', 'deviceCode': '1000038', 'alarmCode': '44df73ba-a423-4479-af70-1f930b00a7e0', 'alarmPicture': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220901/1/dsf_80fed821-29c9-11ed-884a-e4246c7d1635_27257520_27264993.jpg', 'nodeType': 2, 'alarmDate': '1662026965', 'alarmGrade': 2, 'isSave': True, 'extend': {'faceImageUrl': ['6ad010cf-ce45-11ec-9715-e4246c7d1635/20220901/1/dsf_80fed821-29c9-11ed-884a-e4246c7d1635_27257520_27264993.jpg'], 'glass': 0, 'beard': 0, 'candidateInfo': [{'birthday': '2022-8-24', 'faceImageUrl': ['6ad010cf-ce45-11ec-9715-e4246c7d1635/20220901/1/dsf_80fed821-29c9-11ed-884a-e4246c7d1635_27264993_27338395.jpg'], 'groupName': '全体人员', 'similarity': 97, 'sex': 1, 'cardType': 1, 'name': '曹前明', 'devPersonId': '48', 'id': '342422199004040175', 'type': 0}], 'sex': 0, 'occurrenceCount': 0, 'deviceCode': '1000038', 'globalScenePicUrl': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220901/1/dsf_80fed821-29c9-11ed-884a-e4246c7d1635_26915031_27257520.jpg', 'eye': 0, 'alarmType': 1001003, 'perFlag': -1, 'mouth': 0, 'feature': [], 'isHit': True, 'channelSeq': 24, 'szSerialUUID': '', 'channelName': '窑头平台值班室', 'beginTime': 1662026965, 'endTime': 1662026965, 'age': -1, 'mask': 0}, 'unitType': 1, 'alarmType': 1001003, 'channelSeq': 24, 'orgCode': '001001001', 'channelName': '窑头平台值班室', 'alarmStat': 1, 'isEvent': True}, 'subsystem': 'evo-face', 'userIds': None, 'sid': None, 'domainId': None, 'infoArray': None, 'protocol': None} data = {'id': 1662026969203, 'category': 'alarm', 'method': 'alarm.msg', 'info': {'orgName': '曲阳县金隅水泥厂', 'nodeCode': '1000038$1$0$24', 'deviceCode': '1000038', 'alarmCode': '44df73ba-a423-4479-af70-1f930b00a7e0', 'alarmPicture': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220901/1/dsf_80fed821-29c9-11ed-884a-e4246c7d1635_27257520_27264993.jpg', 'nodeType': 2, 'alarmDate': '1662026965', 'alarmGrade': 2, 'isSave': True, 'extend': {'faceImageUrl': ['6ad010cf-ce45-11ec-9715-e4246c7d1635/20220901/1/dsf_80fed821-29c9-11ed-884a-e4246c7d1635_27257520_27264993.jpg'], 'glass': 0, 'beard': 0, 'candidateInfo': [{'birthday': '2022-8-24', 'faceImageUrl': [
'6ad010cf-ce45-11ec-9715-e4246c7d1635/20220901/1/dsf_80fed821-29c9-11ed-884a-e4246c7d1635_27264993_27338395.jpg'], 'groupName': '全体人员', 'similarity': 97, 'sex': 1, 'cardType': 1, 'name': '曹前明', 'devPersonId': '48', 'id': '342422199004040175', 'type': 0}], 'sex': 0, 'occurrenceCount': 0, 'deviceCode': '1000038', 'globalScenePicUrl': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220901/1/dsf_80fed821-29c9-11ed-884a-e4246c7d1635_26915031_27257520.jpg', 'eye': 0, 'alarmType': 1001003, 'perFlag': -1, 'mouth': 0, 'feature': [], 'isHit': True, 'channelSeq': 24, 'szSerialUUID': '', 'channelName': '窑头平台值班室', 'beginTime': 1662026965, 'endTime': 1662026965, 'age': -1, 'mask': 0}, 'unitType': 1, 'alarmType': 1001003, 'channelSeq': 24, 'orgCode': '001001001', 'channelName': '窑头平台值班室', 'alarmStat': 1, 'isEvent': True}, 'subsystem': 'evo-face', 'userIds': None, 'sid': None, 'domainId': None, 'infoArray': None, 'protocol': None}
# data = {'id': 1662032288888, 'category': 'alarm', 'method': 'alarm.msg', 'info': {'orgName': '曲阳县金隅水泥厂', 'nodeCode': '1000038$1$0$25', 'deviceCode': '1000038', 'alarmCode': 'c3df59cd-59d0-4f46-a32c-d2bf7778b37d', 'alarmPicture': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220901/1/dsf_80fed821-29c9-11ed-884a-e4246c7d1635_44280859_44288676.jpg', 'nodeType': 2, 'alarmDate': '1662032288', 'alarmGrade': 2, 'isSave': True, 'extend': {'faceImageUrl': ['6ad010cf-ce45-11ec-9715-e4246c7d1635/20220901/1/dsf_80fed821-29c9-11ed-884a-e4246c7d1635_44280859_44288676.jpg'], 'glass': 0, 'beard': 0, 'candidateInfo': [], 'sex': 0, 'occurrenceCount': 0, 'deviceCode': '1000038', 'globalScenePicUrl': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220901/1/dsf_80fed821-29c9-11ed-884a-e4246c7d1635_44127174_44280859.jpg', 'eye': 0, 'alarmType': 1001000, 'perFlag': -1, 'mouth': 0, 'feature': [], 'isHit': True, 'channelSeq': 25, 'szSerialUUID': '', 'channelName': '公司大门口', 'beginTime': 1662032284, 'endTime': 1662032284, 'age': -1, 'mask': 0}, 'unitType': 1, 'alarmType': 1001000, 'channelSeq': 25, 'orgCode': '001001001', 'channelName': '公司大门口', 'alarmStat': 1, 'isEvent': True}, 'subsystem': 'evo-face', 'userIds': None, 'sid': None, 'domainId': None, 'infoArray': None, 'protocol': None} # data = {'id': 1662032288888, 'category': 'alarm', 'method': 'alarm.msg', 'info': {'orgName': '曲阳县金隅水泥厂', 'nodeCode': '1000038$1$0$25', 'deviceCode': '1000038', 'alarmCode': 'c3df59cd-59d0-4f46-a32c-d2bf7778b37d', 'alarmPicture': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220901/1/dsf_80fed821-29c9-11ed-884a-e4246c7d1635_44280859_44288676.jpg', 'nodeType': 2, 'alarmDate': '1662032288', 'alarmGrade': 2, 'isSave': True, 'extend': {'faceImageUrl': ['6ad010cf-ce45-11ec-9715-e4246c7d1635/20220901/1/dsf_80fed821-29c9-11ed-884a-e4246c7d1635_44280859_44288676.jpg'], 'glass': 0, 'beard': 0, 'candidateInfo': [], 'sex': 0, 'occurrenceCount': 0, 'deviceCode': '1000038', 'globalScenePicUrl': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220901/1/dsf_80fed821-29c9-11ed-884a-e4246c7d1635_44127174_44280859.jpg', 'eye': 0, 'alarmType': 1001000, 'perFlag': -1, 'mouth': 0, 'feature': [], 'isHit': True, 'channelSeq': 25, 'szSerialUUID': '', 'channelName': '公司大门口', 'beginTime': 1662032284, 'endTime': 1662032284, 'age': -1, 'mask': 0}, 'unitType': 1, 'alarmType': 1001000, 'channelSeq': 25, 'orgCode': '001001001', 'channelName': '公司大门口', 'alarmStat': 1, 'isEvent': True}, 'subsystem': 'evo-face', 'userIds': None, 'sid': None, 'domainId': None, 'infoArray': None, 'protocol': None}
data = {'id': 1662099853937, 'category': 'alarm', 'method': 'alarm.msg', 'info': {'orgName': '曲阳县金隅水泥厂', 'nodeCode': '1000038$1$0$24', 'deviceCode': '1000038', 'alarmCode': 'c520e09f-4b5d-4d04-be7b-005386a9b835', 'alarmPicture': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220902/1/dsf_a880f743-2a7e-11ed-884a-e4246c7d1635_57321861_57329128.jpg', 'nodeType': 2, 'alarmDate': '1662099849', 'alarmGrade': 2, 'isSave': True, 'extend': {'faceImageUrl': ['6ad010cf-ce45-11ec-9715-e4246c7d1635/20220902/1/dsf_a880f743-2a7e-11ed-884a-e4246c7d1635_57321861_57329128.jpg'], 'glass': 0, 'beard': 0, 'candidateInfo': [{'birthday': '2022-8-24', 'faceImageUrl': [ data = {'id': 1662099853937, 'category': 'alarm', 'method': 'alarm.msg', 'info': {'orgName': '曲阳县金隅水泥厂', 'nodeCode': '1000038$1$0$24', 'deviceCode': '1000038', 'alarmCode': 'c520e09f-4b5d-4d04-be7b-005386a9b835', 'alarmPicture': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220902/1/dsf_a880f743-2a7e-11ed-884a-e4246c7d1635_57321861_57329128.jpg', 'nodeType': 2, 'alarmDate': '1662099849', 'alarmGrade': 2, 'isSave': True, 'extend': {'faceImageUrl': ['6ad010cf-ce45-11ec-9715-e4246c7d1635/20220902/1/dsf_a880f743-2a7e-11ed-884a-e4246c7d1635_57321861_57329128.jpg'], 'glass': 0, 'beard': 0, 'candidateInfo': [{'birthday': '2022-8-24', 'faceImageUrl': [
'6ad010cf-ce45-11ec-9715-e4246c7d1635/20220902/1/dsf_a880f743-2a7e-11ed-884a-e4246c7d1635_57329128_57402530.jpg'], 'groupName': '全体人员', 'similarity': 99, 'sex': 1, 'cardType': 1, 'name': '曹前明', 'devPersonId': '48', 'id': '342422199004040175', 'type': 0}], 'sex': 0, 'occurrenceCount': 0, 'deviceCode': '1000038', 'globalScenePicUrl': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220902/1/dsf_a880f743-2a7e-11ed-884a-e4246c7d1635_56995669_57321861.jpg', 'eye': 0, 'alarmType': 1001003, 'perFlag': -1, 'mouth': 0, 'feature': [], 'isHit': True, 'channelSeq': 24, 'szSerialUUID': '', 'channelName': '窑头平台值班室', 'beginTime': 1662099849, 'endTime': 1662099849, 'age': -1, 'mask': 0}, 'unitType': 1, 'alarmType': 1001003, 'channelSeq': 24, 'orgCode': '001001001', 'channelName': '窑头平台值班室', 'alarmStat': 1, 'isEvent': True}, 'subsystem': 'evo-face', 'userIds': None, 'sid': None, 'domainId': None, 'infoArray': None, 'protocol': None} '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220902/1/dsf_a880f743-2a7e-11ed-884a-e4246c7d1635_57329128_57402530.jpg'], 'groupName': '全体人员', 'similarity': 99, 'sex': 1, 'cardType': 1, 'name': '曹前明', 'devPersonId': '48', 'id': '342422199004040175', 'type': 0}], 'sex': 0, 'occurrenceCount': 0, 'deviceCode': '1000038', 'globalScenePicUrl': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220902/1/dsf_a880f743-2a7e-11ed-884a-e4246c7d1635_56995669_57321861.jpg', 'eye': 0, 'alarmType': 1001003, 'perFlag': -1, 'mouth': 0, 'feature': [], 'isHit': True, 'channelSeq': 24, 'szSerialUUID': '', 'channelName': '窑头平台值班室', 'beginTime': 1662099849, 'endTime': 1662099849, 'age': -1, 'mask': 0}, 'unitType': 1, 'alarmType': 1001003, 'channelSeq': 24, 'orgCode': '001001001', 'channelName': '窑头平台值班室', 'alarmStat': 1, 'isEvent': True}, 'subsystem': 'evo-face', 'userIds': None, 'sid': None, 'domainId': None, 'infoArray': None, 'protocol': None}
data = {'id': 1662786479984, 'category': 'alarm', 'method': 'alarm.msg', 'info': {'orgName': '曲阳县金隅水泥厂', 'nodeCode': '1000038$1$0$24', 'deviceCode': '1000038', 'alarmCode': 'b672731c-4807-47e6-a468-c5f85a68e87d', 'alarmPicture': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220910/1/dsf_2c1150b4-309b-11ed-884a-e4246c7d1635_45588364_45596445.jpg', 'nodeType': 2, 'alarmDate': '1662786477', 'alarmGrade': 2, 'isSave': True, 'extend': {'faceImageUrl': ['6ad010cf-ce45-11ec-9715-e4246c7d1635/20220910/1/dsf_2c1150b4-309b-11ed-884a-e4246c7d1635_45588364_45596445.jpg'], 'glass': 0, 'beard': 0, 'candidateInfo': [{'birthday': '2022-8-24', 'faceImageUrl': ['6ad010cf-ce45-11ec-9715-e4246c7d1635/20220910/1/dsf_2c1150b4-309b-11ed-884a-e4246c7d1635_45596445_45673444.jpg'], 'groupName': '全体人员', 'similarity': 81, 'sex': 2, 'cardType': 1, 'name': '石静', 'devPersonId': '47', 'id': '371324199502156548', 'type': 0}], 'sex': 0, 'occurrenceCount': 0, 'deviceCode': '1000038', 'globalScenePicUrl': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220910/1/dsf_2c1150b4-309b-11ed-884a-e4246c7d1635_45288246_45588364.jpg', 'eye': 0, 'alarmType': 1001003, 'perFlag': -1, 'mouth': 0, 'feature': [], 'isHit': True, 'channelSeq': 24, 'szSerialUUID': '', 'channelName': '窑头平台值班室', 'beginTime': 1662786477, 'endTime': 1662786477, 'age': -1, 'mask': 0}, 'unitType': 1, 'alarmType': 1001003, 'channelSeq': 24, 'orgCode': '001001001', 'channelName': '窑头平台值班室', 'alarmStat': 1, 'isEvent': True}, 'subsystem': 'evo-face', 'userIds': None, 'sid': None, 'domainId': None, 'infoArray': None, 'protocol': None} data = {'id': 1662786479984, 'category': 'alarm', 'method': 'alarm.msg', 'info': {'orgName': '曲阳县金隅水泥厂', 'nodeCode': '1000038$1$0$24', 'deviceCode': '1000038', 'alarmCode': 'b672731c-4807-47e6-a468-c5f85a68e87d', 'alarmPicture': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220910/1/dsf_2c1150b4-309b-11ed-884a-e4246c7d1635_45588364_45596445.jpg', 'nodeType': 2, 'alarmDate': '1662786477', 'alarmGrade': 2, 'isSave': True, 'extend': {'faceImageUrl': ['6ad010cf-ce45-11ec-9715-e4246c7d1635/20220910/1/dsf_2c1150b4-309b-11ed-884a-e4246c7d1635_45588364_45596445.jpg'], 'glass': 0, 'beard': 0, 'candidateInfo': [{'birthday': '2022-8-24', 'faceImageUrl': [
'6ad010cf-ce45-11ec-9715-e4246c7d1635/20220910/1/dsf_2c1150b4-309b-11ed-884a-e4246c7d1635_45596445_45673444.jpg'], 'groupName': '全体人员', 'similarity': 81, 'sex': 2, 'cardType': 1, 'name': '石静', 'devPersonId': '47', 'id': '371324199502156548', 'type': 0}], 'sex': 0, 'occurrenceCount': 0, 'deviceCode': '1000038', 'globalScenePicUrl': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220910/1/dsf_2c1150b4-309b-11ed-884a-e4246c7d1635_45288246_45588364.jpg', 'eye': 0, 'alarmType': 1001003, 'perFlag': -1, 'mouth': 0, 'feature': [], 'isHit': True, 'channelSeq': 24, 'szSerialUUID': '', 'channelName': '窑头平台值班室', 'beginTime': 1662786477, 'endTime': 1662786477, 'age': -1, 'mask': 0}, 'unitType': 1, 'alarmType': 1001003, 'channelSeq': 24, 'orgCode': '001001001', 'channelName': '窑头平台值班室', 'alarmStat': 1, 'isEvent': True}, 'subsystem': 'evo-face', 'userIds': None, 'sid': None, 'domainId': None, 'infoArray': None, 'protocol': None}
dispatch_dahua_event(data=data) dispatch_dahua_event(data=data)
return Response() return Response()
@ -210,6 +214,35 @@ class TestViewSet(CustomGenericViewSet):
snap_and_analyse(vc, ['fire1'], Opl.objects.get(id='1568880208688320512')) snap_and_analyse(vc, ['fire1'], Opl.objects.get(id='1568880208688320512'))
return Response() return Response()
@action(methods=['post'], detail=False, serializer_class=Serializer)
def test_snap_task(self, request, pk=None):
"""测试抓图识别任务
测试抓图识别任务
"""
code = request.data['code']
task = opl_task.delay([code], '1568880208688320512')
task_id = task.task_id
test_snap_list = cache.get('test_snap_task', [])
test_snap_list.append(task_id)
cache.set('test_snap_task', test_snap_list)
return Response({'test_snap_task': task_id})
@action(methods=['post'], detail=False, serializer_class=Serializer)
def close_snap_task(self, request, pk=None):
"""关闭抓图识别任务
关闭抓图识别任务
"""
test_snap_list = cache.get('test_snap_task', [])
from celery.app.control import Control
from server.celery import app
celery_control = Control(app=app)
# 关闭作业视频监控任务
for i in test_snap_list:
celery_control.revoke(i, terminate=True)
return Response()
@action(methods=['post'], detail=False, serializer_class=Serializer) @action(methods=['post'], detail=False, serializer_class=Serializer)
def test_not_in_place(self, request, pk=None): def test_not_in_place(self, request, pk=None):
check_not_in_place(Opl.objects.get(id='1568880208688320512')) check_not_in_place(Opl.objects.get(id='1568880208688320512'))

View File

@ -15,7 +15,8 @@ from apps.third.models import TDevice
from apps.third.tapis import xxapis from apps.third.tapis import xxapis
from django.utils import timezone from django.utils import timezone
import time import time
from django.utils import timezone from django.core.cache import cache
@shared_task @shared_task
@ -79,12 +80,13 @@ def check_event_timeout():
def opl_task(vc_codes: list, opl_id: str): def opl_task(vc_codes: list, opl_id: str):
"""作业监控任务 """作业监控任务
""" """
start_time = time.time()
opl_cate = Opl.objects.get(id=opl_id).cate opl_cate = Opl.objects.get(id=opl_id).cate
# 找到作业需要加载的算法 # 找到作业需要加载的算法
algo_codes = list(EventCate.objects.filter(opl_cates=opl_cate).values_list('code', flat=True)) algo_codes = list(EventCate.objects.filter(opl_cates=opl_cate).values_list('code', flat=True))
vchannels = TDevice.objects.filter(code__in=vc_codes) vchannels = TDevice.objects.filter(code__in=vc_codes)
opl = Opl.objects.get(id=opl_id) opl = Opl.objects.get(id=opl_id)
while True: while time.time()-start_time < 28800: # 一次任务不手动关闭最多持续8小时
for i in vchannels: for i in vchannels:
Thread(target=snap_and_analyse, args=(i, algo_codes, opl)).start() Thread(target=snap_and_analyse, args=(i, algo_codes, opl)).start()
time.sleep(4) time.sleep(4)

View File

@ -112,8 +112,6 @@ def opl_end(ticket: Ticket):
celery_control = Control(app=app) celery_control = Control(app=app)
# 关闭作业视频监控任务 # 关闭作业视频监控任务
celery_control.revoke(opl.mtask_id, terminate=True) celery_control.revoke(opl.mtask_id, terminate=True)
opl.mtask_id = None
opl.save()
operation = opl.operation operation = opl.operation
opls = Opl.objects.filter(operation=operation) opls = Opl.objects.filter(operation=operation)
opls.filter(ticket=None).delete() # 删除无用许可证 opls.filter(ticket=None).delete() # 删除无用许可证