8

I am trying to get a file upload system working in Django Rest Framework.

The files I want to upload are .gpx files which are custom xml files. I don't want to store the files in the database, instead I want to extract information from them and then input this into my model.

I have a function that takes a temp file and then extracts the info and then creates the model elements as needed. What I'm looking to do is perform some checks on the file before it is uploaded and passed to this function.

How should I do this?

The file upload is currently done as in the documentation (see below), which a generic APIView and a put command. This works perfectly, I just want to know what the best way is to check this file's validity before upload.

views.py

class FileUploadView(views.APIView):
    parser_classes = (FileUploadParser, )

    def put(self, request, filename, format=None):
        up_file = request.data['file']

        SaveGPXtoModel(up_file, request.user)

        return Response(status=204)

Should the API do these checks or should it assume the file has already been validated?

In Django these checks would be handled by the form, should I use a serializer to do these checks?

If a serializer is the way to go then does it matter that there is one file as an input and various data points as an output?

Håken Lid
  • 22,318
  • 9
  • 52
  • 67
Domronic
  • 149
  • 1
  • 1
  • 11

1 Answers1

14

You can start by writing a serializer for your file, it doesn't have to be linked to a model:

class FileSerializer(serializers.Serializer):
    file = serializers.FileField()

But fileField doesn't do any specific check. Depending on what you need to check, add a custom validator and use :

class FileSerializer(serializers.Serializer):
    file = serializers.FileField(validators=[validate_file])

There is a nice example of how you could write a class based file validator here

Then use your serializer in your view :

class FileUploadView(APIView):
    parser_classes = (MultiPartParser, )

    def post(self, request):
        serializer = FileSerializer(data=request.data)
        if not serializer.is_valid():
            return Response(
                data=serializer.errors,
                status=status.HTTP_400_BAD_REQUEST
            )
        ...
Duf59
  • 500
  • 6
  • 16