naritoブログ

【お知らせ】
・コメントで質問等をしたが返事が返ってこない場合、私はそれを見落としています。
その場合は再度コメントをするかメールをしてください(toritoritorina@gmail.com)。

・近いうちに新しいブログが作成されます。わーお!

Python、requestsを使ったアップロード

約916日前 2016年3月21日15:39
プログラミング関連
Requests Python
requestsを使ったアップロードの例です


このように、非常に簡単に行えます
import requests

url = "http://test.com/api/image/"
files = {'upload_file': open("test.png", "rb")}
res = requests.post(url, files=files)



例えば、これをDjangoで受け取りたい場合は以下のようになります
非常にシンプルな例です
from django.http import HttpResponse
from django.views.decorators.http import require_POST
from django.views.decorators.csrf import csrf_exempt
from .models import Photo


@require_POST
@csrf_exempt
def receive_image(request):
    upload_file = request.FILES["upload_file"]
    photo = Photo(title="タイトル", image=upload_file)
    photo.save()
    download_url = "http://test.com/media/" + photo.image.name
    return HttpResponse(download_url, content_type="text/plain")



このデコレータをつけると、CSRF 対策のチェックが無効化されます
具体的には、{% csrf_token %}がなくても動くようになります
外部に公開したい場合やajax等で、やむを得ず使用することがあります
@csrf_exempt


今回はタイトルと画像の2つだけを持つ、Photoモデルを使用しました
upload_file = request.FILES["upload_file"]
image_data = Photo(title="タイトル", image=upload_file)
image_data.save()


ダウンロード用のURLを作成し、それをHttpResponseで返しています。単純にtext/plainです
requestsだと、response.textで画像URLがわかるようになります
download_url = "http://test.com/media/" + photo.image.name
return HttpResponse(download_url, content_type="text/plain")


url部分は、いくつか作成方法があります。
from urllib import parse
...
...
parse_url = parse.urlparse(request.build_absolute_uri())
parse_url = parse_url._replace(path=photo.image.url)
url = parse.urlunparse(parse_url)
return HttpResponse(url, content_type="text/plain")



from django.contrib.sites.shortcuts import get_current_site
...
...
current_site = get_current_site(request)
domain = current_site.domain
download_url = '{0}://{1}{2}'.format(
    'https' if request.is_secure() else 'http',
    domain,
    photo.image.url,
)


参考
http://docs.python-requests.org/en/master/user/quickstart/
名無し 約37日前 2018年8月17日11:41 返信する
Lineのでアイコン画像を設定するときなどに、所定のサイズに切り取ったり縮小したりして扱いやすくする機能がありますが、あのような機能をDjangoで実装するにはどうすれば良いでしょうか?
何か特別なライブラリを使わなければ難しいでしょうか?
なりと 約37日前 2018年8月17日21:44
django関連のライブラリである「sorl-thumbnail 」が使えるかもしれません。
https://sorl-thumbnail.readthedocs.io/en/latest/examples.html をご覧ください。
名無し 約35日前 2018年8月19日13:24 返信する
教えていただいたsorl-thumbnailを使い、このようなsignalを利用して、新規登録や画像変更の際には画像をリサイズできるようにしたのですが、予想外の不具合が起こってしまいました。
今まではサーバーにアップロードされた画像は.JPEG形式になっていたのですが、今回の変更を加えた後は、何の拡張子もついていないただの「ファイル」としてアップロードされています。
今のところ不具合は起こっていないのですが、予想と違う挙動は好ましいことではないので修正したいと考えています。なにか解決策はあるでしょうか?
@receiver(signals.pre_save, sender=User)
def auto_resize_image_on_save(sender, instance, **kwargs):
if instance.image.width != 840:
width = instance.image.width
height = instance.image.height

range_img = 840 / width
height = int(height * range_img)
scale = "{}x{}".format(840, height)

resized = get_thumbnail(instance.image, scale, crop='center', quality=99, format='JPEG')
instance.image.save(resized.name, ContentFile(resized.read()), True)
else:
pass
なりと 約34日前 2018年8月20日23:00
@receiver(signals.post_save, sender=Hello)
post_saveにするとどうでしょうか。