I am trying to upload image with android as frontend and django as backend.
The model:
class Photo(models.Model):
title = models.CharField(max_length=255,blank=True)
photo = models.FileField(upload_to='photos')
description = models.TextField(blank=True)
uploaded = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'media_photos'
def __unicode__(self):
return '%s' % self.title
The view to url url(r'^photos/upload/$','upload_photo'):
def upload_photo(request):
form=PhotoForm(request.POST,request.FILES)
if request.method=='POST':
if form.is_valid():
image = request.FILES['photo']
title1 =''
new_image = Photo(title=title1,photo=image,description='')
new_image.save()
response_data=[{"success": "1"}]
return HttpResponse(simplejson.dumps(response_data), mimetype='application/json')
now i am trying to access the view here from android. So now my android side code to upload image is:
public void doFileUpload(String path){
HttpURLConnection conn = null;
DataOutputStream dos = null;
DataInputStream inStream = null;
String lineEnd = "\r\n";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1*1024*1024;
String urlString = "http://"; // server ip
try
{
//------------------ CLIENT REQUEST
FileInputStream fileInputStream = new FileInputStream(new File(path) );
// open a URL connection to the Servlet
URL url = new URL(urlString);
// Open a HTTP connection to the URL
conn = (HttpURLConnection) url.openConnection();
// Allow Inputs
conn.setDoInput(true);
// Allow Outputs
conn.setDoOutput(true);
// Don't use a cached copy.
conn.setUseCaches(false);
// Use a post method.
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary="+" ");
dos = new DataOutputStream( conn.getOutputStream() );
dos.writeBytes(lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" + path + "\"" + lineEnd);
dos.writeBytes(lineEnd);
// create a buffer of maximum size
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// read file and write it into form...
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0)
{
dos.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
// send multipart form data necesssary after file data...
dos.writeBytes(lineEnd);
dos.writeBytes(lineEnd);
// close streams
Log.e("Debug","File is written");
fileInputStream.close();
dos.flush();
dos.close();
}
catch (MalformedURLException ex)
{
Log.e("Debug", "error: " + ex.getMessage(), ex);
}
catch (IOException ioe)
{
Log.e("Debug", "error: " + ioe.getMessage(), ioe);
}
//------------------ read the SERVER RESPONSE
try {
inStream = new DataInputStream ( conn.getInputStream() );
String str;
while (( str = inStream.readLine()) != null)
{
Log.e("Debug","Server Response "+str);
}
inStream.close();
}
catch (IOException ioex){
Log.e("Debug", "error: " + ioex.getMessage(), ioex);
}
}
}
but it gives me an error:
E/Debug(590): error: java.net.URISyntaxException: Authority expected at index 7: http://
Should be urlString = "http://192.168.1.2/photos/upload";
But then if it doesn't work, you'll get a different error, and we'll probably need that error to answer further.
Also, it looks like you don't have a real boundary string set and you aren't using it correctly.
Have a look here. Notice how he uses a unique boundary string and writes it to the output stream?
Even after you overcome these difficulties, you'll run afoul of Django's requirement that you supply a csrfmiddlewaretoken with your POST parameters. And I don't see how you can obtain that on an Android device; by design that token is there to prevent calling Django backend code (i.e. a "view") from anything other than a Django frontend (i.e. a "template"). I.e. it's designed to thwart doing exactly what you're trying to do.
You could disable the csrf feature on a particular view -- use the "@csrf_exempt" decorator. And then you can decide if you care enough about security, to work out a substitute of your own for what the csrf thing gives you.
Or, instead of uploading a picture from an Android app, write a web app to upload a picture, and have your Django project serve up that web app. Your Android app could launch the browser (as an Intent) and point it at that web app. Here's some code that'll do that: https://simpleisbetterthancomplex.com/tutorial/2016/08/01/how-to-upload-files-with-django.html (It won't win any beauty contests, but it does work.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With