Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django add comment section on posts feed

I want to share a project that currently can create user and each user can create N posts
The source is available on github

and I has two models users and post
enter image description here

and the template layers

enter image description here

Currently the feed for each post has a button that send an commenting the post I want to change that to put the comments of the post and not send and email each user should be able to comment a post and the comment should remain

{% block container %}
<body id="bg" img style="zoom: 85%; background-position: center center; background-attachment: fixed;background-repeat:no-repeat;padding:5px; background-image: url('{% static "/back.png"%}') ";>
<div style="background-image: url({% static 'static/img/back.png' %});">

    <div class="row" style="align:center">
        {% for post in posts %}
        <div class="col-sm-12 col-md-8 offset-md-4 mt-5 p-0 post-container,width:50%;">
            <div class="card" style="width: 32rem;width:50%;">
                <div class="card-body">
                    <div class="media pt-3 pl-3 pb-1">
                        <a href="{% url " users:detail" post.user.username%}">
                        <img alt="{{ post.user.username }}" class="mr-3 rounded-circle" height="35"
                             src="{{ post.profile.picture.url }}">
                        </a>
                        <h3 class="card-title">{{ post.title }}</h3>
                    </div>

                    <p class="card-text">{{ post.desc }}</p>

                </div>
            </div>
            <img alt="{{ post.title }}" src="{{ post.photo.url }}" style="width: 50%; heigth:60%">

            <div class="media-body">
                <b><p style="margin-top: 5px;">@{{ post.user.username }} - <small>{{ post.created }}</small>
                    &nbsp;&nbsp;
                    <a href="" style="color: #000; font-size: 20px;">
                        <i class="far fa-heart"></i>
                    </a>
                    <br>
                </p></b>


            </div>
            <!-- COMENT SECTION THAT I WANT TO IMPLEMENT MY FEATURE-->
            <form action="{% url 'posts:comment_new' %}" enctype="multipart/form-data" method="POST">
                {% csrf_token %}

                <input
                        class="form-control {% if form.title.errors %}is-invalid{% endif %}"
                        name="title"
                        size="16"
                        type="hidden"
                        value="{{post.title}}"
                >

                <input
                        class="form-control {% if form.title.errors %}is-invalid{% endif %}"
                        name="first_name "
                        size="16"
                        type="hidden"
                        value="{{user.first_name}}"
                >
                <input
                        class="form-control {% if form.title.errors %}is-invalid{% endif %}"
                        name="last_name "
                        size="16"
                        type="hidden"
                        value="{{user.last_name}}"
                >
                <textarea class="form-control" cols="50" name="comment" rows="5"
                          style="width:50%;" value="{{ comments.comment }}"></textarea>
                <button class="btn btn-outline-info btn-lg" style="width:35%; display:block;margin:auto;" type="submit">
                    Publish
                </button>

            </form>
        </div>
        <br>
        {% endfor %}
    </div>
</div>

{% endblock %}

As I said I want to replace this form function call to create a comment section instead sending a email with the comment

< form action = "{% url 'posts:comment_new' %}">


def comment_new(request):
    if request.method == 'POST':
        message = request.POST['comment']
        subject = request.POST['title']
        user = request.POST['first_name']
        last_name = request.POST['last_name']
        # lastname = request.POST['lastname']

        send_mail("[MAIL] " + subject, user + " " + last_name + " said  " + message + " on http://url.com:8000",
                  '[email protected]',
                  ['[email protected]'], fail_silently=False)
    posts = Post.objects.all().order_by('-created')
    return render(request, os.path.join(BASE_DIR, 'templates', 'posts', 'feed.html'), {'posts': posts})

I think this maybe create a comment with user and post id with the comment detail

def comment_new(request):
    if request.method == 'POST':   
        message = request.POST['comment']
        subject = request.POST['title']
        user = request.POST['first_name']
        last_name = request.POST['last_name']

        #lastname = request.POST['lastname']
        form = PostForm(request.POST, request.FILES)
        form.save()

One options its create a comment

class Comment(models.Model):
    """
    #id= models.AutoField(max_length=1000, blank=True)

    # post = models.ForeignKey(Post, related_name='',on_delete=models.CASCADE,default=0)
    """

    #comment = models.ForeignKey('posts.Post', related_name='posts_rel', to_field="comments", db_column="comments",
     #                           on_delete=models.CASCADE, null=True, default=1, blank=True)
    post = models.IntegerField(blank=True,null=True,unique=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE,null=True)
    username = models.CharField(blank=True, null=True, unique=True ,max_length=200)
    comment = models.CharField(max_length=254, blank=True, null=True)

and then the form

class CommentForm(forms.ModelForm):

    class Meta:
        """form settings"""
        model = Comment
        fields = ('user','username','post','comment',)

finally with the function I'm able to persist but not able to render

form = CommentForm(request.POST, request.FILES)

# print formset.errors

if form.is_valid():
   form.save()

but I can't find the way to render the object on the html file

please feel free to suggest any solution or better create a pull request on the public git hub repo
like image 1000
Guillermo Nahuel Varelli Avatar asked Mar 02 '20 22:03

Guillermo Nahuel Varelli


People also ask

How do I comment out code in Django?

To comment out a block of code in a Django template, use the {% comment %} and {% endcomment %} tags and pass the code to not render between the tags. And another example of commenting out some code.

How do I create a one to many relationship in Django?

To handle One-To-Many relationships in Django you need to use ForeignKey . The current structure in your example allows each Dude to have one number, and each number to belong to multiple Dudes (same with Business).


1 Answers

In the book Django 2 by Example we can find a step by step guide to create a comment system, wherein the users will be able to comment on posts.

In order to do it, is as simple as the following four steps

  1. Create a model to save the comments
  2. Create a form to submit comments and validate the input data
  3. Add a view that processes the form and saves the new comment to the database
  4. Edit the post detail template to display the list of comments and the form to add a new comment

  1. Create a model to save the comments

In your models.py file for the application, add the following code

class Comment(models.Model): 
    post = models.ForeignKey(Post,
                             on_delete=models.CASCADE,
                             related_name='comments')
    name = models.CharField(max_length=80) 
    email = models.EmailField() 
    body = models.TextField() 
    created = models.DateTimeField(auto_now_add=True) 
    updated = models.DateTimeField(auto_now=True) 
    active = models.BooleanField(default=True) 

    class Meta: 
        ordering = ('created',) 

    def __str__(self): 
        return 'Comment by {} on {}'.format(self.name, self.post) 

The new Comment model you just created is not yet synchronized into the database. Run the following command to generate a new migration that reflects the creation of the new model:

python manage.py makemigrations APPNAME

and

python manage.py migrate

After this, the new table exists in the database. Now, open the admin.py file of the blog application, import the Comment model, and add the following ModelAdmin class:

from .models import Post, Comment

@admin.register(Comment)
class CommentAdmin(admin.ModelAdmin):
    list_display = ('name', 'email', 'post', 'created', 'active')
    list_filter = ('active', 'created', 'updated')
    search_fields = ('name', 'email', 'body')

  1. Create a form to submit comments and validate the input data

Edit the forms.py file of your blog application and add the following lines:

from .models import Comment

class CommentForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = ('name', 'email', 'body')

  1. Add a view that processes the form and saves the new comment to the database

Edit the views.py file, add imports for the Comment model and the CommentForm form, and modify the post detail view to make it look like the following:

from .models import Post, Comment
from .forms import EmailPostForm, CommentForm

def post_detail(request, year, month, day, post):
    post = get_object_or_404(Post, slug=post,
                                   status='published',
                                   publish__year=year,
                                   publish__month=month,
                                   publish__day=day)

    # List of active comments for this post
    comments = post.comments.filter(active=True)

    new_comment = None

    if request.method == 'POST':
        # A comment was posted
        comment_form = CommentForm(data=request.POST)
        if comment_form.is_valid():
            # Create Comment object but don't save to database yet          
            new_comment = comment_form.save(commit=False)
            # Assign the current post to the comment
            new_comment.post = post
            # Save the comment to the database
            new_comment.save()
    else:
        comment_form = CommentForm()                   
    return render(request,
                  'blog/post/detail.html',
                  {'post': post,
                   'comments': comments,
                   'new_comment': new_comment,
                   'comment_form': comment_form})

  1. Edit the post detail template to display the list of comments and the form to add a new comment

At this point we have created the functionality to manage comments for a post. Now, we will need to adapt our post/detail.html template to do the following things: - Display the list of comments - Display a form for users to add a new comment

Append the following lines to the post/detail.html template for the list of comments:

{% for comment in comments %}
  <div class="comment">
    <p class="info">
      Comment {{ forloop.counter }} by {{ comment.name }}
      {{ comment.created }}
    </p>
    {{ comment.body|linebreaks }}
  </div>
{% empty %}
  <p>There are no comments yet.</p>
{% endfor %}

Then, for the other point, add the following lines:

{% if new_comment %}
  <h2>Your comment has been added.</h2>
{% else %}
  <h2>Add a new comment</h2>
  <form action="." method="post">
    {{ comment_form.as_p }}
    {% csrf_token %}
    <p><input type="submit" value="Add comment"></p>
  </form>
{% endif %}
like image 178
Tiago Martins Peres Avatar answered Sep 20 '22 03:09

Tiago Martins Peres