Python django rest单线程/块视图

Python django rest单线程/块视图,python,django,python-3.x,django-rest-framework,pyinstaller,Python,Django,Python 3.x,Django Rest Framework,Pyinstaller,当视图中的代码由单个用户执行时,是否可以阻止访问该视图的所有用户执行该代码?一种单线程视图 我需要它,因为我在这个视图中使用pyinstaller生成python可执行文件,并通过配置文件将用户名传递到可执行文件中 例如: class CliConfig(APIView): def get(self, request, format=None): try: config['DEFAULT']['username'] = request.user

当视图中的代码由单个用户执行时,是否可以阻止访问该视图的所有用户执行该代码?一种单线程视图

我需要它,因为我在这个视图中使用
pyinstaller
生成python可执行文件,并通过配置文件将用户名传递到可执行文件中

例如:

class CliConfig(APIView):

    def get(self, request, format=None):
        try:
            config['DEFAULT']['username'] = request.user

            #make a build with pyinstaller
            bin_file = open(*generated filepath *, 'rb')
            response = Response(FileWrapper(bin_file), content_type='application/octet-stream')
            response['Content-Disposition'] = 'attachment; filename="%s"' % '*filename*'
            return response
        finally:
            config['DEFAULT']['username'] = ''
所以,基本上我想要的是在django rest framwork
APIView
中生成一个python可执行文件,它在其设置中有一个唯一的用户名。除了通过设置文件传递用户名之外,我看不到其他方法。如果有办法的话,我将不胜感激


python3.6.5
djangorestframework==3.8.2
pyinstaller==3.3.1

为什么要在配置中存储用户名? 这一代人不应该是每个用户吗

无论如何,在视图内部执行耗时的任务不是一个好的做法。
用于生成可执行文件并接受任何变量而不停止Django的长期任务。在此任务结束时,您可以将可执行文件发送到电子邮件或其他内容

from celery import Celery

app = Celery('hello', broker='amqp://guest@localhost//')


@app.task
def generate_executable(username):
    # make a build with pyinstaller with username

    bin_file = open(*generated filepath *, 'rb')
    response = Response(FileWrapper(bin_file), content_type='application/octet-stream')
    response['Content-Disposition'] = 'attachment; filename="%s"' % '*filename*'

    # send email and/or returns as task result

    return response


class CliConfig(APIView):

    def get(self, request, format=None):
        task = generate_executable(request.user)
        task.delay()

        return Response({"status": "started", "task_id": task.task_id})

看看Django渠道项目。通道为开发人员提供了抽象,并支持许多协议,包括HTTP。您可以将关键页面重写为用户频道。因此,您将能够使用
async/await
构造以块方式编写异步代码。

您还可以通过Javascript显示锁定状态,并使用Redis锁定机制:

#/settings.py
ASGI_APPLICATION=“my_app.routing.APPLICATION”
#我的应用程序/routing.py
从channels.routing导入协议类型路由器
从。消费者进口锁消费者
应用程序=协议类型路由器({
“websocket”:AuthMiddlewareStack(
URLRouter([
url(“^ws/lock$”,LockConsumer),
])
),
})
#my_app/consumers.py
类别LockConsumer(JsonWebsocketConsumer):
def连接(自):
如果self.scope['user']已通过身份验证:
self.accept()
其他:
self.close(代码='unauthorized')
通过
def接收_json(自身、内容、**kwargs):
#进程锁定程序
#尝试通过RedisAPI锁定
#如果锁定->通过javascript向用户显示警报
#模板,请参见此处的fuul文档http://channels.readthedocs.io/en/latest/javascript.html
...
....

如何创建生成的文件路径?对于每个请求都有一个唯一的安装程序,而不是阻止其他人生成安装程序,您感觉如何?编辑:啊,我看到问题了。您想锁定修改
配置['DEFAULT']['username']
。为什么不为每个请求创建一个不同名称的配置文件?tempfile模块可能会对此有所帮助。如果使用不同名称的配置,则构建将不知道新的配置名称。假设您有多个并行运行的工作进程。如果您只有一个进程和一个线程(如django development runserver中),那么一次只处理一个请求,并且保证不会出现争用条件。如果您有多个wsgi工作进程,在一个进程中修改
设置
对其他进程没有任何影响。您必须创建工作人员之间共享的锁。例如,数据库锁。我相信这个问题是这个问题的重复(由于悬赏,无法将其作为重复提交)。如果不需要将其扩展到多个服务器,最简单的解决方案是使用数据库锁或文件系统锁。
# <settings_dir>/settings.py
ASGI_APPLICATION = "my_app.routing.application"


# my_app/routing.py
from channels.routing import ProtocolTypeRouter

from .consumers import LockConsumer


application = ProtocolTypeRouter({
    "websocket": AuthMiddlewareStack(
        URLRouter([
            url("^ws/lock$", LockConsumer),
        ])
    ),
})


# my_app/consumers.py
class LockConsumer(JsonWebsocketConsumer):

    def connect(self):
        if self.scope['user'].is_authenticated:
            self.accept()
        else:
            self.close(code='unauthorized')
        pass

    def receive_json(self, content, **kwargs):
       # process lock procedures
       # try to lock by REDIS API
       # if locked -> show alarm to user by javascript 


# template, see fuul doc here http://channels.readthedocs.io/en/latest/javascript.html
...
<script src="{% static "websocketbridge.js" %}"></script>
....