Я создал приложение django и хочу запускать функцию и представление асинхронно.

Это код файла вида django. У меня есть функция, у которой нет параметров и возврата, так как я использую глобальные переменные в коде.

В настоящее время я использую потоки и есть проблема. когда startfunc() запущен и выполняет какой-то код, и данные получены в то же время в представлении, это просто нарушает startfunc() и весь процесс не завершен, что является большой проблемой для меня и для приложения. Вот почему я пытаюсь использовать async. Если это можно сделать вместе (поток + async), я думаю, это было бы еще лучше. Дайте мне знать, если я ошибаюсь

я попробовал async, но получил эту ошибку RuntimeWarning: coroutine 'startfunc' was never awaited и также показывает некоторые ошибки из-за csrf, поэтому я добавил csrf_exempt, но все равно не работает

import func # (its a file in the directory of the django app)
global func_running
    

# this is the function

import func # (its a file in the directory of the django app)
global func_running
    
def startfunc():
    while func_running:
        # run a piece of code
        time.sleep(1)

@csrf_exempt
@sync_to_async
def restview(request):
    try:
        raw_data = request.body.decode('utf-8').strip('"')
        data = json.loads(raw_data)
        if "xyz" in data:
            xyz = data["xyz"]
            bot.xyz= xyz
            if not func.func_running:
                
                func_thread = threading.Thread(target=startfunc())
                func_running = True
                func_event.set()
                func_thread.start()
        return Response({"message": "func updated", "func": func})
    except json.JSONDecodeError:
        return Response({"error": "Invalid JSON"}, status=400)

Я хочу, чтобы обе функции выполнялись асинхронно. Я пробовал sync_to_async для функции представления, но она возвращала ошибки.

В Django не рекомендуется использовать глобальные переменные, так как в этом нет никакого смысла. Как объясняется здесь, в производственной среде у вас будет запущено несколько экземпляров процесса Python (проще говоря, "несколько терминалов, работающих одновременно"), поэтому нет смысла говорить о глобальных переменных. Вместо этого вам следует либо (1) использовать объектно-ориентированный Python, если переменная вычисляется на лету пользователем, либо (2) сохранять ее в базе данных.

(1) В частности, здесь django.views.View вы можете назначать переменные в классе представления. Вы можете использовать потоки для ускорения работы циклов. Например:

from django.views import Views
from django.http import JsonResponse
import concurrent.futures


class MySpecialView(View):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.result = []

    def fun_function(n):
        return n//2 #this is an example obviously

    def loop_fun_function(k):
        list_k = list(range(k))
        with concurrent.futures.ThreadPoolExecutor() as executor:
            self.result = list(executor.map(self.fun_function, list_k))
    
    @property
    def context(self, *args, **kwargs):
        return {"result": self.result}
    
    def get(self, request, *args, **kwargs):
        self.loop_fun_function(k=request.GET["SomeInteger"])
        return JsonResponse(self.context)

Или в случае (2) просто сохраните в базу данных, используя ORM-обертку Django для SQL.

Вернуться на верх