pythondjangodjango-modelsdjango-viewsdjango-email

Send 'User' name and 'Form content' in email notification


I'm trying to get the form to send an email notification of the 'Users' username and content of the 'Comment' its self. I have managed to get the title of the post working but nothing else. Need a little help.

Views

def ViewPost(request, slug):
        try:
            post = BlogPost.objects.get(slug=slug)
        except BlogPost.DoesNotExist: 
            print("Blog with this slug does not exist")
            post = None
    
    
        comments = post.comments.filter(status=True)
        user_comment = None
    
        if request.method == 'POST':
            comment_form = CommentForm(request.POST)
            if comment_form.is_valid():
                user_comment = comment_form.save(commit=False)
                user_comment.post = post
                user_comment.user = request.user
                user_comment.save()
               
                messages.success(request, ("Comment successfully posted, thank you..."))
                send_mail('You have recieved a comment on a blog post', post.title, post.user # not working , #reference comment here 
                [
                    'gmail.com'])
              
        else:
            comment_form = CommentForm()
    
        
        return render(request, 'mhpapp/view-post.html', {'post': post, 'slug': slug, 'comments': user_comment, 'comments': comments, 'comment_form': comment_form})

Comment Model

class BlogComment(models.Model):
    post = models.ForeignKey(BlogPost, related_name="comments", on_delete=models.CASCADE)
    user = models.ForeignKey(User, editable=False, on_delete=models.CASCADE, default="",)
    name = models.CharField('Name',max_length=100, default="")
    text = models.TextField('Comment',max_length=1000, default="")
    date = models.DateTimeField(auto_now_add=True)
    status = models.BooleanField(default=True)

    class Meta:
            ordering = ("date",) 

    def __str__(self):
        return '%s -> %s'%(self.post.title, self.user)

Solution

  • Ideally, your view function should be named view_post (follow snake case in Python code). Refer to PEP8 for Python coding conventions. It should just be doing that, i.e. viewing a post with given slug. Using POST method to actually post a comment on that post in the same view should be avoided. You can do that in another view, and once a comment is posted successfully, you can redirect to the same slug on your view_post view.

    Now coming to the actual issue with your code, the call to send_mail function is wrong. A good practice to follow in your code is to pass the parameters as keyword arguments. In cases when the complexity of a function becomes high (due to the increasing number of parameters that it expects), it becomes easier for you and anyone else reading your code to understand what is happening, if you pass parameters as keyword arguments.

    The send_mail function expects the following parameters:

    send_mail(subject, message, from_email, recipient_list, fail_silently=False, auth_user=None, auth_password=None, connection=None, html_message=None)
    

    So, your function call will be changed to something like this:

    subject = f"User: {user_comment.user.username} left you a comment"
    message = f"Hi, {user_comment.user.username} left the following comment on post with slug {user_comment.post.slug}\n {user_comment.text}"
    send_mail(subject=subject, message=message, from_email="youremail@example.com", recipient_list=['someone@example.com'], fail_silently=False)