无法使用django上传多张图片
Cant upload multilple images using django
我正在尝试使用 Djnago 创建页面以在我的网站上的其他模型中添加新产品及其图像。
我得到的图像列表的长度始终为 0,并且出现 IndexError: list index out of range。我想我从请求中获取文件时没有正确使用 images = request.FILES.getlist('images')
models.py
class Products(models.Model):
product_name = models.CharField(
max_length=255, verbose_name='Product name')
product_slug = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
product_image = models.ImageField(
default='image-placeholder.png', verbose_name='Image')
creaton_date = models.DateTimeField(auto_now_add=True)
brand = models.ForeignKey(
Brands, verbose_name='Brand', on_delete=models.PROTECT)
price = models.FloatField(verbose_name='Price')
description = models.TextField(null=True, verbose_name='Description')
category = models.ForeignKey(
Categories, on_delete=models.CASCADE, verbose_name='Category')
bought_count = models.IntegerField(null=True, default=0)
class ProductImage(models.Model):
product = models.ForeignKey(Products, on_delete=models.CASCADE)
image = models.ImageField()
default = models.BooleanField(default=False)
def __str__(self):
return str(self.product)
template.html
<form id="checkoutform" action="" method="post">
{% csrf_token %}
<div class="caption">
<div class="form-group">
<input class="input" type="text" name="product-name" placeholder="Product name">
</div>
<div class="form-group">
<input class="input" type="text" name="brand" placeholder="Brand">
</div>
<div class="form-group">
<input class="input" type="number" name="price" placeholder="Price">
</div>
<div class="form-group">
<input class="input" type="file" multiple name="images" placeholder="Images">
</div>
<div class="form-group">
<input class="input" type="text" name="desc" placeholder="Description">
</div>
<div class="form-group">
<input class="input" type="text" name="category" placeholder="Category">
</div>
<input type="submit" value="Submit">
</form>
views.py
def create_product(request):
if request.user.is_superuser:
if request.method == 'POST':
data = request.POST
images = request.FILES.getlist('images')
brand = Brands.objects.get(name=data['brand'])
category = Categories.objects.get(name=data['category'])
product = Products.objects.create(
product_name = data['product-name'],
brand=brand,
price = data['price'],
description = data['desc'],
category = category,
image = images[0],
)
for i in range (1, len(images)):
image = ProductImage.objects.create(
product = product,
image = images[i]
)
return render(request, 'store/create_product.html')
else:
return HttpResponse("You are not allowed here")
好吧,如果您不介意的话,我会建议另一种上传多张图片的方法,首先创建单独的模型来处理图片,然后创建一个表单来处理多张图片上传。
Models.py
class Products(models.Model):
product_name = models.CharField(
max_length=255, verbose_name='Product name')
product_slug = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
product_image = models.ImageField(
default='image-placeholder.png', verbose_name='Image')
creaton_date = models.DateTimeField(auto_now_add=True)
brand = models.ForeignKey(
Brands, verbose_name='Brand', on_delete=models.PROTECT)
price = models.FloatField(verbose_name='Price')
description = models.TextField(null=True, verbose_name='Description')
category = models.ForeignKey(
Categories, on_delete=models.CASCADE, verbose_name='Category')
bought_count = models.IntegerField(null=True, default=0)
class productImage(models.Model):
product = models.ForeignKey(Product,on_delete=models.CASCADE)
image = models.ImageField(default='image-placeholder.png', verbose_name='Image')
您必须 link 在管理员中使用 StackedInine 将两个模型放在一起,就像这样:
Admin.py
from .models import Products,ProductImage
class ProductAdminImage(Admin.StackedInline)
model = ProductImage
@Admin.register(Products)
class ProductAdmin(Admin.ModelAdmin):
list_display = [] # fields that you want to display
inlines = [ProductAdminImage] # Here we are linking both models with an inline
现在我们将致力于 forms.py 处理多张图片上传
from .models import ProductImage
class ProductImageForm(forms.ModelForm):
class Meta:
model = ProductImage
fields = ['image']
widgets ={'image' :forms.ClearableFileInput(attrs={'multiple':True})}
最后我们专注于视图来操纵我们的图片上传,到目前为止你所做的很好,但是还有另一种上传多张图片的方法,这在很多情况下对我有用!
from .forms import ProductImageForm
def create_product(request):
if request.user.is_superuser:
if request.method == 'POST':
data = request.POST
images = request.FILES.getlist('images')
brand = Brands.objects.get(name=data['brand'])
category = Categories.objects.get(name=data['category'])
form = ProductImageForm(request.POST, request.FILES)
product = Products(product_name = data['product-name'],brand=brand,
price = data['price'],
description = data['desc'],
category = category,
product_image = images[0],)
product.save()
if form.is_valid():
data = form.save(commit=False)
for files in images:
data =ProductImage(product = product, image = files)
data.save()
return render(request, 'store/create_product.html')
else:
return HttpResponse("You are not allowed here")
对于那些可能遇到过类似问题的人来说,解决方案非常明显。我只是忘了在我的表单中添加 enctype="multipart/form-data"(用于上传媒体文件)
<form id="checkoutform" action="" method="post" enctype="multipart/form-data">
我正在尝试使用 Djnago 创建页面以在我的网站上的其他模型中添加新产品及其图像。 我得到的图像列表的长度始终为 0,并且出现 IndexError: list index out of range。我想我从请求中获取文件时没有正确使用 images = request.FILES.getlist('images')
models.py
class Products(models.Model):
product_name = models.CharField(
max_length=255, verbose_name='Product name')
product_slug = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
product_image = models.ImageField(
default='image-placeholder.png', verbose_name='Image')
creaton_date = models.DateTimeField(auto_now_add=True)
brand = models.ForeignKey(
Brands, verbose_name='Brand', on_delete=models.PROTECT)
price = models.FloatField(verbose_name='Price')
description = models.TextField(null=True, verbose_name='Description')
category = models.ForeignKey(
Categories, on_delete=models.CASCADE, verbose_name='Category')
bought_count = models.IntegerField(null=True, default=0)
class ProductImage(models.Model):
product = models.ForeignKey(Products, on_delete=models.CASCADE)
image = models.ImageField()
default = models.BooleanField(default=False)
def __str__(self):
return str(self.product)
template.html
<form id="checkoutform" action="" method="post">
{% csrf_token %}
<div class="caption">
<div class="form-group">
<input class="input" type="text" name="product-name" placeholder="Product name">
</div>
<div class="form-group">
<input class="input" type="text" name="brand" placeholder="Brand">
</div>
<div class="form-group">
<input class="input" type="number" name="price" placeholder="Price">
</div>
<div class="form-group">
<input class="input" type="file" multiple name="images" placeholder="Images">
</div>
<div class="form-group">
<input class="input" type="text" name="desc" placeholder="Description">
</div>
<div class="form-group">
<input class="input" type="text" name="category" placeholder="Category">
</div>
<input type="submit" value="Submit">
</form>
views.py
def create_product(request):
if request.user.is_superuser:
if request.method == 'POST':
data = request.POST
images = request.FILES.getlist('images')
brand = Brands.objects.get(name=data['brand'])
category = Categories.objects.get(name=data['category'])
product = Products.objects.create(
product_name = data['product-name'],
brand=brand,
price = data['price'],
description = data['desc'],
category = category,
image = images[0],
)
for i in range (1, len(images)):
image = ProductImage.objects.create(
product = product,
image = images[i]
)
return render(request, 'store/create_product.html')
else:
return HttpResponse("You are not allowed here")
好吧,如果您不介意的话,我会建议另一种上传多张图片的方法,首先创建单独的模型来处理图片,然后创建一个表单来处理多张图片上传。
Models.py
class Products(models.Model):
product_name = models.CharField(
max_length=255, verbose_name='Product name')
product_slug = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
product_image = models.ImageField(
default='image-placeholder.png', verbose_name='Image')
creaton_date = models.DateTimeField(auto_now_add=True)
brand = models.ForeignKey(
Brands, verbose_name='Brand', on_delete=models.PROTECT)
price = models.FloatField(verbose_name='Price')
description = models.TextField(null=True, verbose_name='Description')
category = models.ForeignKey(
Categories, on_delete=models.CASCADE, verbose_name='Category')
bought_count = models.IntegerField(null=True, default=0)
class productImage(models.Model):
product = models.ForeignKey(Product,on_delete=models.CASCADE)
image = models.ImageField(default='image-placeholder.png', verbose_name='Image')
您必须 link 在管理员中使用 StackedInine 将两个模型放在一起,就像这样:
Admin.py
from .models import Products,ProductImage
class ProductAdminImage(Admin.StackedInline)
model = ProductImage
@Admin.register(Products)
class ProductAdmin(Admin.ModelAdmin):
list_display = [] # fields that you want to display
inlines = [ProductAdminImage] # Here we are linking both models with an inline
现在我们将致力于 forms.py 处理多张图片上传
from .models import ProductImage
class ProductImageForm(forms.ModelForm):
class Meta:
model = ProductImage
fields = ['image']
widgets ={'image' :forms.ClearableFileInput(attrs={'multiple':True})}
最后我们专注于视图来操纵我们的图片上传,到目前为止你所做的很好,但是还有另一种上传多张图片的方法,这在很多情况下对我有用!
from .forms import ProductImageForm
def create_product(request):
if request.user.is_superuser:
if request.method == 'POST':
data = request.POST
images = request.FILES.getlist('images')
brand = Brands.objects.get(name=data['brand'])
category = Categories.objects.get(name=data['category'])
form = ProductImageForm(request.POST, request.FILES)
product = Products(product_name = data['product-name'],brand=brand,
price = data['price'],
description = data['desc'],
category = category,
product_image = images[0],)
product.save()
if form.is_valid():
data = form.save(commit=False)
for files in images:
data =ProductImage(product = product, image = files)
data.save()
return render(request, 'store/create_product.html')
else:
return HttpResponse("You are not allowed here")
对于那些可能遇到过类似问题的人来说,解决方案非常明显。我只是忘了在我的表单中添加 enctype="multipart/form-data"(用于上传媒体文件)
<form id="checkoutform" action="" method="post" enctype="multipart/form-data">