Support file upload in AsyncFormView and subevent editor

This commit is contained in:
Raphael Michel
2023-10-16 17:59:32 +02:00
parent abda800953
commit 4d75c568b5
3 changed files with 46 additions and 6 deletions

View File

@@ -20,6 +20,8 @@
# <https://www.gnu.org/licenses/>.
#
import logging
from collections import defaultdict
from datetime import timedelta
from importlib import import_module
from zoneinfo import ZoneInfo
@@ -29,18 +31,20 @@ from celery.result import AsyncResult
from django.conf import settings
from django.contrib import messages
from django.core.exceptions import PermissionDenied, ValidationError
from django.core.files.uploadedfile import UploadedFile
from django.db import transaction
from django.http import HttpResponse, JsonResponse, QueryDict
from django.shortcuts import redirect, render
from django.test import RequestFactory
from django.utils import timezone, translation
from django.utils.timezone import get_current_timezone
from django.utils.datastructures import MultiValueDict
from django.utils.timezone import get_current_timezone, now
from django.utils.translation import get_language, gettext as _
from django.views import View
from django.views.generic import FormView
from redis import ResponseError
from pretix.base.models import User
from pretix.base.models import CachedFile, User
from pretix.base.services.tasks import ProfiledEventTask
from pretix.celery_app import app
@@ -228,15 +232,39 @@ class AsyncFormView(AsyncMixin, FormView):
)
def __init_subclass__(cls):
class StoredUploadedFile(UploadedFile):
pass
def async_execute(self, *, request_path, query_string, form_kwargs, locale, tz, url_kwargs=None, url_args=None,
organizer=None, event=None, user=None, session_key=None):
view_instance = cls()
form_kwargs['data'] = QueryDict(form_kwargs['data'])
if form_kwargs['files']:
for k, l in form_kwargs['files'].items():
uploadedfiles = []
for cfid in l:
cf = CachedFile.objects.get(pk=cfid)
uploadedfiles.append(StoredUploadedFile(
file=cf.file,
name=cf.filename,
content_type=cf.type,
size=cf.file.size,
charset=None,
content_type_extra=None,
))
form_kwargs['files'][k] = uploadedfiles
form_kwargs['files'] = MultiValueDict(form_kwargs['files'])
req = RequestFactory().post(
request_path + '?' + query_string,
data=form_kwargs['data'].urlencode(),
content_type='application/x-www-form-urlencoded'
)
if form_kwargs['files']:
req._load_post_and_files()
req._files = form_kwargs['files']
view_instance.request = req
view_instance.kwargs = url_kwargs
view_instance.args = url_args
@@ -287,8 +315,19 @@ class AsyncFormView(AsyncMixin, FormView):
return super().get(request, *args, **kwargs)
def form_valid(self, form):
if form.files:
raise TypeError('File upload currently not supported in AsyncFormView')
files = defaultdict(list)
if self.request.FILES:
for k, v in self.request.FILES.items():
cf = CachedFile.objects.create(
expires=now() + timedelta(hours=2),
date=now(),
web_download=False,
filename=v.name,
type=v.content_type,
)
cf.file.save('uploaded_file.dat', v)
files[k].append(str(cf.pk))
form_kwargs = {
k: v for k, v in self.get_form_kwargs().items()
}
@@ -299,6 +338,7 @@ class AsyncFormView(AsyncMixin, FormView):
form_kwargs['instance'] = None
form_kwargs.setdefault('data', QueryDict())
form_kwargs['data'] = form_kwargs['data'].urlencode()
form_kwargs['files'] = files
form_kwargs['initial'] = {}
form_kwargs.pop('event', None)
kwargs = {

View File

@@ -8,7 +8,7 @@
{% block title %}{% trans "Date" context "subevent" %}{% endblock %}
{% block content %}
<h1>{% trans "Create multiple dates" context "subevent" %}</h1>
<form action="" method="post" class="form-horizontal" id="subevent-bulk-create-form" data-asynctask>
<form action="" method="post" class="form-horizontal" id="subevent-bulk-create-form" data-asynctask enctype="multipart/form-data">
{% csrf_token %}
{% bootstrap_form_errors form %}
{% for f in itemvar_forms %}

View File

@@ -11,7 +11,7 @@
{% else %}
<h1>{% trans "Date" context "subevent" %}</h1>
{% endif %}
<form action="" method="post" class="form-horizontal">
<form action="" method="post" class="form-horizontal" enctype="multipart/form-datai">
{% csrf_token %}
{% bootstrap_form_errors form %}
{% for f in itemvar_forms %}