Django in production (nginx, gunicorn, supervisor). Server Error (500) при отправке формы
Доброго времени суток, товарищи программисты!
Сделал проект на Django и залил его на хостинг VPS с помощью nginx, gunicorn и supervisor. Это моя первая практика.
Проблема заключается в том, что при отправке формы на сайте выходит ошибка Server Error (500). Хотя сам сайт работает, и в админке всё тоже изменяется, добавляется и т.д.
Пробовал на локальном сервере на моём ПК и нет никакой ошибки (естественно с DUBUG=True).
Данные, которые могут быть полезны для решения проблемы:
Установленные модули python:
django
django-adminlte3
Pillow
django-ipware
gunicorn
supervisor
DateTime
asgiref
pytz
sqlparse
zope.interface
Упрощённый html формы (ну на всякий случай):
<form action="{% url 'send_email:send' %}" method="POST">
{% csrf_token %}
<div>
<p>Ваше имя: </p>
<input type="text" placeholder="Введите Ваше имя" name="name">
</div>
<div>
<p>Ваш номер телефона: </p>
<input type="text" placeholder="Введите Ваш телефон" name="phone">
</div>
<button type="submit">Отправить</button>
</form>
Код send_email views.py:
from django.shortcuts import redirect
from main.models import Email
from django.conf import settings
from django.core.mail import send_mail
from .models import *
from ipware import get_client_ip
import datetime
def send(request):
if request.method == "POST" and request.POST["name"] and request.POST["phone"]:
client_ip = get_client_ip(request) # получаю ip отправителя
name = request.POST["name"] # получаю имя отправителя через POST
phone = request.POST["phone"] # получаю номер телефона отправителя через POST
# обрезаю поля на всякий случай
name = name[:255]
phone = phone[:255]
# достаю email из БД, на который нужно отправлять письмо
emails = Email.objects.all()
if emails:
to = emails[0]
else: # если не сработало, то загружаю заявку в БД (default для email_to стоит)
email_request = EmailRequest(
ip_user=client_ip[0],
name=name,
phone=phone,
request_time=f"{datetime.datetime.now()} (по времени сервера)"
)
email_request.save()
return redirect('main:index') # перенаправление
# формирую письмо
message = f"""
Кто-то отправил заявку
Имя отправителя: {name};
Номер телефона отправителя: {phone};"""
html = f"""
<html>
<head></head>
<body>
<h1>Кто-то отправил заявку</h1>
<h3>Имя отправителя: {name};</h3>
<h3>Номер телефона отправителя: <a href="tel:{phone}">{phone}</a>;</h3>
<hr>
IP-адрес отправителя: {client_ip[0]}
</body>
</html>"""
# отправка письма на почту
send_mail(subject='Получена заявка от клиента', message=message, from_email=f"{settings.DEFAULT_FROM_EMAIL} <{settings.EMAIL_HOST_USER}>", recipient_list=[to], html_message=html)
# загрузка заявки в БД
email_request = EmailRequest(
ip_user=client_ip[0],
name=name,
phone=phone,
email_to=to,
request_time=f"{datetime.datetime.now()} (по времени сервера)"
)
email_request.save()
return redirect('main:index') # перенаправление
else:
return redirect('main:index')
Возможно, ошибка в настройках библиотеки send_mail.
Вот основные настройки проекта:
DEBUG = False
EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend'
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.mail.ru'
EMAIL_PORT = '25'
EMAIL_HOST_USER = '<EMAIL ADDRESS>'
EMAIL_HOST_PASSWORD = '<PASSWORD>'
DEFAULT_FROM_EMAIL = '<NAME IN ENGLISH>'
EMAIL_DEBUG = False
LANGUAGE_CODE = 'ru'
TIME_ZONE = 'Europe/Moscow'
USE_I18N = True
USE_L10N = True
USE_TZ = True
Я думаю, что ошибка может быть в настройке nginx, gunicorn или supervisor.
Настройка nginx /etc/nginx/sites-available/default (проверял с помощью: sudo nginx -t):
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/<DOMEN>.ru;
index index.html index.htm index.nginx-debian.html;
server_name <DOMEN>.ru;
access_log /var/log/nginx/example.log;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/<USER>/<PROJECT_NAME>;
expires 30d;
}
location /media/ {
root /home/<USER>/<PROJECT_NAME>;
expires 30d;
}
location / {
proxy_pass http://unix:/home/<USER>/<PROJECT_NAME>/<PROJECT_NAME>.sock;
proxy_set_header Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
Настройка gunicorn.service /etc/systemd/system/gunicorn.service:
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=<USER>
Group=www-data
WorkingDirectory=/home/<USER>/<PROJECT_NAME>
ExecStart=/home/<USER>/venv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/home/<USER>/<PROJECT_NAME>/<PROJECT_NAME>.sock <PROJECT_NAME>.wsgi:application
[Install]
WantedBy=multi-user.target
Настройки supervisor /etc/supervisor/conf.d:
[program:<PROGRAM_NAME>]
command=/home/<USER>/venv/bin/gunicorn <PROJECT_NAME>.wsgi:application -c /home/<USER>/<PROJECT_NAME>/config/gunicorn.conf.py
directory=/home/<USER>/<PROJECT_NAME>
user=<USER>
autorestart=true
redirect_stderr=true
stdout_logfile = /home/<USER>/<PROJECT_NAME>/logs/debug.log
Файл /home/<USER>/<PROJECT_NAME>/config/gunicorn.conf.py, упомянутый выше, в настройках supervisor /etc/supervisor/conf.d во 2-ой строке:
bind = "127.0.0.1:8000"
workers = 3
user = "<USER>"
timeout = 120
Файл /home/<USER>/<PROJECT_NAME>/<PROJECT_NAME>.sock создаётся, и, как я уже говорил, сервер запускается (проверял с помощью: sudo systemctl status gunicorn и sudo supervisorctl status <PROGRAM_NAME>)
В логах /var/log/nginx/example.log и sudo journalctl -u gunicorn: пишет "POST <URL> HTTP/1.0" 500 и дальше что-то типо: Chrome, Mozilla и т.д.
В логах /home/<USER>/<PROJECT_NAME>/logs/debug.log и sudo tail -F /var/log/nginx/error.log ничего по этому поводу не нашёл
Если кто-то знает решение, может сказать, где посмотреть нормальные подробные логи, или дать полезный совет - пишите, буду благодарен за каждую, даже малейшую, помощь. Заранее спасибо
Ответы (1 шт):
В общем я решил этот вопрос.
Проблема заключалась в файле send_email:views.py.
Ошибка была следующая:
django.core.exceptions.ValidationError: ['Значение “2021-06-08 16:27:51.404028 (по времени сервера)” имеет неверный формат. Оно должно быть в формате YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ].']
Я просто исправил соответствующим образом этот файл, и всё заработало.
Большое спасибо за ваши советы. Проблема решена. Всего доброго!