#はじめに
ご覧いただき誠にありがとうございます。
現在Djangoの画像を管理する仕組みを整えております。画像を一括でアップロードするという仕組みを整え、いざ本番環境に稼働させると動かない状態です。ですがDjangoのテストサーバーだと問題なく機能しているため、本当によくわからないエラーです。
仕組みとしては特定のURLにPOST、その後サーバー側のコードで画像をDBに保存する処理を行う形です。
(追記 バージョン情報)
本番サーバーOSはCentOS release 7.4.1708 (Core)
開発環境はMacOSCatalin10.15.1(19B88)
Apache=>2.4.6
Django=>2.1.5
Python=>3.6.7
#問題のソース
リクエストを受け取り、DBへ保存するView
views.py
from django.shortcuts import render,Http404 from django.http import HttpResponse from .models import ImageObjects from PIL import Image import json from django.core.files.uploadedfile import InMemoryUploadedFile from django.core.files.base import ContentFile from io import BytesIO # Create your views here. def endpoint(request): if request.method == "POST": #画像ファイル取得 for imgSrc in request.FILES.values(): newImage = ImageObjects() newImage.image = imgSrc newImage.save() return HttpResponse(200) else: # 何もしない raise Http404
保存先DBのmodel
models.py
from django.db import models from datetime import datetime from django.utils import timezone from PIL import Image from django.core.files.base import ContentFile from sorl.thumbnail import ImageField, get_thumbnail import os if os.environ.get('Production') != None: from mysite.settings import local as conf else: from mysite.settings import production as conf def delete_previous_file(function): def wrapper(*args, **kwargs): self = args[0] # 保存前のファイル名を取得 result = ImageObjects.objects.filter(pk=self.pk) previous = result[0] if len(result) else None super(ImageObjects, self).save() # 関数実行 result = function(*args, **kwargs) # 保存前のファイルがあったら削除 if previous: print(previous.image.name) os.remove(os.path.join(conf.MEDIA_ROOT,previous.image.name)) return result return wrapper # Create your models here. class Tag(models.Model): name = models.CharField('タグ名', max_length=30) def __str__(self): return self.name class ImageObjects(models.Model): image = models.ImageField( upload_to="media_uploads/", verbose_name="ファイル" ) date = models.DateTimeField(verbose_name="作成日時",default=timezone.now) tags = models.ManyToManyField(Tag, verbose_name='タグ', blank=True) def __str__(self): return self.image.name def save(self, *args, **kwargs): if not self.id: #大きい画像ならリサイズ super().save(*args, **kwargs) width = self.image.width height = self.image.height range_img = 600 / width height = int(height * range_img) scale = "{}x{}".format(600, height) resized = get_thumbnail( self.image, scale, crop='center', quality=99) self.image.save(resized.name, ContentFile(resized.read()), True) super().save(*args, **kwargs) @delete_previous_file def delete(self, using=None, keep_parents=False): super(ImageObjects, self).delete()
POSTするフロント側のコード
<form id="imageUploader" name="imageForm"> <input id="imageInput" type="file" enctype="multipart/form-data" name="file" multiple accept="image/*" capture="camera" onchange="uploadFile(event);" /> </form> <script> //POSTが終了したら画面更新をする。 function redirect() { window.location.reload(); }; //アップローダー function uploadFile(e) { e.preventDefault(); //CSRFtokenはDjangoのテンプレートエンジンで埋め込んでいる。 var csrf = '{{csrf_token}}'; var files = e.target.files; var xhr = new XMLHttpRequest(); var data = new FormData(); xhr.open('POST', '/api/image_post/'); xhr.setRequestHeader('X-CSRFToken',csrf); xhr.timeout = 2000; xhr.onload = redirect(); for (var i = 0; i < files.length; i++) { // ファイルをajaxでアップロード data.append(files[i].name, files[i]); // ファイル情報を送信データとして設定 } xhr.send(data); return 0; }; </script>
#確認した症状
①Apacheにて
mod_wsgi (pid=9761): Request data read error when proxying data to daemon process: Partial results are valid but processing is incomplete.(以降省略)
という文言がerrorログに出てくる。
アクセスログを見るとPOSTは成功したことになっている(200番を返した模様)
②Djangoテストサーバーを確認したら
Traceback (most recent call last): File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/socketserver.py", line 650, in process_request_thread self.finish_request(request, client_address) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/socketserver.py", line 360, in finish_request self.RequestHandlerClass(request, client_address, self) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/socketserver.py", line 720, in __init__ self.handle() File "/Users/username/python/mysite-venv/lib/python3.7/site-packages/django/core/servers/basehttp.py", line 171, in handle self.handle_one_request() File "/Users/username/python/mysite-venv/lib/python3.7/site-packages/django/core/servers/basehttp.py", line 179, in handle_one_request self.raw_requestline = self.rfile.readline(65537) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/socket.py", line 589, in readinto return self._sock.recv_into(b) ConnectionResetError: [Errno 54] Connection reset by peer
というエラーが出ていた。なお画像のアップロードには成功
③送るデータサイズに関わらずPOSTの時間が一定
大量のファイルをアップロードしようとしたら、なぜか一瞬で処理が完了する。しかし、一部アップロードができていない状況であった。
症状は以上となります、
他に必要な情報があれば、お手数おかけし申し訳ありませんが、ご指摘いただけると幸いです。よろしくお願いいたします。
回答1件
あなたの回答
tips
プレビュー