我尝试使用react-dropzone和tastypie上传多个图像。我无法使用tastypie将图像存储到服务器。文件显示在控制台上,同时在django控制台上显示文件名。< / p>
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);
}
});
}
});
我做错了什么?为什么图像不存储在服务器上?请在这个问题上赐教。
答案 0 :(得分:1)
你的问题在这里:
data.update(request.FILES)
print('data is',data)
return data
这会将'file': <InMemoryUploadedFile>
添加到您的捆绑包中。
但是,您的模型并未在任何位置定义“文件”。它定义了'image'(这是你的文件)。
所以你需要做的是:
data['image'] = request.FILES['file]
return data