2

I have tried to upload multiple image using react-dropzone and tastypie.I am not able to store the images to the server using tastypie.The files are shown on console and also on django console the name of file is shown.

Models.py

class Rental(models.Model):
    """
    Rents
    """
    ownerName = models.CharField(_("Owner's Name"),max_length=255, blank=True, null = True,
        help_text=_("Owner's Full Name"))
    email = models.CharField(max_length=120,blank=True, null=True)
    phoneNumber = models.PositiveIntegerField(blank=False,null=True,
        help_text=_("Phone number of contact person"))
    listingName =  models.CharField(_("Lisitng Name"), max_length=255, blank=False, null=True,
        help_text=_("Title of the rental space"))
    summary = models.TextField(max_length=500, blank=True, null= True,
        help_text=_("Description of the rental space"))
    property = models.CharField(_("Property type"),max_length=10,null=True)
    room = models.PositiveIntegerField(_("No of Rooms"), blank=False, null=True,
        help_text=_("Number of bedrooms available"))
    price = models.PositiveIntegerField(blank=False,null=True,
        help_text=_("Rental price of the space per month"))
    city =  models.CharField(_("City"), max_length=255, blank=False, null=True,
        help_text=_("City of the rental space"))
    place =  models.CharField(_("Place"), max_length=255, blank=False, null=True,
        help_text=_("Place of the rental space"))
    water = models.CharField(_("water facilities"),max_length=50,null=True,
        help_text=_("Is there water facility?"))
    amenities = models.CharField(_("amenities"),max_length=100,null=True)
    phone_image = models.CharField(max_length=2048,blank=True,null=True,
        help_text=_("image form of the phone number"))
    image = models.FileField(upload_to='/media/')


    def save(self, *args, **kwargs):
        if self.phoneNumber:
            print(self.phoneNumber)
            font = ImageFont.truetype(settings.PHONE_FONT,14)
            phone_image=Image.new("RGBA", (120,16),(255, 255, 255))
            draw = ImageDraw.Draw(phone_image) 
            draw.text((0, 0), self.phoneNumber, (0,0,0), font=font)

            byte_stream = BytesIO()
            phone_image.save(byte_stream, format="png")
            byte_stream.seek(0)

            self.phone_image = base64.b64encode(byte_stream.read()).decode()
        return super(Rental,self).save( *args, **kwargs)

    def __str__(self):
        return self.listingName

    class Meta:
        verbose_name = _("Rent")
        verbose_name_plural = _("Rents")

Api.py

class MultipartResource(object):
    def deserialize(self, request, data, format=None):
        if not format:
            format = request.META.get('CONTENT_TYPE', 'application/json')

        if format == 'application/x-www-form-urlencoded':
            return request.POST

        if format.startswith('multipart'):
            data = request.POST.copy()
            data.update(request.FILES)
            print('data is',data)
            return data

    def put_detail(self, request, **kwargs):
        if request.META.get('CONTENT_TYPE').startswith('multipart') and \
                not hasattr(request, '_body'):
            request._body = ''


        return super(MultipartResource, self).deserialize(request, data, format)



class RentalResource(MultipartResource,ModelResource):
    class Meta:
        queryset = Rental.objects.all()
        resource_name = 'rental'
        allowed_methods = ['get', 'post']
        fields = ['listingName','property','city','place','ownerName','room','water','amenities','price','summary','phoneNumber','email','image']
        filtering = { "property" : ALL , "room":ALL,"price":ALL}
        # authentication = BasicAuthentication()
        authorization = DjangoAuthorization()

Listing.js

var RenderPhotos = React.createClass({
    getInitialState: function () {
        return {
          files:[]
        };
    },

    onDrop(files) {
        console.log('Received files: ', files);
    this.setState({
        files: files
    });
    },

    showFiles() {
        const files = this.state.files || null;
        console.log('files',files);

        if (!files.length) {
            return null;
        }

        return (
            <div>
                <h3>Dropped files: </h3>
                <ul className="gallery">
                    {
                        files.map((file, idx) => {
                            return (
                                <li className="col-md-3" key={idx}>
                                    <img src={file.preview} width={100}/>
                                    <div>{file.name}</div>
                                </li>
                            );
                        })
                    }
                </ul>
            </div>
        );
    },

    render: function () {
      return (
           <div>
                <h3>Photos can bring your space to life</h3>
                <p>Add photos of spaces to give more insight of your space </p>
                <hr/>
                <div className="col-md-12">
                <form method="post" encType="multipart/form-data">
                  <Dropzone onDrop={this.onDrop}
                          style={style}
                          activeStyle={activeStyle}>
                    Try dropping some files here, or click to select files to upload.
                </Dropzone>
                </form>
                {this.showFiles()}
                </div>
                <div className="row continueBtn text-right">
                    <button className="btn how-it-works pull-left" onClick={this.props.previousStep}>Back</button>
                    <button className="btn how-it-works" onClick={this.submitRent}>Next</button>
                </div>
          </div>
      );
    },

        submitRent: function(e) {
          var req = request.post('http://localhost:8000/api/v1/rental/');
          var image = [];
          image = new FormData();
          var that = this;
          var index;
          for (index = 0; index < that.state.files.length; ++index) {
              console.log(that.state.files[index]);
              image.append('files',that.state.files[index]);
          }
          req.send(image);
          console.log('req is',req);
          req.end((err, res) => {
            if (err) {
              console.log('error', err);
            } else {
              console.log('success', res);

            }
          });


    }

});

What have i done wrong? Why image is not stored on the server? Please enlighten me on this issue.

Django Console where i get the dropped images

pri
  • 620
  • 2
  • 9
  • 20

1 Answers1

1

Your problem is here:

data.update(request.FILES)
print('data is',data)
return data

this adds 'file': <InMemoryUploadedFile> to your bundle. Your model however doesn't define 'file' anywhere. It defines 'image' (which is your file). So what you need to to is:

data['image'] = request.FILES['file]
return data
Remi Smirra
  • 2,499
  • 1
  • 14
  • 15
  • Only one image is sent instead of multiples.Why is that so ? – pri Jan 13 '16 at 10:46
  • I found out that request.FILES['files'] returns only the last data value it finds for that key. When i try to iterate request.FILES.getlist('files') i get an error of MultiValueDict object is not callable. – pri Jan 14 '16 at 05:06