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(upload_to="products")

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>

settings.py:

STATIC_URL = '/static/'
MEDIA_URL = '/images/'
STATICFILES_DIRS = [
BASE_DIR / 'static'
]
MEDIA_ROOT = os.path.join(BASE_DIR, 'static/images')
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

项目urls . py

urlpatterns = [
path('admin/', admin.site.urls),
path('', include('projects.urls')),
]

应用urls . py

urlpatterns = [
path("", views.createProject, name="create-project")
]

Issue:

  1. 您制作的ProjectFormProject模型相关,但image字段在ProjectImage模型中。所以,image字段甚至没有传递给模板,你也没有在ProjectFrom中传递fields=['title','describtion']

  2. 您没有在项目的urls.py中配置保存媒体文件。

解决方案:

  1. 您应该在forms.py中创建两个表单,第一个ProjectForm将获得Project模型的数据,第二个ProjectImageForm将获得图像列表,然后使用request.FILES.getlist('image')您可以保存与特定实例相关的图像一个接一个地在循环中保存。

  2. 您应该在项目的url .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:在处理完POST数据后,你应该总是返回HttpResponseRedirect,这个技巧不是Django特有的,它是一个很好的实践,正如教程中所述。

Note:基于函数的视图一般写在snake_case而不是camelCase,你也可以从createProject改成create_project

Note:ProjectImage模型的FileField中将upload_to后面的/添加为upload_to='products/'

;在ClearableFileInput中不支持,您可以使用allow_multiple_selected代替。但仍然只允许上传一个项目。

这个方法适合我

forms.py

class MultipleFileInput(forms.ClearableFileInput):
allow_multiple_selected = True

class ProductImageForm(forms.ModelForm):
class Meta:
model = ProductImage
fields = ('image',)
widgets = {
'image': MultipleFileInput()
}

相关内容

  • 没有找到相关文章

最新更新