Проблема с попыткой загрузки отдельных изображений через несколько различных входов 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

enter image description here

Используйте утверждения 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)
Вернуться на верх