鄔喬妤
鄔喬妤

Reputation: 59

Django: How can I download images from Base64ImageField?

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

Answers (1)

onkar
onkar

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

Related Questions