Django SMTP Email Issue: Пароль приложения Gmail не работает + модель не обновляется
Я работаю над проектом Django, в котором мне нужно отправлять электронные письма с помощью SMTP-сервера Gmail. Однако, несмотря на то, что я правильно настроил параметры SMTP и использовал App Password от Google, я все равно сталкиваюсь с проблемами при попытке отправки писем. Кроме того, модель, в которой я храню ответы на отзывы, не обновляется, даже после того, как я пытаюсь сохранить в ней данные. Вот полный набор настроек:
Что я пробовал:
1.Настройки SMTP в settings.py
:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = 'myemail@gmail.com'
EMAIL_HOST_PASSWORD = 'myapppassword' # Gmail App Password
DEFAULT_FROM_EMAIL = 'myemail@gmail.com'
Виды:
В моем представлении я разрешаю продавцам отвечать на отзывы о товаре. Когда продавец отвечает, ответ сохраняется в модели ProductReview
и покупателю должно быть отправлено электронное письмо. Вот код представления:
@login_required
def product_reviews(request):
try:
vendor = Vendor.objects.get(user=request.user)
except Vendor.DoesNotExist:
return render(request, 'vendorpannel/no_vendor.html')
all_reviews = ProductReview.objects.filter(vendor=vendor)
if request.method == "POST":
review_id = request.POST.get('review_id')
reply_text = request.POST.get('reply_text')
if review_id and reply_text:
try:
review = ProductReview.objects.get(id=review_id, vendor=vendor)
review.reply = reply_text # Save the reply to the model
review.save()
# Send an email to the customer
customer_email = review.user.email
subject = "Reply to Your Product Review"
message = f"""
Dear {review.user.username},
The vendor has replied to your review for the product "{review.product.title}":
"{reply_text}"
Thank you for sharing your feedback.
Best regards,
Your Website Team
"""
send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [customer_email])
return redirect('product_reviews') # Redirect to avoid form resubmission
except ProductReview.DoesNotExist:
# Handle invalid review_id
context = {
"all_reviews": all_reviews,
"error_message": "Review not found or you don't have permission to reply to this review.",
}
return render(request, "vendorpannel/product-reviews.html", context)
context = {
"all_reviews": all_reviews,
}
return render(request, "vendorpannel/product-reviews.html", context)
HTML-шаблон: Вот часть HTML-шаблона, где продавец может отправить ответ на отзыв о товаре:
{% for r in all_reviews %}
<div class="review-card">
<img src="{{r.product.image.url}}" alt="Product Image">
<div class="review-details">
<h5>Product Name: {{r.product.title}}</h5>
<p><strong>Reviewer:</strong> Anon's Customer</p>
<p><strong>Rating:</strong> {{ r.rating }} Star{{ r.rating|pluralize }}</p>
<p><strong>Review:</strong> {{r.review}}</p>
<!-- Vendor Reply -->
{% if review.reply %}
<p><strong>Vendor Reply:</strong> {{ review.reply }}</p>
{% else %}
<form method="POST">
{% csrf_token %}
<textarea name="reply_text" rows="2" placeholder="Write your reply here..." required></textarea>
<input type="hidden" name="review_id" value="{{ review.id }}"> <!-- Ensure this value is correct -->
<button type="submit" class="btn btn-primary btn-sm">Reply 2</button>
</form>
{% endif %}
<!-- Reply Form -->
<form class="reply-form">
<label for="reply-1" class="form-label">Your Reply:</label>
<textarea id="reply-1" class="form-control" rows="3" placeholder="Write your reply..."></textarea>
<button type="submit" class="btn btn-primary mt-2">Reply</button>
</form>
</div>
</div>
{% endfor %}
Модель:
Модель ProductReview
используется для хранения отзывов и ответов, но поле ответа обновляется некорректно. Вот модель:
class ProductReview(models.Model):
user=models.ForeignKey(CustomUser, on_delete=models.SET_NULL ,null=True)
vendor=models.ForeignKey(Vendor, on_delete=models.SET_NULL,null=True,related_name="productreview")
product=models.ForeignKey(Product, on_delete=models.SET_NULL ,null=True,related_name="reviews")
review=models.TextField()
reply = models.TextField(null=True, blank=True)
rating = models.BigIntegerField(choices=RATING, default=3)
date=models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name_plural="Product Reviews"
def __str__(self):
return self.product.title
def get_rating(self):
return self.rating
Проблемы:
- Электронная почта не отправляется:
Несмотря на то, что я правильно настроил почтовый бэкэнд и использовал пароль Gmail App Password, при попытке отправить письмо я получаю следующую ошибку:
socket.gaierror: [Errno 11001] getaddrinfo failed
- Модель не обновляется:
Когда продавец отвечает на отзыв, ответ должен быть сохранен в модели ProductReview
. Однако он не обновляется в базе данных.
Что я пробовал:
- Дважды проверьте настройки SMTP и убедитесь, что мой пароль App Password верен.
- Убедитесь, что учетная запись Gmail настроена на 2-Step Verification и использует App Password.
- Убедитесь, что поле
reply
модели включено в форму и сохранено в представлении.
Вопросы:
- Почему в данном случае не работает настройка App Password?
- Есть ли проблема с конфигурацией электронной почты или проблемы с сетью на моем локальном компьютере?
- Почему поле ответа не обновляется в модели
ProductReview
, хотя я правильно сохраняю его в представлении? - Может быть, что-то не так с моей
ProductReview
моделью или с тем, как я сохраняю ответ?