提问人:Maxim K 提问时间:11/6/2023 更新时间:11/7/2023 访问量:40
如何在请求中添加多个 base64 编码的图像
How to add multiple base64 encoded images in a request
问:
我想发出 POST 请求来创建机器人,同时我想传输几个以 base64 编码的photo_examples图像。 默认情况下,使用 Base64ImageField 时,只能添加一张图片,我需要添加几张。 我试图查看互联网上的其他项目,但我没有找到如何实现它的解决方案。
models.py
class Bot(models.Model):
"""Bot Model."""
name = models.CharField(
'Название',
max_length=100
)
author = models.ForeignKey(
User,
on_delete=models.CASCADE,
verbose_name='Автор',
)
description = models.TextField(
'Описание'
)
categories = models.ManyToManyField(
Category,
through='CategoryBot',
related_name='bots',
verbose_name='Категории',
)
main_photo = models.ImageField(
'Фото',
upload_to='uploads/main/%Y/%m/%d/',
)
price = models.DecimalField(
'Цена',
max_digits=8,
decimal_places=0
)
is_special_offer = models.BooleanField(
'Спецпредложение',
default=False
)
class Meta:
ordering = ('name',)
verbose_name = 'Бот'
verbose_name_plural = 'Боты'
def __str__(self):
return self.name
class Photo(models.Model):
"""Model of photos of examples of the bot's work."""
photo_examples = models.ImageField(
'Фото(образцы)',
upload_to='uploads/examples/%Y/%m/%d/',
)
bot = models.ForeignKey(
Bot,
on_delete=models.CASCADE,
verbose_name='Бот',
related_name='photo_examples'
)
class Meta:
ordering = ('bot',)
verbose_name = 'Фото(образцы)'
verbose_name_plural = 'Фото(образцы)'
def __str__(self):
return f' Фото бота {self.bot}'
serializers.py
class PhotoSerializer(serializers.ModelSerializer):
"""Serializer of photo bot examples"""
photo_examples = Base64ImageField()
class Meta:
model = Photo
fields = '__all__'
class CategoryNameSerializer(serializers.PrimaryKeyRelatedField):
def to_representation(self, value):
return value.name
class AbstractBotSerializer(serializers.ModelSerializer):
"""
An abstract class that defines serialization and
deserialization behavior for bot-related data.
"""
photo_examples = PhotoSerializer(many=True)
author = serializers.StringRelatedField(read_only=True)
discount_author = serializers.SerializerMethodField()
discount_category = serializers.SerializerMethodField()
amount_discounts_sum = serializers.SerializerMethodField()
final_price = serializers.SerializerMethodField()
categories = CategoryNameSerializer(
required=False,
queryset=Category.objects.all(),
many=True,
)
class Meta:
abstract = True
fields = '__all__'
views.py
class BotViewSet(ModelViewSet):
"""The viewset for the bot.
With the possibility of pagination, search by name
and description, filtering by category"""
queryset = Bot.objects.all()
serializer_class = BotSerializer
pagination_class = LimitPageNumberPagination
filter_backends = (filters.SearchFilter, DjangoFilterBackend, )
search_fields = ('name', 'description')
permission_classes = (IsAuthorOrReadOnly, IsAuthor,)
filterset_fields = ('categories', )
def get_serializer_class(self):
if self.action == 'retrieve':
return BotReviewRatingSerializer
return self.serializer_class
def perform_create(self, serializer):
discount_author = self.request.data.get("discount_author", 0)
bot_instance = serializer.save(author=self.request.user)
bot_discount, created = BotDiscount.objects.get_or_create(
bot=bot_instance, defaults={"discount": discount_author}
)
if not created:
bot_discount.discount = discount_author
bot_discount.save()
我想以大约这种格式传输数据,但是如果有一种方法可以更轻松地实现多个等碱基,那么您可以使用另一种方法来传输一些等碱基。
POST 请求
{
"name": "My Bot New",
"description": "This is my bot",
"main_photo": "data:image/jpeg;base64,/9j/4A....A/9k=",
"price": 500,
"discount_author": 35,
"categories": [6, 4],
"photo_examples": [
{
"photo_examples": "data:image/jpeg;base64,/9j/4A....A/9k="
},
{
"photo_examples": "data:image/jpeg;base64,/9j/4A....A/9k="
}
]
}
现在我收到一个错误:
{
"photo_examples": [
{
"bot": [
"Required field"
]
},
{
"bot": [
"Required field."
]
}
]
}
答:
0赞
Maxim K
11/7/2023
#1
添加到perform_create views.py:
# extracts the photo data from the request data
photos_data = self.request.data.get('photo_examples', None)
if photos_data:
# walk through each photo
for photo_data in photos_data:
photo_examples_data = photo_data.get('photo_examples', None)
if photo_examples_data:
# creates a new instance of a photo using a bot instance
photo = Photo.objects.create(bot=bot_instance)
# saves photo_examples data in an instance Photo
photo.photo_examples.save(
f"{photo.pk}.jpg",
ContentFile(base64.b64decode(
photo_examples_data.split(',')[1])),
save=True
)
В serializers.py 重新定义了该领域photo_examples
photo_examples = PhotoSerializer(many=True, read_only=True)
评论