Reputation: 59
I can use json format to upload images with Base64ImageField (by POST), but now I want to download images in the same way (by POST). When I POST a image to "driver_photo", for example:
"R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
,the image would save as "driver_photo":"driver_photos/2016/05/20/d2821170-662.gif". My question is how could I open the file , encode it for convenient transmition by Base64ImageField and POST them.
Below is my serializer.py
class PassengerDataSerializer(serializers.ModelSerializer):
passenger_photo = Base64ImageField(
max_length=None, use_url=True,
)
class Meta:
model = PassengerData
fields = ("passenger_name","passenger_phone", "passenger_photo")
class TaxiDriverDataSerializer(serializers.ModelSerializer):
PassengerDatas = PassengerDataSerializer( many=True )
driver_photo = Base64ImageField(
max_length=None, use_url=True,
)
class Meta:
model = TaxiDriverData
fields = ("pk","fingerprint","driver_name","driver_photo","PassengerDatas")
def create(self, validated_data):
taxiDriverData = TaxiDriverData.objects.create(fingerprint = validated_data['fingerprint'],
driver_name = validated_data['driver_name'],
driver_photo = validated_data['driver_photo'],
)
taxiDriverData.save()
Passenger_Datas = validated_data.pop('PassengerDatas')
for passenger in Passenger_Datas:
passengerdata = PassengerData.objects.create(passenger_name = passenger.get('passenger_name'),
passenger_phone = passenger.get('passenger_phone'),
passenger_photo = passenger.get('passenger_photo'), )
passengerdata.taxi_driver_data_id = taxiDriverData
passengerdata.save()
return taxiDriverData
def update(self, instance, validated_data):
instance.fingerprint = validated_data['fingerprint']
instance.driver_name = validated_data['driver_name']
instance.driver_photo = validated_data['driver_photo']
instance.save()
return instance
views.py
@api_view(['GET','POST'])
def taxi_driver_list(request, format=None):
if request.method=="GET":
TaxiDriverDatas =list(TaxiDriverData.objects.all())
serializer = TaxiDriverDataSerializer(TaxiDriverDatas,many=True)
return Response(serializer.data)
elif request.method == 'POST':
#print (request.body)
serializer = TaxiDriverDataSerializer(data=request.data)
#, files=request.FILES
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@api_view(['GET', 'PUT', 'DELETE'])
def taxi_driver_detial(request,pk, format=None):
try:
Taxi_Driver_Data = TaxiDriverData.objects.get(pk=pk)
except TaxiDriverData.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
if request.method == "GET":
serializer = TaxiDriverDataSerializer(Taxi_Driver_Data)
return Response(serializer.data)
elif request.method == "PUT":
serializer = TaxiDriverDataSerializer(Taxi_Driver_Data,data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
else:
return Response(serializer.errors,status=status.HTTP_400_BAD_REQUEST)
elif request.method == "DELETE":
Taxi_Driver_Data.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
models.py
class TaxiDriverData(models.Model):
fingerprint = models.CharField(max_length=30, default="")
driver_name = models.CharField(max_length=30, default="")
driver_photo = models.ImageField(upload_to ="driver_photos/%Y/%m/%d/", null=True ,blank=True)
class PassengerData(models.Model):
taxi_driver_data_id = models.ForeignKey(TaxiDriverData, related_name='PassengerDatas', null=True)
passenger_name = models.CharField(max_length=100, default="")
passenger_phone = models.CharField(validators=[phone_regex], blank=True, max_length=16)
passenger_photo = models.ImageField(upload_to ="passenger_photos/%Y/%m/%d/", null=True ,blank=True )
Thanks for help.
Upvotes: 1
Views: 784
Reputation: 4547
It is highly recommended to use POST
instead of GET
to send/receive Base64
images, since Base64
images are converted to String
with length of string varying upto 15000 characters. If you are using the GET method, you are limited to a maximum of 2,048 characters.
Save the image
import base64
imgdata = base64.b64decode(imgstring)
filename = 'some_image.jpg' # I assume you have a way of picking unique filenames
with open(filename, 'wb') as f:
f.write(imgdata)
Edit1 You could do something like this to save the image
import base64
import datetime
def save_image(request):
b64_image = request.POST['driver_photo'] #key that is being used to send the data
imgdata = base64.b64decode(b64_image)
var = datetime.datetime.now().strftime("%d%m%Y%H%M%S") #This will give unique values everytime. Values are based on current datetime
filename = "PATH_TO_SAVE_FILE" + var +'.jpg'
with open(filename, 'wb') as f:
f.write(imgdata)
Edit 2
POST Request in Android
HttpClient httpclient = new DefaultHttpClient();
String responseStr="";
String URL=Constants.API_URL;#URL where request needs to be sent
HttpPost httppost = new HttpPost(URL);
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("id", pick_up_id));
nameValuePairs.add(new BasicNameValuePair("driver_photo", strPhoto));#image in form of Base64 String which you need to send
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
int responseCode = response.getStatusLine().getStatusCode();
switch(responseCode) {
case 200:
HttpEntity entity = response.getEntity();
if(entity != null) {
String responseBody = EntityUtils.toString(entity);
responseStr=responseBody;
}
break;
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
}
System.out.println("this is response "+responseStr);
Upvotes: 1