I have a Vue front end that collects data (and files) from a user and POST it to a Django Rest Framework end point using Axios.
Here is the code for that function:
import { ref } from "vue";
import axios from "axios";
const fields = ref({
audience: "",
cancomment: "",
category: "",
body: "",
errors: [],
previews: [],
images: [],
video: [],
user: user,
});
function submitPost() {
const formData = {
'category': fields.value.category.index,
'body': fields.value.body,
'can_view': fields.value.audience,
'can_comment': fields.value.cancomment,
'video': fields.value.video,
'uploaded_images': fields.value.images,
'user': store.userId
};
console.log(formData['uploaded_images'])
axios
.post('api/v1/posts/create/', formData, {
headers: {
"Content-Type": "multipart/form-data",
"X-CSRFToken": "{{csrf-token}}"
}
})
.then((response) => {
if(response.status == 201){
store.messages.push("Post created successfully")
}
})
.catch((error) => {
messages.value.items.push(error.message)
})
}
When I post data the response I see on the server side is:
uploaded_data = validated_data.pop('uploaded_images')
KeyError: 'uploaded_images'
that comes from this serializer:
class PostImageSerializer(serializers.ModelSerializer):
class Meta:
model = PostImage
fields = ['image', 'post']
class PostSerializer(serializers.ModelSerializer):
images = PostImageSerializer(many=True, read_only=True, required=False)
uploaded_images = serializers.ListField(required=False, child=serializers.FileField(max_length=1000000, allow_empty_file=False, use_url=False),write_only=True)
class Meta:
model = Post
fields = [
"category",
"body",
"images",
"uploaded_images",
"video",
"can_view",
"can_comment",
"user",
"published",
"pinned",
"created_at",
"updated_at",
]
def create(self, validated_data):
uploaded_data = validated_data.pop('uploaded_images')
new_post = Post.objects.create(**validated_data)
try:
for uploaded_item in uploaded_data:
PostImage.objects.create(post = new_post, images = uploaded_item)
except:
PostImage.objects.create(post=new_post)
return new_post
Trying to make sense of this so am I correct in my thinking that DRF saves the serializer when the data is sent to the endpoint? The variable validated_data I presume is the request.data object? Why am I getting the KeyError then and how can I see what the data is that is being validated, or sent in the post request on the server side. The data sent in the post request in the browser looks like this:
-----------------------------2091287168172869498837072731
Content-Disposition: form-data; name="body"
Post
-----------------------------2091287168172869498837072731
Content-Disposition: form-data; name="can_view"
Everybody
-----------------------------2091287168172869498837072731
Content-Disposition: form-data; name="can_comment"
Everybody
-----------------------------2091287168172869498837072731
Content-Disposition: form-data; name="uploaded_images.0"; filename="tumblr_42e2ad7e187aaa1b4c6f4f7e698d03f2_c9a2b230_640.jpg"
Content-Type: image/jpeg
-----------------------------2091287168172869498837072731
Content-Disposition: form-data; name="body"
Post
-----------------------------2091287168172869498837072731
Content-Disposition: form-data; name="can_view"
Everybody
-----------------------------2091287168172869498837072731
Content-Disposition: form-data; name="can_comment"
Everybody
-----------------------------2091287168172869498837072731
Content-Disposition: form-data; name="uploaded_images.0"; filename="tumblr_42e2ad7e187aaa1b4c6f4f7e698d03f2_c9a2b230_640.jpg"
Content-Type: image/jpeg
(¼T¼Þ7ó[®«ý;>7гô
eIqegy[XbkéÉc¤ÎSFÌÔÂåÄAR§*P!I<R,4AP9ÖgÅÖYÔ×éu«ÅÉ<IJª+`,.uòÜtK7xéu.Ô¬]{ù£æÍ÷·n²±×:îã¡`UÐKxªyjxñDUAP¢+ÄÅB1yõçùuS5å
D÷ zö4®n¦Öod&<z¼P
W9©xeúD5ÈMpÖö¬ðÓKÊľO«oµÊMçÇy|z=^<AKêôz¼x##:ù;«OdÞ¢¶WRùººRêÜêú8ø¡ãÄ"¼AãÅj¿3ÆõÙRÆ]_MTÆ^;;
`ttR}mì¤*bêwy¾=d<xòøòxÄ(
Here is the ViewSet that sits at the endpoint:
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
filter_backends = [django_filters.rest_framework.DjangoFilterBackend, filters.SearchFilter, django_filters.rest_framework.OrderingFilter]
# filterset_class = PostFilter
ordering_fields = ['created_at',]
search_fields = ['category', 'body']
permission_classes = [permissions.IsAuthenticated]
def get_serializer_context(self):
return {'request': self.request}
parser_classes = [MultiPartParser, FormParser]
lookup_field = 'slug'