You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django商城站点单商品多图上传功能实现求助

解决方案:Django商品多图上传实现

1. 修改模型结构

新增关联模型存储多图,一个商品对应多张图片:

# products/models.py
class Product(models.Model):
    Name = models.CharField(max_length=60)
    Descriptions = models.TextField()
    Price = models.IntegerField()
    # 可选:保留原字段作为主图,不需要的话可删除
    Image = models.ImageField(upload_to='product', null=True, blank=True)
    category = models.ManyToManyField(Category, null=True, blank=True)
    Discount = models.SmallIntegerField(null=True, blank=True)
    Size = models.ManyToManyField(ProductSize, related_name='product')
    Color = models.ManyToManyField(ProductColor, related_name='product', blank=True)
    Property = models.ManyToManyField(ProductProperty, related_name='product')

# 新增商品图片模型
class ProductImage(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='images')
    image = models.ImageField(upload_to='product_images/')
    order = models.PositiveIntegerField(default=0)  # 控制图片显示顺序

    class Meta:
        ordering = ['order']

2. 更新详情视图

在详情页视图中传入商品的所有图片:

# products/views.py
class ProductDetail(DetailView):
    template_name = 'product/single-product.html'
    model = Product

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # 把当前商品的图片列表传入模板
        context['product_images'] = self.object.images.all()
        return context

3. 配置多图上传表单

用inlineformset_factory创建支持多图上传的表单集:

# products/forms.py(没有则新建)
from django.forms import inlineformset_factory
from .models import Product, ProductImage

# 限制最多4张图片,默认显示4个上传框
ProductImageFormSet = inlineformset_factory(
    Product,
    ProductImage,
    fields=('image', 'order'),
    extra=4,
    max_num=4,
    can_delete=False
)

4. 实现商品新增/编辑视图

在商品创建视图中处理图片表单集:

# products/views.py
from django.views.generic.edit import CreateView
from .models import Product
from .forms import ProductImageFormSet

class ProductCreate(CreateView):
    model = Product
    fields = ['Name', 'Descriptions', 'Price', 'category', 'Discount', 'Size', 'Color', 'Property']
    template_name = 'product/product_create.html'

    def form_valid(self, form):
        self.object = form.save()
        # 处理图片上传
        formset = ProductImageFormSet(self.request.POST, self.request.FILES, instance=self.object)
        if formset.is_valid():
            formset.save()
        return super().form_valid(form)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # 把图片表单集传入模板
        if self.request.POST:
            context['image_formset'] = ProductImageFormSet(self.request.POST, self.request.FILES)
        else:
            context['image_formset'] = ProductImageFormSet()
        return context

5. 模板渲染

商品创建模板(product_create.html)

<form method="post" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form.as_p }}
    {{ image_formset.management_form }}
    {% for form in image_formset %}
        {{ form.as_p }}
    {% endfor %}
    <button type="submit">保存商品</button>
</form>

商品详情模板(single-product.html)

<div class="product-image-group">
    {% for img in product_images %}
        <img src="{{ img.image.url }}" alt="{{ object.Name }}">
    {% endfor %}
    <!-- 显示原主图(如果保留了该字段) -->
    {% if object.Image %}
        <img src="{{ object.Image.url }}" alt="{{ object.Name }} 主图">
    {% endif %}
</div>

6. 配置媒体文件

确保settings.py中已配置媒体路径:

# settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'

在项目根urls.py中添加媒体路由:

# urls.py
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # 其他路由
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

7. 执行数据库迁移

python manage.py makemigrations
python manage.py migrate

内容的提问来源于stack exchange,提问作者mobin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 17:22:04