Я создал приложение 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.