質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Apache

Apacheは、Apache HTTP Serverの略で、最も人気の高いWebサーバソフトウェアの一つです。安定性が高いオープンソースソフトウェアとして商用サイトから自宅サーバまで、多くのプラットフォーム向けに開発・配布されています。サーバーソフトウェアの不具合(NCSA httpd)を修正するパッチ(a patch)を集積、一つ独立したソフトウェアとして開発されました。

XHR

XHR(別名XMLHttpRequest)はJavaScriptなどのスクリプト言語を使ってサーバーとHTTP通信を行うAPIを指します。

Q&A

解決済

1回答

2497閲覧

xhrでDjangoサーバーに画像を複数POSTすると本番環境のみ挙動がおかしくなる。

switch0805

総合スコア25

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Apache

Apacheは、Apache HTTP Serverの略で、最も人気の高いWebサーバソフトウェアの一つです。安定性が高いオープンソースソフトウェアとして商用サイトから自宅サーバまで、多くのプラットフォーム向けに開発・配布されています。サーバーソフトウェアの不具合(NCSA httpd)を修正するパッチ(a patch)を集積、一つ独立したソフトウェアとして開発されました。

XHR

XHR(別名XMLHttpRequest)はJavaScriptなどのスクリプト言語を使ってサーバーとHTTP通信を行うAPIを指します。

0グッド

1クリップ

投稿2019/12/12 14:25

編集2019/12/13 07:06

#はじめに
ご覧いただき誠にありがとうございます。

現在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の時間が一定
大量のファイルをアップロードしようとしたら、なぜか一瞬で処理が完了する。しかし、一部アップロードができていない状況であった。

症状は以上となります、

他に必要な情報があれば、お手数おかけし申し訳ありませんが、ご指摘いただけると幸いです。よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tatamyiwathy

2019/12/13 02:49

回答するためには情報が足りないように感じました OSは何? Apacheのバージョンは? Dnagoのバージョンは? Pythonのバージョンは?
switch0805

2019/12/13 07:15 編集

ご指摘ありがとうございます。 本番サーバーOSはCentOS release 7.4.1708 (Core) 開発環境はMacOSCatalin10.15.1(19B88) Apache=>2.4.6 Django=>2.1.5 Python=>3.6.7 となります!よろしくお願いいたします。
tatamyiwathy

2019/12/13 07:20

本番サーバーだけで発生するのであればApacheの設定あたりでしょうか。 ファイルサイズ的なこともあるのかもしれませんね→https://qiita.com/index_30/items/bc1915efc6f87b4971fd
tatamyiwathy

2019/12/16 01:24

"ConnectionResetError: [Errno 54] Connection reset by peer"ってネット接続の根っこのほうで出るエラーって感じですよね。タイムアウトしたとかホストと通信が切れたとか。 特定のファイルだけで起きるとかないですか?
switch0805

2019/12/18 08:23 編集

返答が遅れ大変申し訳ありません。 特定のファイルで起こるとかはないですね。大概の画像(png,gif,jpg)で起こります。本番環境だとどういうわけか送れたファイルをもう一度送ったら、そのときはなぜかダメだったということはあります。
guest

回答1

0

自己解決

django-filerを採用しCKeditorに乗り換えることで解消した。

投稿2020/05/04 15:38

switch0805

総合スコア25

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問