Django загрузка нескольких изображений в одно сообщение
Здравствуйте, я хочу позволить пользователю загружать несколько изображений в каждый пост. Аналогично платформе электронной коммерции с несколькими изображениями для каждого продукта. Но до сих пор изображения не отправляются в базу данных.
Вот мой код на данный момент:
models.py
:
class Project(models.Model):
title = models.CharField(max_length=200)
describtion = models.TextField(null=True, blank=True)
class ProjectImage(models.Model):
project = models.ForeignKey(Project, on_delete=models.CASCADE)
image = models.FileField()
forms.py
class ProjectForm(ModelForm):
image = forms.ImageField(widget=ClearableFileInput(attrs={'multiple':True}))
class Meta:
model = Project
fields = ['title', 'describtion']
views.py
:
def createProject(request):
form = ProjectForm()
if request.method == 'POST':
form = ProjectForm(request.POST)
images = request.FILES.getlist('image')
if form.is_valid():
project = form.save()
for i in images:
ProjectImage(project=project, image=i).save()
context = {'form':form}
return render(request, 'projects/project_form.html', context)
project_form.html
:
<form class="form" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{% for field in form %}
<div class="form__field">
<label for="formInput#text">{{field.label}}</label>
{{field}}
</div>
{% endfor %}
<input type="submit" name="" id="">
</form>
Выпуск:
Вы сделали
ProjectForm
, который относится к моделиProject
, но полеimage
находится в моделиProjectImage
. Таким образом, полеimage
даже не передается в шаблон, и вы также не передали его вfields=['title','describtion']
вProjectFrom
.Вы не сделали конфигурации для сохранения медиа файлов в urls.py.
проекта.
Решение:
Вы должны сделать две формы в forms.py, первая
ProjectForm
, которая будет получать данные для моделиProject
, а втораяProjectImageForm
, которая будет получать список изображений, затем используяrequest.FILES.getlist('image')
вы можете сохранять изображения, которые относятся к определенному экземпляру по одному в цикле, как вы пытались сохранить.Вы должны сделать медиа конфигурации в urls.py
проекта.
Попробуйте код ниже:
forms.py
from django import forms
from django.forms import ClearableFileInput
from .models import Project, ProjectImage
class ProjectForm(forms.ModelForm):
class Meta:
model = Project
fields = ['title', 'describtion']
class ProjectImageForm(forms.ModelForm):
class Meta:
model = ProjectImage
fields = ['image']
widgets = {
'image': ClearableFileInput(attrs={'multiple': True}),
}
views.py
from django.http import HttpResponse
from django.shortcuts import redirect, render
from .forms import ProjectImageForm, ProjectForm
from .models import Project, ProjectImage
def createProject(request):
form = ProjectForm()
form2 = ProjectImageForm()
if request.method == 'POST':
form = ProjectForm(request.POST)
form2 = ProjectImageForm(request.POST, request.FILES)
images = request.FILES.getlist('image')
if form.is_valid() and form2.is_valid():
title = form.cleaned_data['title']
describ = form.cleaned_data['describtion']
print(title, describ)
project_instance = Project.objects.create(
title=title, describtion=describ)
print('-------------------------------------------')
print(project_instance)
print('-------------------------------------------')
for i in images:
ProjectImage.objects.create(project=project_instance, image=i)
return redirect('thanks')
context = {'form': form, 'form2': form2}
return render(request, 'projects/project_form.html', context)
def thanks(request):
return HttpResponse('<h1>Form saved.</h1>')
project_form.html или файл шаблона:
<form class="form" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{form.title.label_tag}}
{{form.title}}
<br><br>
{{form.describtion.label_tag}}
{{form.describtion}}
<br><br>
{{form2.image.label_tag}}
{{form2.image}}
<br><br>
<input type="submit" name="" id="">
</form>
urls.py проекта
from django.conf.urls.static import static
from django.conf import settings
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('projects.urls'))
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT)
urls.py приложения
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('home.urls'))
]
Ваши models.py и settings.py могут оставаться одинаковыми, но рекомендуется использовать
MEDIA_URL = 'media/'
и MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
, тогда вы должны сделать вложенные папки внутри них для сохранения изображений или любых файлов.
Note:
Вы всегда должны возвращатьHttpResponseRedirect
после работы с POST данными, совет не относится к Django, это хорошая практика в целом, как указано в tutorial4.
Note:
Представления на основе функций обычно пишутся вsnake_case
, а не в, вы можете изменить его наcamelCase
create_project
из.createProject
Note:
Добавьте/
в конце upload_to какupload_to='products/'
в поле image вProjectImage
модели.