1

I am using Angular and Bootstrap to serve my forms. If a user uploads an image, Angular serves it in the "data:" format, but Django is looking for a file type. I have fixed this issue by overriding both perform_authentication (To modify the image to a file) and perform_create (to inject my user_id). Is there a better way to override?

I'd rather not override my view. I'd rather override the way Django validates ImageFields. What I want to do is check if the passed value is a 64-bit string, if it is, modify it to a file type, then validate the ImageField. The below code works as is, I just don't feel is optimal.

Here is my view:

class UserCredentialList(generics.ListCreateAPIView):
    permission_classes = (IsCredentialOwnerOrAdmin,)
    serializer_class = CredentialSerializer

    """
    This view should return a list of all the purchases
    for the currently authenticated user.
    """

    def get_queryset(self):
        """
        This view should return a list of all models by
        the maker passed in the URL
        """
        user = self.request.user
        return Credential.objects.filter(member=user)

    def perform_create(self, serializer):
        serializer.save(member_id=self.request.user.id)

    def perform_authentication(self, request):
        if request.method == 'POST':
            data = request.data.pop('document_image', None)

            from django.core.files.base import ContentFile
            import base64
            import six
            import uuid

            # Check if this is a base64 string
            if isinstance(data, six.string_types):
                # Check if the base64 string is in the "data:" format
                if 'data:' in data and ';base64,' in data:
                    # Break out the header from the base64 content
                    header, data = data.split(';base64,')

                # Try to decode the file. Return validation error if it fails.
                try:
                    decoded_file = base64.b64decode(data)
                except TypeError:
                    self.fail('invalid_image')

                # Generate file name:
                file_name = str(uuid.uuid4())[:12]  # 12 characters are more than enough.
                # Get the file name extension:
                import imghdr

                file_extension = imghdr.what(file_name, decoded_file)
                file_extension = "jpg" if file_extension == "jpeg" else file_extension

                complete_file_name = "%s.%s" % (file_name, file_extension,)

                data = ContentFile(decoded_file, name=complete_file_name)

                request.data['document_image'] = data
        request.user

And here is my serializer:

class CredentialSerializer(serializers.ModelSerializer):
    class Meta:
        model = Credential
        fields = (
            'id',
            'credential_type',
            'credential_number',
            'date_received',
            'is_verified',
            'date_verified',
            'document_image',
        )

And here is my model:

class Credential(models.Model):
    """Used to store various credentials for member validation."""
    document_image = models.ImageField(
        upload_to=get_upload_path(instance="instance",
                                  filename="filename.ext",
                                  path='images/credentials/'))

    PASSENGER = 'P'
    OWNER = 'O'
    CAPTAIN = 'C'
    CREDENTIAL_CHOICES = (
        (PASSENGER, 'Passenger'),
        (OWNER, 'Owner'),
        (CAPTAIN, 'Captain'),
    )

    credential_type = models.CharField(max_length=1,
                                       choices=CREDENTIAL_CHOICES,
                                       default=PASSENGER)
    credential_number = models.CharField(max_length=255)
    date_received = models.DateTimeField(auto_now_add=True)
    is_verified = models.BooleanField(default=False)
    date_verified = models.DateTimeField(blank=True, null=True)
    member = models.ForeignKey(settings.AUTH_USER_MODEL,
                                  related_name='credentials')

I used the below link to help me, now I just want to figure out how override the proper method Django REST Framework upload image: "The submitted data was not a file"

Well I've made one change since making: I have moved this function to my serializer and instead I now override the method: is_valid and that works as well. At least it's not in my view anymore.

Community
  • 1
  • 1
Diesel
  • 5,099
  • 7
  • 43
  • 81

0 Answers0