2016-01-13 48 views
2

我试图使用react-dropzone和tastypie上传多个图片。我无法使用tastypie将图像存储到服务器。这些文件显示在控制台上,也显示在django控制台上显示文件的名称。React Dropzone使用Tastypie上传多张图片

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); 

      } 
      }); 


    } 

}); 

我有什么错?为什么图像不存储在服务器上?请在这个问题上给我启发。

Django Console where i get the dropped images

+0

什么是你的'Rental'型号是什么样子? –

回答

1

你的问题是在这里:

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

这增加'file': <InMemoryUploadedFile>你的包。 然而,你的模型并没有在任何地方定义'文件'。它定义了'图像'(这是你的文件)。 所以你有什么需要的是:

data['image'] = request.FILES['file] 
return data 
+0

只发送一张图片而不是多张图片。那为什么? – pri

+0

我发现request.FILES ['files']只返回找到该键的最后一个数据值。当我尝试迭代request.FILES.getlist('文件')我得到一个错误的MultiValueDict对象不可调用。 – pri