実現したいこと
画像をアップロードした時の500エラーを解決したい。
ローカル環境での画像アップロードは行えますが、本番環境だと画像をアップロードした時のみ500エラーが返ってきます。
追記
エラーの原因がPillow関連だということがわかりました。
Pillowをインストールしているはずですが、下記のエラーが出ます。
Pillowインストール時のpython3のバージョンと実行python3のバージョンは同じかと思います。
PILはインストールしておりません。
No module named 'PIL'
のエラーを解決したい。
本番環境
OS:mac
Django:3.2.10
Python:3.9
Linux
Django:3.2.12
python:3.7
MySQL:8.0
Apache:2.4.53
EC2
S3
コード
settings.py
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'xxxxxxxxxx', 'USER': 'xxxxxxxxxxx', 'PASSWORD': 'xxxxxxxxxx', 'HOST': 'xxxxxxxxxxxxxx.rds.amazonaws.com', 'PORT': '3306', } } STATIC_URL = 'static/' # Default primary key field type # https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' #CSSの読み込み STATICFILES_DIRS = [ BASE_DIR / "static" ] #カスタムユーザーモデルをデフォルトに設定 AUTH_USER_MODEL = 'register.User' #registerの設定 LOGIN_URL = 'register:login' LOGIN_REDIRECT_URL = 'admin:top' LOGOUT_REDIRECT_URL = 'register:login' # 画像の読み込み # MEDIA_ROOT = os.path.join(BASE_DIR) # S3の設定 AWS_LOCATION = 'static' DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' AWS_STORAGE_BUCKET_NAME = 'xxxxxxxx' AWS_S3_REGION_NAME = 'ap-northeast-1' AWS_ACCESS_KEY_ID = 'xxxxxxxxx' AWS_SECRET_ACCESS_KEY = 'xxxxxxxxxxxxx'
model.py
def upload_image_to(instance, filename): staff = str(instance.staff_id) return os.path.join('static', 'images', staff, filename) class Staff(models.Model): staff_id = models.BigAutoField(primary_key=True,validators=[MaxValueValidator(8)]) staff_code = models.IntegerField() staff_name = models.CharField(max_length=255) staff_phone_1 = models.CharField(max_length=255,blank=True,null=True) staff_sex = models.SmallIntegerField(validators=[MaxValueValidator(1)]) staff_email = models.EmailField() staff_login_password = models.CharField(max_length=255) staff_status = models.SmallIntegerField(validators=[MaxValueValidator(2)],blank=True,null=True) staff_image = models.ImageField(max_length=255, default='static/images/default.png', upload_to=upload_image_to)
views.py
class StaffCreateForm(View): return render(request,"pages/staffCreate.html",context) def post(self, request): posted = Staff( staff_code = request.POST["staff_code"], staff_name = request.POST["staff_name"], staff_email = request.POST["staff_email"], staff_login_password = request.POST["staff_login_password"], staff_sex = request.POST["staff_sex"], ) staff_phone_1_result = request.POST["staff_phone_1"] staff_status_result = request.POST["staff_status"] staff_image_result = request.FILES.get("staff_image") if not "" == staff_phone_1_result: posted.staff_phone_1 = request.POST["staff_phone_1"] if not "" == staff_status_result: posted.staff_status= request.POST["staff_status"] #画像をアップロードしなかった際、デフォルトの画像を挿入 if None == staff_image_result: posted.staff_image = str("static/images/default.png") else: posted.staff_image = request.FILES.get("staff_image") posted.save() return redirect("admin:staffList") class StaffEditForm(UpdateView): template_name = 'pages/staffEdit.html' model = Staff fields = [ 'staff_code', 'staff_name', 'staff_email', 'staff_login_password', 'staff_sex', 'staff_phone_1', 'staff_status', 'staff_image', ] def get_success_url(self): return reverse('admin:staffList')
staffCreate.html
<div class="p-staff__formBox"> <p class="p-staff__formText">画像</p> <div class="p-staff__imageBlock"> <div class="p-staff__imageTest"> <!-- デフォルト画像 --> <img id="no_image" class="{% if staff.staff_image != none %}hidden{% endif %}" src="https://xxxxxxxxx.amazonaws.com/static/images/default.png"> <!-- 画像がある場合 --> <img id="image_preview" class="{% if staff.staff_image == none %}hidden{% endif %}" src="https://xxxxxxxxxxxx.amazonaws.com/{{ staff.staff_image }}"> </div> <label class="p-staff-imageLabel"> 画像をアップロード <input class="p-staff__imageBtn" type="file" accept=".png, .jpeg, .jpg, .gif, .img" name="staff_image" onchange="previewImage(this)"> </label> </div> </div> <!-- プレビュー --> <script> function previewImage(elem) { let fileReader = new FileReader(); fileReader.onload = (function(){ document.getElementById('image_preview').classList.remove('hidden'); document.getElementById('no_image').classList.add('hidden'); document.getElementById('image_preview').src = fileReader.result; }) fileReader.readAsDataURL(elem.files[0]); } </script>
etc/httpd/conf.d/アプリ名.conf
"/etc/httpd/conf.d/アプリ名.conf" 18L, 503B 9,15 全て LoadModule wsgi_module /usr/local/lib64/python3.7/site-packages/mod_wsgi/server/mod_wsgi-py37.cpython-37m-x86_64-linux-gnu.so ServerName xx.xx.xxx.xxx WSGIScriptAlias / /home/ec2-user/アプリ名/config/wsgi.py WSGIPythonPath /home/ec2-user/アプリ名:/usr/bin/python3 Alias /static/ /home/ec2-user/アプリ名/static/ <Directory /home/ec2-user/アプリ名/static> Require all granted </Directory> <Directory /home/ec2-user/アプリ名/config> <Files wsgi.py> Require all granted </Files> </Directory>
試したこと
DBの初期化やsettings.pyのSTATIC_URLのパスを変えたりしてみましたが、解決できませんでした。
画像アップロード時のみ500エラーが出る事象がネットに転がっていなかったため、皆様のお力を借りたいです。よろしくお願い致します。
足りない記述やエラーの要因になりそうなものがありましたら、教えていただけると幸いです。
追記
エラー文
ModuleNotFoundError at /admin/staff/edit/2 No module named 'PIL' Request Method: POST Request URL: http://xx.xx.xxx.xxx/admin/staff/edit/2 Django Version: 3.2.12 Exception Type: ModuleNotFoundError Exception Value: No module named 'PIL' Exception Location: /usr/local/lib/python3.7/site-packages/django/forms/fields.py, line 631, in to_python Python Executable: /usr/bin/python3 Python Version: 3.7.10 Python Path: ['/home/ec2-user/アプリ名', '/usr/bin/python3', '/usr/lib64/python37.zip', '/usr/lib64/python3.7', '/usr/lib64/python3.7/lib-dynload', '/usr/local/lib64/python3.7/site-packages', '/usr/local/lib/python3.7/site-packages', '/usr/lib64/python3.7/site-packages', '/usr/lib/python3.7/site-packages'] Server time: Tue, 10 May 2022 14:57:42 +0000
python
$ python3 Python 3.7.10 (default, Jun 3 2021, 00:02:01) [GCC 7.3.1 20180712 (Red Hat 7.3.1-13)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import pillow Traceback (most recent call last): File "<stdin>", line 1, in <module> ModuleNotFoundError: No module named 'pillow' >>> import PIL >>>
まだ回答がついていません
会員登録して回答してみよう