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:

  1. 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
  1. 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:

  1. Double-checked SMTP settings and ensured my App Password is correct.
  2. Verified that the Gmail account is set up for 2-Step Verification and using the App Password.
  3. Made sure the model’s reply field is included in the form and saved in the view.

Questions:

  1. Why is the App Password setup failing in this case?
  2. Is there a problem with the email configuration or network issues on my local machine?
  3. Why isn’t the reply field updating in the ProductReview model even though I’m saving it correctly in the view?
  4. Is there anything wrong with my ProductReview model or the way I’m saving the reply?
Вернуться на верх