如何在 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 就是这样做的。做这样的事情以上是关于如何在 django 中将多个图像一起发布?的主要内容,如果未能解决你的问题,请参考以下文章
如何在可重用的应用程序中将命名空间 url 与 django 一起使用