#python #django #django-rest-framework
#python #django #django-rest-framework
Вопрос:
Я пытаюсь отправить POST-запрос.
Я пытаюсь опубликовать данные (FormData) из javascript, который содержит массив изображений, Команда print (request.data) в моей консоли показывает это:
<QueryDict:
{'title': ['testTitle'], 'text': ['testText'],
'images': [<InMemoryUploadedFile: 486217.jpg (image/jpeg)>,
<InMemoryUploadedFile: 344611.jpg (image/jpeg)>,
<InMemoryUploadedFile: default.png (image/png)>]
}>
код в django:models.py
class Article(models.Model):
title = models.CharField(max_length=120)
text = models.TextField()
create_time = models.DateTimeField(default=datetime.utcnow, blank=True,
null=True)
def __str__(self):
return self.title
class ArticleImage(models.Model):
article = models.ForeignKey(Article, related_name='images',
on_delete=models.CASCADE)
img = models.ImageField(upload_to='article_images/')
is_main = models.BooleanField(default=False,blank=True,null=True)
create_time = models.DateTimeField(default=datetime.utcnow, blank=True,
null=True)
def __str__(self):
return self.article.title
views.py
class ArticleMixinView(generics.GenericAPIView,
mixins.ListModelMixin,
mixins.CreateModelMixin,
...)
serializer_class = ArticleSerializer
queryset = Article.objects.all()
lookup_field = 'id'
def post(self, request):
print(request.data)
new_article = Article.objects.create(title=request.data.get('title'),
text=request.data.get('text'))
new_article.save()
for img in request.data.get('images'):
# article_img = ArticleImage(article=new_article,img=File(img),
# is_main=False )
# article_img.save()
return Response({
'article': ArticleSerializer(new_article,
context=self.get_serializer_context()).data
})
Создание объекта Article работает нормально, но у меня возникли некоторые проблемы с этим массивом. Что не так, или как я могу получить изображения из объектов InMemoryUploadedFile????
Пожалуйста, любая помощь. Спасибо за пересылку)
Ответ №1:
Я думаю, что вы отправляете images
в виде массива из своего интерфейса. Вы можете отформатировать их немного лучше, чтобы каждый объект массива соответствовал вашей ArticleImage
модели. Например, каждый объект images
ключа должен иметь файл, соответствующий img
ключу (потому что это имя вашего поля в модели):
<QueryDict:
{'title': ['testTitle'],
'text': ['testText'],
'images': [{'img': <InMemoryUploadedFile: 486217.jpg (image/jpeg)>},
{'img': <InMemoryUploadedFile: 344611.jpg (image/jpeg)>}]
}>
Теперь вы можете использовать ModelSerializer
with many=True
, чтобы выполнить эту работу за вас.
Например, создайте сериализатор для ArticleImage
модели:
class ArticleImageSerializer(serializers.ModelSerializer):
class Meta:
model = ArticleImage
fields = ('article', 'img', 'is_main', 'create_time')
read_only_fields = ('article', 'is_main', 'create_time') # so that only `img` field comes from input
Теперь используйте это для сохранения ваших изображений в вашей модели:
def post(self, request):
print(request.data)
images = request.data.pop('images')
serializer = self.get_serializer_class(data=request.data) # why not use ArticleSerializer?
serializer.is_valid(raise_exception=True) # this lets you validate if something is wrong with user's input
new_article = serializer.save() # similar to Article.objects.create
images_serializer = ArticleImageSerializer(data=images, many=True) # only `img` comes from data
images_serializer.is_valid(raise_exception=True)
images_serializer.save(article=new_article, is_main=False) # adding additional fileds
return Response(serializer.data)
Этот код не тестировался, дайте мне знать, если что-то не работает должным образом. Надеюсь, это поможет.
Комментарии:
1. Я думаю, что я делаю что-то неправильно в своем методе создания FormData let data = new FormData(); const {imgList}=this.state; data.append(‘title’, event.target.elements.title.value,); data.append(‘text’,event.target.elements.content.value,); imgList.forEach(i =>{ data.append (‘images []’, i); }) Это нормально?