Я создаю CreateAPIView с Django Rest Framework и вызываю его с ajax. Я хочу загрузить несколько изображений с сообщением, но могу загрузить только 1 изображение.
Это моя модель:
class Post(models.Model):
user = models.ForeignKey(User, related_name='posts',
on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now=True)
message = models.TextField(blank=True)
message_html = models.TextField(editable=False)
group = models.ForeignKey(
Group, related_name='posts', null=True, blank=True, on_delete=models.CASCADE)
liked = models.ManyToManyField(
settings.AUTH_USER_MODEL, blank=True, related_name='post_liked')
updated = models.DateTimeField(auto_now=True, blank=True)
destination = models.ForeignKey(
Destination, on_delete=models.CASCADE, blank=True, null=True)
type = models.CharField(choices=CATEGORY, max_length=100, default='Public')
objects = PostManager()
def __str__(self):
return self.user.username
....
class PostImage(models.Model):
post = models.ForeignKey(
Post, on_delete=models.CASCADE, default=None, related_name='post_images')
image = models.FileField(upload_to='post-files', blank=True)
def __str__(self):
return self.post.message
Это мой сериализатор:
class PostImageModelSerializer(serializers.ModelSerializer):
class Meta:
model = PostImage
fields = '__all__'
class PostModelSerializer(serializers.ModelSerializer):
def __init__(self, *args, **kwargs):
file_fields = kwargs.pop('file_fields', None)
super().__init__(*args, **kwargs)
if file_fields:
field_update_dict = {field: serializers.FileField(
required=False, write_only=True) for field in file_fields}
self.fields.update(**field_update_dict)
def create(self, validated_data):
validated_data_copy = validated_data.copy()
validated_files = []
for key, value in validated_data_copy.items():
if isinstance(value, InMemoryUploadedFile):
validated_files.append(value)
validated_data.pop(key)
post_instance = super().create(validated_data)
print(validated_files)
for file in validated_files:
PostImage.objects.create(
post=post_instance, image=file)
return post_instance
user = UserDisplaySerializer(read_only=True)
post_images = PostImageModelSerializer(many=True, read_only=True)
timesince = serializers.SerializerMethodField()
destination = DestinationDisplaySerializer(read_only=True)
did_like = serializers.SerializerMethodField()
liked = serializers.SerializerMethodField()
class Meta:
model = Post
fields = ['id', 'user', 'message', 'type',
'destination', 'timesince', 'did_like', 'liked', 'post_images']
....
Это мой API:
class PostsCreateApiView(generics.CreateAPIView):
queryset = Post.objects.all()
serializer_class = PostModelSerializer
def create(self, request, *args, **kwargs):
file_fields = list(request.FILES.keys())
serializer = self.get_serializer(
data=request.data, file_fields=file_fields)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
def perform_create(self, serializer):
serializer.save(user=self.request.user)
и мой ajax вызов:
$('#postForm').on('submit', function (e) {
e.preventDefault();
var form = $(this);
var formdata = false;
if (window.FormData) {
formdata = new FormData(form[0]);
}
if (charsCurrent > 0 && charsCurrent <= charsTotal) {
$.ajax({
url: "/api/posts/create/",
data: formdata ? formdata : form.serialize(),
method: "POST",
processData: false,
contentType: false,
success: function (data) {
fetchPosts();
form.find("input[type=text], textarea").val("");
$('#inputLaunchToPOST').modal('hide');
attachPost(data, true);
// updateHashLinks();
},
error: function (data) {
console.log("error");
console.log(data.statusText);
console.log(data.status);
},
});
}
});
Этот код получает только одно изображение, в то время как я проверяю его на 2 или 3 изображения для один пост. Я думаю, что-то с «InMemoryUploadedFile» я использовал в своем сериализаторе.