Does not reflect current user in comment

Viewed 57

I'm creating an Instagram-style application with Django 3.2.5, where users have profiles to visit and upload photos. I am implementing a commenting system.

When generating the comment as a user with a registered profile, the comment is rendered as if it were anonymous.

I have investigated and it happens that in the model of the comment I made a relationship with the user and profile giving the null parameter as true. When removing this parameter and resubmitting a comment on a post I get a Not Null Constraint Failed error for profile_id and for user_id.

The image shows the first comments made from the admin. And the last one with the null = true parameter in the model.

Sample picture

models.py

class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
user = models.ForeignKey(User, on_delete=models.CASCADE)
profile = models.ForeignKey(Profile, on_delete=models.CASCADE)
text = models.TextField(max_length=200)
created_date = models.DateTimeField(auto_now_add=True)

class Meta:
    ordering = ['created_date']

def __str__(self):
    return self.text

views.py

def create_comment(request, pk):
post = get_object_or_404(Post, pk=pk)

if request.method == "POST":
    form = CommentForm(request.POST)
    
    if form.is_valid():
        comment = form.save(commit=False)
        comment.post = post
        comment.save()
        return redirect('posts:feed')

else:
    form = CommentForm()
    
return render(request, 'posts/feed.html', {
    'form': form,
    })

urls.py

urlpatterns = [
path(r'^post/(?P<pk>[0-9]+)/comment/$', create_comment, name='create'),]

forms.py

class CommentForm(forms.ModelForm):
pass

class Meta:
    model = Comment
    fields = ['text']

HTML

    <form action="{% url 'comments:create' pk=post.pk %}" method="POST" >
    {% csrf_token %}
    <div class="input-group">
        <input type="text" class="form-control" placeholder="Comment here" aria-label="text" name="text" value="{{ post.comment.pk}}" >
        <div class="input-group-append">
        <button class="btn btn-dark" type="submit" id="button-addon2"><i class="fas fa-comment"></i></button>
        </div>
    </div>
</form>
1 Answers

You should link the .user attribute to the logged in user, so:

from django.contrib.auth.decorators import login_required

@login_required
def create_comment(request, pk):
    if request.method == 'POST':
        form = CommentForm(request.POST, request.FILES)
    
        if form.is_valid():
            form.instance.post_id = pk
            form.instance.user = request.user
            form.save()
            return redirect('posts:feed')
    else:
        form = CommentForm()
    
    return render(request, 'posts/feed.html', {'form': form})

By making use of .post_id = pk, we no longer query the database to obtain the post first, validation is done when creating the Comment instance.


Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.


Note: You can limit views to a view to authenticated users with the @login_required decorator [Django-doc].

Related