Как сделать три функции одной кнопкой отправки с одним документом формы?
У меня проблема с вызовом нескольких функций при одном нажатии кнопки submit. У меня есть одна форма, в которую пользователь должен вложить один файл (документ exls), и мне нужно, чтобы один документ использовался для 3 функций. Мне нужно сохранить документ, сделать некоторые действия в pandas и показать его в html. Могу ли я сделать это, поместив его в класс или что-то подобное? Мне очень нужна помощь, спасибо заранее.
def save_exls(request):
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
newdoc = Document(docfile=request.FILES['docfile'])
newdoc.save()
return redirect('html_exls')
else:
form = DocumentForm()
documents = Document.objects.all()
context = {'documents': documents, 'form': form,}
return render(request, 'list.html', context)
def pandas_exls(request):
if request.method == "POST":
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
output = io.BytesIO()
newdoc = request.FILES['docfile']
dfs = pd.read_excel(newdoc, sheet_name=None, index_col=[0])
writer = pd.ExcelWriter(output)
for name, df in dfs.items():
#pandas stuff
done.to_excel(writer, sheet_name=name)
output.seek(0)
response = HttpResponse(
output, content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = 'attachment; filename=%s' % filename
return response
else:
form = DocumentForm()
return render(request, 'list.html', {'form': form})
def html_exls(request):
if request.method == "POST":
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
output = io.BytesIO()
newdoc = request.FILES['docfile']
dfs = pd.read_excel(newdoc, sheet_name=None, index_col=[0])
writer = pd.ExcelWriter(output)
for name, df in dfs.items():
#pandas stuff for html
done.to_excel(writer, sheet_name=name)
html = done.to_html()
print(html)
output.seek(0)
response = HttpResponse(
output, content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = 'attachment; filename=%s' % filename
return response
else:
form = DocumentForm()
return render(request, 'list.html', {'form': form})
Некоторые варианты, которые вы, возможно, захотите изучить:
- Если все API действительно связаны друг с другом, вы можете преобразовать их в один API, который будет выполнять все 3 функции. Затем, чтобы по-прежнему поддерживать каждый API по отдельности, рефакторить код так, чтобы не повторять один и тот же код в объединенном API вместе с отдельными API. .
- Поверх шаблона HTML добавьте JavaScript (AJAX), который перехватит отправку формы, где вы будете выполнять 3x HTTP POST запросы к различным URL.
- Примените шаблон "Публикация/Подписка" (Pub/Sub) (Producer/Consumer). Идея состоит в том, чтобы подписать 3x URL на resource-x. Теперь опубликуйте/поместите данные на ресурс x. Затем система Pub/Sub должна переслать данные и вызвать всех подписанных потребителей, которые являются 3x URL.
- Одним из способов является использование таких сервисов, как AWS SNS, где вы создаете тему, подписываете 3x URL на эту тему, а затем изменяете свою форму для публикации в этой теме.
- Другим способом является реализация очереди задач, например Celery. Преобразуйте 3x URL в задачи Celery. Затем подготовьте один HTTP URL, который будет регистрировать полученные запросы к 3x задачам. Затем измените вашу форму, чтобы она отправляла запросы на этот HTTP URL.
- Не рекомендуется. Это было бы проще всего, но это грязный хак и очень синхронный. Цепляйте каждое представление друг к другу таким образом, чтобы после завершения работы одного представления вызывать следующее.