Проблема с попыткой загрузки отдельных изображений через несколько различных входов HTML-формы в Django без Django Forms
Я пытаюсь создать цифровые визитные карточки, создавая пользовательский визуальный редактор с различными html-формами для загрузки различных изображений, таких как профиль, фон, логотип и т.д., без Django Forms. Я смог заставить одну форму работать с бэкендом Django, который использует поля, одно из которых для имени изображения, а другое - url изображения. Я надеялся повторить этот процесс для каждого изображения, пока не дойду до раздела слайдера. Я все еще работаю над этим, поэтому дизайн еще не завершен и использую тестовые данные. Я включил изображение для справки о том, чего я пытаюсь достичь, так же глупо, как и тестовые данные.
urls.py
from django.conf.urls import url
from django.urls import path
from . import views
urlpatterns = [
url(r'^icards/icard/list/$', views.icard_list, name='icard_list'),
url(r'^icards/icard/add/', views.icard_add, name='icard_add'),
url(r'^icards/icard/edit/(?P<pk>\d+)/$', views.icard_edit, name='icard_edit'),
# url(r'^icards/icard_details/(?P<pk>\d+)/$', views.icard_details, name='icard_details'),
url(r'^icards/icard/delete/(?P<pk>\d+)/$', views.icard_delete, name='icard_delete'),
# url(r'^icards/editor_base/', views.editor_base, name='editor_base'),
url(r'icards/', views.icards, name='icards'),
views.py
models.py
error
Используйте утверждения request.FILES.get()
и if
для обработки необязательных загрузок изображений.
# myfile = request.FILES['myfile']
# bg_myfile = request.FILES['bg_myfile']
myfile = request.FILES.get('myfile')
bg_myfile = request.FILES.get('bg_myfile')
# fss.delete(icard.logo)
# fss.delete(icard.bg_image)
# b.logo = filename
# b.logo_url = url
# b.bg_image = bg_filename
# b.bg_url = bg_url
if myfile:
fss.delete(icard.logo)
b.logo = filename
b.logo_url = url
if bg_myfile:
fss.delete(icard.bg_image)
b.bg_image = bg_filename
b.bg_url = bg_url
Обработка нескольких загруженных изображений
Для более удобной обработки загрузки нескольких изображений:
- избегайте вложенных утверждений
if
для проверок "не поддерживается" и "слишком большой". - сохранять файлы после проверок (которые не полагаются на сохраненные файлы) вместо удаления при неудачных проверках.
- возвращать имена файлов, которые не прошли проверку, чтобы помочь пользователю узнать, что нужно решить. .
- defer
fs.delete()
, чтобы существующие изображения не удалялись, еслиicard.save()
не удается.
try:
print("Try function reached")
myfile = request.FILES.get('myfile')
bg_myfile = request.FILES.get('bg_myfile')
files_to_check = filter(None, [myfile, bg_myfile])
filenames_not_supported = [file.name for file in files_to_check if not str(myfile.content_type).startswith("image")]
if filenames_not_supported:
error = "Your File is not supported: {}".format(filenames_not_supported)
return render(request, 'back/error.html', {'error': error})
filenames_too_large = [file.name for file in files_to_check if file.size >= 5000000]
if filenames_too_large:
error = "your File is Larger than 5 MB: {}".format(filenames_too_large)
return render(request, 'back/error.html', {'error': error})
fs = FileSystemStorage()
filenames_to_delete = []
if myfile:
filenames_to_delete.append(icard.logo)
icard.logo = fs.save(myfile.name, myfile)
icard.logo_url = fs.url(icard.logo)
if bg_myfile:
filenames_to_delete.append(icard.bg_image)
icard.bg_image = fs.save(bg_myfile.name, bg_myfile)
icard.bg_url = fs.url(icard.bg_image)
icard.name = name
icard.category = category
icard.feature_one = feature_one
icard.save()
print("func: Icard Data Edit Saved")
for filename in filenames_to_delete:
fs.delete(filename)
return redirect('icard_list')
except Exception:
return redirect('icard_edit', pk)
Тогда работа с загрузкой нового изображения будет простой и понятной:
profile = request.FILES.get('profile')
# files_to_check = filter(None, [myfile, bg_myfile])
files_to_check = filter(None, [myfile, bg_myfile, profile])
# ...
if profile:
filenames_to_delete.append(icard.profile)
icard.profile = fs.save(profile.name, profile)
icard.profile_url = fs.url(icard.profile)
Об ошибке NoReverseMatch
Шаблон URL r'^icards/icard/edit/(?P<pk>\d+)/$'
требует pk
.
# return redirect('icard_edit')
return redirect('icard_edit', pk)