Django обрабатывает файлы, загруженные через React, не заставляя пользователей ждать
Прошу прощения, если название смущает.
Итак, я пытаюсь создать webapp, где пользователи загружают некоторые файлы через сайт React, затем, когда Django получает эти файлы, он начинает обрабатывать эти файлы, вызывая некоторые функции.
Однако, нагрузка довольно большая, бэкенду может потребоваться 3-5 минут для завершения операции обработки. Я бы хотел, чтобы бэкенд делал свое дело, не заставляя пользователя фронтенда ждать.
Таким образом, пока бэкэнд обрабатывает эти файлы, пользователи могут продолжать пользоваться сайтом, как они хотят, а когда операция обработки будет завершена, может появиться закусочная панель или что-то подобное, чтобы уведомить пользователя фронтэнда о том, что операция завершена.
Backend
settings.py
# Configure path to uploaded files
DATA_ROOT = os.path.join(BASE_DIR, 'myapp/main/data')
DATA_URL = 'data'
Модель: myproject/myapp/models.py
class Document(models.Model):
docfile = models.FileField(upload_to='')
Вид: myproject/myapp/views.py
Я думал использовать для этого async в Python, но разве return
не приведет к немедленному уничтожению процесса?
Функция upload
является лишь небольшой модификацией документации от Django о том, как обрабатывать загруженные файлы.
# import a bunch of stuff...
async def handle_uploaded_files(files):
await process(files)
def upload(request):
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
files = request.FILES.getlist('ix_files')
for file in files:
file.save()
asyncio.run(handle_uploaded_files(files))
return HttpResponseRedirect('/')
else:
form = DocumentForm()
return render(request, 'myapp/index.html')
URLs проекта: myproject/urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('myapp.urls')),
] + static(settings.DATA_URL, document_root=settings.DATA_ROOT)
URLs приложения: myproject/myapp/urls.py
urlpatterns = [
path('', never_cache(views.index)),
path('upload/', never_cache(views.upload)), # this is the one!
path('api/', include(router.urls)),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]
Frontend
const onDrop = useCallback((acceptedFiles) => {
//TODO
const csrftoken = Cookies.get('csrftoken');
var form_data = new FormData();
for (var i = 0; i < acceptedFiles.length; i++) {
form_data.append("ixFile" + i, acceptedFiles[i]);
}
axios
.post(process.env.UPLOAD_URL, form_data, {
headers: { "content-type": "multipart/form-data", 'X-CSRFToken': csrftoken },
})
.then((res) => {
console.log(res.data);
})
.catch((err) => console.log(err));
});