如何在 django 中将多个图像一起发布?

Posted

技术标签:

【中文标题】如何在 django 中将多个图像一起发布?【英文标题】:how to post multiple images together in django? 【发布时间】:2022-01-22 17:52:48 【问题描述】:

我想在 django 中创建一个包含多个图像的发布请求。

我尝试为图像创建不同的模型并使用 OnetoOneField 将其连接到我的“车辆”模型,但它一次只允许发布 1 个图像。(此方法如下所示)

我还尝试将多个图像作为逗号分隔的字符串获取,但是当我将图像作为二进制图像列表发布时,它显示“无效类型”错误。

我只需要创建一个 API 来一次性发布多张图片。

这是我的 model.py 文件 -

class VehicleImage(models.Model):
    image_id = models.AutoField(primary_key=True)
    image = models.ImageField(upload_to="media")
    def __str__(self):
        return self.vehicle.auction_title

class Vehicle(models.Model):
    auction_title = models.TextField()
    vehicle_images = models.ManyToManyField(VehicleImage, blank=True)
    vehicle_images_list = models.TextField()
    def __str__(self):
        return self.auction_title

Serializer.py 文件 -

class VehicleImageSerializer(serializers.ModelSerializer):
    class Meta:
        model = VehicleImage
        fields = "__all__"

class VehicleSerializer(serializers.ModelSerializer):
    vehicle_images = VehicleImageSerializer(many=True, read_only=True)
    
    class Meta:
        model = Vehicle
        fields = "__all__"

    def create(self, validated_data):
        images_data = validated_data['vehicle_images_list']
        vehicle = Vehicle.objects.create(**validated_data)
        if images_data!="":
            for data in images_data.split(','):
                image = VehicleImage.objects.get(image_id=data)
                vehicle.vehicle_images.add(image)
        return vehicle

Views.py 文件

class add_vehicle(ListCreateAPIView):        
    queryset = Vehicle.objects.all().order_by('-vehicle_id')
    serializer_class = VehicleSerializer
    pagination_class = CustomPagination

    def post(self, request, format=None):
        # creating the Vehicle
        vehicle_serializer = VehicleSerializer(data=request.data)
        if vehicle_serializer.is_valid():
            vehicle_serializer.save()
            return Response(
                "response":"vehicle_id":vehicle_serializer.data['vehicle_id'],
                "status_code":200, status = status.HTTP_200_OK)
        return Response(
                "response":vehicle_serializer.errors,
                "status_code":400, status = status.HTTP_400_BAD_REQUEST)

class add_images(ListCreateAPIView):
    queryset = VehicleImage.objects.all()
    serializer_class = VehicleImageSerializer
    pagination_class = CustomPagination

    def post(self, request, format=None):
        image_serializer = VehicleImageSerializer(data=request.data)
        if image_serializer.is_valid():
            image_serializer.save()
            return Response(
                "response":image_serializer.data,
                "status_code":200, status = status.HTTP_200_OK)
        return Response(
                "response":image_serializer.errors,
                "status_code":400, status = status.HTTP_400_BAD_REQUEST)

使用此方法,我首先使用“add_images”类逐个添加图像,然后在创建车辆时提供图像 ID 列表。有没有办法一次性添加所有图片?

【问题讨论】:

我认为没有办法直接使用DRF上传多张图片。您可能需要在view.py 中迭代图像,更多详细信息请访问***.com/a/53035559/16785359 我尝试了类似的方法,如此链接所示。它适用于邮递员,但是当我将它与 angular 一起使用时它不起作用,因为我无法获得二进制图像数据列表。它只显示一个列表 - [,,,.....] 我敢肯定,它有角度问题,而不是后端问题。您应该在前端修复表单或 API。 【参考方案1】:

要首先将多个图像发布到您的数据库,您需要为您的车辆创建单独的图像模型,如下所示: 模型.py

class Vehicle(models.Model):
    auction_title = models.TextField()
    description = models.CharField(max_length=200)
    date_created = models.DateTimeField(auto_now_add=True)
    def __str__(self):
        return self.auction_title

class VehicleImage(models.Model):
    vechicle  = models.ForeignKey(Vehicle,on_delete=models.CASCADE)
    image = models.ImageField(upload_to="media")
    def __str__(self):
        return self.vehicle.auction_title

然后你在你的admin.py中用stackedInline把这两个模型链接在一起,就像这样:

class VehicleImagesAdmin(admin.StackedInline):
       model = VehicleImage

class VehicleAdmin(admin.ModelAdmin):
      # The field your want to display 
      list_display  = ['auction_title','date_created']
      # Here you link the models together 
      inlines = [VehicleImagesAdmin]

现在您需要创建一个表单来处理多次上传

class VehicleImagesForm(forms.ModelForm):
    class Meta:
        model = VehicleImage
        fields = ['image']
        widget = forms.ClearableFileInput(attrs='multiple':True)

然后我们专注于创建一个视图来处理多个图像的发布请求过程,请注意,我将编写一个基于函数的视图以使其保持简单,它与类库视图具有相同的约定或智慧,因此您可以随意用你自己的智慧解决它。但这完美无缺。

def upload_vehicle_images(request):
    form = VehicleImagesForm(request.POST, request.FILES)
    files = requests.FILES.getlist['image']
    auction_title = request.POST['auction_title']
    description = request.POST['descritpion']
    vehicle = Vehicle(auction_title=auction_title,description=description)
    vehicle.save()
    # You would have to make some iterations through the list images inorder to post 
    # them to your database
    if form.is_valid:
       for file in files:
           vehicle_image_data = VehicleImage(vehicle=vehicle, image=file)
           vehicle_image_data.save() 
    return redirect(# redirect to anywhere you)

用于发布多张图片的 html 模板

 <form method="POST" action="" enctype="multipart/form-data">
% csrf_token %
<textarea class=""name="auction_title" id="id_auction_title"></textarea>
  <textarea class="" name="description" id="id_description"></textarea>
   <input  type="file" name="image"  id="id_image" multiple accept="image/*" >
 <button  type="submit">Post</button> 
</form>

或者您可以在将表单添加到上下文时使用它

<form method="POST" action="" enctype="multipart/form-data">
 % csrf_token %
 % form %
 <button  type="submit">Post</button> 
</form>

    

【讨论】:

不使用表格可以吗?我只需要创建一个 API 并将其提供给前端团队。 是的,如果您不想使用表单,我对 HTML 就是这样做的。做这样的事情
% csrf_token %

以上是关于如何在 django 中将多个图像一起发布?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 django 中将图像添加到帖子中

如何在 Django 中将 2 个模型字段结合在一起?

如何在可重用的应用程序中将命名空间 url 与 django 一起使用

如何在 django 中将一个表单字段拆分为模型的多个字段?

如何在django中将多个参数传递给url

如何在django中将QuerySet过滤到每个组的最大成员?