Каналы Django и загрузка файлов
Я изучаю Django на лету, так что потерпите меня. Моя цель состоит в том, чтобы пользователь мог загрузить файл, серверный скрипт обработал его и отправил результаты на каждой итерации клиенту в реальном времени.
Моя текущая структура такова: Пользователь загружает файл (csv), он читается через views.py, затем создается пустой html вид, JS в html создает новый websocket, и вот здесь я не могу передать данные за пределы consumers.py или обработать данные.
Я также не уверен, что структура вида > JS script > consumers > ? является лучшим путем для обработки файлов, но я не нашел много документации по загрузке файлов и каналов.
views.py
from django.shortcuts import render
import pandas as pd
def someFunc(request):
if request.method == "POST":
global csvUpload
csvUpload = pd.read_csv(request.FILES['filename'])
return render(request, 'app/appPost.html')
Сначала я создаю представление здесь, чтобы пустая страница отображалась до запуска сценария.
appPost.html JS скрипт
var socket = new WebSocket('ws://localhost:8000/ws/app_ws/')
socket.onmessage = function(event){
var data = JSON.parse(event.data);
console.log(data);
var para = document.createElement("P");
para.innerText = data.message;
document.body.appendChild(para);
}
consumers.py
from channels.generic.websocket import WebsocketConsumer
from asgiref.sync import async_to_sync
class WSConsumer(WebsocketConsumer):
def connect(self):
self.accept()
self.render()
async_to_sync(self.add_group)('appDel_updates_group')
В конечном итоге я хотел бы передать то, что находится в этом сигнальном файле, соединению websocket.
app_alarm.py
from requests.api import request
import pandas as pd
import requests as r
def app_process(csvUpload):
csvUpload=pd.read_csv(request.FILES['filename'])
csvFile = pd.DataFrame(csvUpload)
colUsernames = csvFile.usernames
for user in colUsernames:
req = r.get('https://reqres.in/api/users/2')
t = req.json()
data = t['data']['email']
message = user + " " + data
channel_layer = get_channel_layer()
async_to_sync(channel_layer.group_send)(
'appDel_updates_group',
{'type': 'render', 'message': message}
)
Копирую из оригинального сообщения edit:
Потоковая обработка позволила мне отрисовать страницу, а затем передать данные в файл alarm.py для обработки. Это решило проблему, которую я имел, добавив следующий код в файл views.py:
x = threading.Thread(target=app_alarm.sub_process, args=[csvUpload])
x.setDaemon(False)
x.start()
return render(request, 'efax/appPost.html')
Это позволяет представлениям захватить файл с помощью request.FILES
и передать его сценарию до того, как страница была отрисована, не дожидаясь завершения обработки. Это сделало бы бессмысленным весь смысл каналов в данной ситуации. Надеюсь, это кому-нибудь поможет.