Django SMTP Email Issue: Gmail App Password Not Working + Model Not Updating
I am working on a Django project where I need to send emails using Gmail’s SMTP server. However, even though I have set up the SMTP settings correctly and used the App Password from Google, I’m still encountering issues when trying to send emails. Additionally, the model where I store the review replies isn't updating, even after I attempt to save data to it. Here’s the full setup:
What I’ve Tried:
1.SMTP Settings in 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'
Views:
In my view, I allow vendors to reply to product reviews. When a vendor replies, the reply is saved in the ProductReview
model and an email should be sent to the customer. Here’s the view code:
@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 Template: Here’s the part of the HTML template where the vendor can submit a reply to the product review:
{% 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 %}
Model:
The ProductReview
model is used to store reviews and replies, but the reply field is not being updated correctly. Here’s the model:
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
Issues:
- Email Not Sending:
Even though I’ve set up the email backend correctly and used a Gmail App Password, I’m getting the following error when trying to send an email:
socket.gaierror: [Errno 11001] getaddrinfo failed
- Model Not Updating:
When the vendor replies to a review, the reply should be saved in the ProductReview
model. However, it’s not updating in the database.
What I’ve Tried:
- Double-checked SMTP settings and ensured my App Password is correct.
- Verified that the Gmail account is set up for 2-Step Verification and using the App Password.
- Made sure the model’s
reply
field is included in the form and saved in the view.
Questions:
- Why is the App Password setup failing in this case?
- Is there a problem with the email configuration or network issues on my local machine?
- Why isn’t the reply field updating in the
ProductReview
model even though I’m saving it correctly in the view? - Is there anything wrong with my
ProductReview
model or the way I’m saving the reply?