1

Here are my code for file uploading to s3. for now i am saving it in local

class UploadedImage(models.Model):
    image = models.ImageField("Uploaded image", upload_to=scramble_uploaded_filename)
    thumbnail = models.ImageField("Thumbnail of uploaded image", blank=True)
    title = models.CharField("Title of the uploaded image", max_length=255, default="Unknown Picture")
    description = models.TextField("Description of the uploaded image", default="")
    def __str__(self):
        return self.title
    def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
        self.thumbnail = create_thumbnail(self.image)
        super(UploadedImage, self).save(force_update=force_update)

below is my serializers

class UploadedImageSerializer(serializers.ModelSerializer):
    class Meta:
        model = UploadedImage
        fields = ('pk', 'image', 'thumbnail', 'title', 'description', )
        read_only_fields = ('thumbnail',)

and views

class UploadedImagesViewSet(viewsets.ModelViewSet):
    queryset = UploadedImage.objects.all()
    serializer_class = UploadedImageSerializer

this is working fine but i am getting error while integration api in angular 6.

below code for angular 6 ts and html

import { Component, OnInit } from '@angular/core';
import { HttpClient, HttpHeaders} from '@angular/common/http';
import { Router } from '@angular/router';
import { ViewChild } from '@angular/core';
@Component({
  selector: 'app-photo-upload',
  templateUrl: './photo-upload.component.html',
  styleUrls: ['./photo-upload.component.css']
})
export class PhotoUploadComponent implements OnInit {
  @ViewChild("fileInput") fileInput;
  constructor(private http: HttpClient ,private router: Router) { }
  ngOnInit() {
  }


  url: string | ArrayBuffer;
  onSelectFile(event) { // called each time file input changes
    if (event.target.files && event.target.files.length>0) {
      console.log(event.target.files[0]);
      var reader = new FileReader();

      reader.readAsDataURL(event.target.files[0]); // read file as data url

      reader.onload = () => { // called once readAsDataURL is completed
        this.url = reader.result;
        console.log(this.url);


      }
    }

  }
  photoupload(f){
    this.onSelectFile(event)
    f.value.images=this.url
    console.log(f.value)

    const header = new HttpHeaders({'Content-Type': 'application/json'});
    this.http.post('http://11.111.11.111:8000/api/images/',
      f.value,{headers:header}).subscribe(( data )  =>  
        { console.log(data)   
        this.router.navigate(['../dashboard']);
         }
        ,error => {console.log(error);
        })
  }
}

hmtl file

<form (ngSubmit)="photoupload(list)" #list="ngForm" >
    <div class="container">
        <label for="title"><b>Photo Title</b></label>
        <input type="text" name="title" placeholder="Enter Title" value="title" id="title" [(ngModel)]= "title"  required >
        <label for="discription"><b>Photo Description</b></label><br>
        <input type="text" placeholder="Enter Description" name="discription"  [(ngModel)]= "discription" required>
        <label for="image"><b>Image </b></label> &nbsp;
        <input type="file" name="image"  (change)="onSelectFile($event)" required ><br>
      <button  type="submit">Upload Photo </button>
    </div>
    <div class="container" style="background-color:#f1f1f1">
    </div>
  </form>

now my problem is that my api is working in postman but i m not able to integrate it on angular 6 i this this is issue related with angular base 64 image ?? but i m able to generate URL also all i can't do is post this data to back-end from frond-end

error image problem image

1 Answers1

0

You are sending Base64 data to the backend while calling your API endpoint using Angular6 frontend. In this case, you have to update your Serializer and implementing such functionality so it can take Base64 data and generate an image file to save on server.

Update your UploadedImageSerializer as given below

from rest_framework import serializers

class Base64ImageField(serializers.ImageField):
"""
A Django REST framework field for handling image-uploads through raw post data.
It uses base64 for encoding and decoding the contents of the file.

Heavily based on
https://github.com/tomchristie/django-rest-framework/pull/1268

Updated for Django REST framework 3.
"""

    def to_internal_value(self, data):
        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:
            file_extension = self.get_file_extension(file_name, decoded_file)

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

            data = ContentFile(decoded_file, name=complete_file_name)

        return super(Base64ImageField, self).to_internal_value(data)

    def get_file_extension(self, file_name, decoded_file):
        import imghdr

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

        return extension

class UploadedImageSerializer(serializers.ModelSerializer):
    image = Base64ImageField(
        max_length=None, use_url=True,
    )

    class Meta:
        model = UploadedImage
        fields = ('pk', 'image', 'thumbnail', 'title', 'description', )
        read_only_fields = ('thumbnail',)

NOTE: Your Thumbnail field may cause a problem here. I will Update this answers soon.

For More Information Please refer Original Post

Rahul Soni
  • 36
  • 2
  • 10