Home > database >  Editable comments django blog
Editable comments django blog

Time:08-04

I'm having trouble making my comments editable. They work fine if I leave them uneditable, but I do want them editable. I think it has something to do with primary keys but I'm not quite getting the hang of it. I was able to edit comments earlier, but it would always edit the latest comment.

Here is my code:

models.py


    class Tee_times(models.Model):
    
        viable_courses = [
            ("Eslövs GK","Eslövs GK"),
            ("Lunds Akademiska GK","Lunds Akademiska GK"),
            ("Söderåsens GK","Söderåsens GK")
        ]
    
        title = models.CharField(max_length=100, choices=viable_courses, default=1)
        content = models.TextField()
        pub_date = models.DateTimeField(auto_now_add=True)
        player = models.ForeignKey(User, on_delete=models.CASCADE)
    
        def __str__(self):
            return self.title
    
        def get_absolute_url(self):
            return reverse("post-detail", kwargs={"pk": self.pk})
    
    class Comment(models.Model):
        text = models.CharField(max_length=200, default="Write a comment")
        tee_time = models.ForeignKey(Tee_times, related_name="comments", on_delete=models.CASCADE)
        pub_date = models.DateTimeField(auto_now_add=True)
        player = models.ForeignKey(User, on_delete=models.CASCADE)
    
        class Meta:
            ordering = ("pub_date",)
    
        def __str__(self):
            return f"{self.player} - {self.pub_date}"
    
        def get_absolute_url(self):
            return reverse("post-detail", kwargs={"pk": self.tee_time.pk})
    
        def set_time(self):
            self.pub_date = models.DateTimeField(auto_now_add=True)

urls.py


    urlpatterns = [
        path('', TeeListView.as_view(), name="index"),
        path('post/<int:pk>/', DetailTeeView.as_view(), name="post-detail"),
        path('post/<int:pk>/comment/new/', CommentCreateView.as_view(), name="comment-create"),
        path('post/<int:pk>/comment/<int:pkc>/update/', CommentUpdateView.as_view(), name="comment-update"),
        path('post/<int:pk>/comment/<int:pkc>/delete/', CommentDeleteView.as_view(), name="comment-delete"),
        path('post/new/', TeeCreateView.as_view(), name="post-create"),
        path('post/<int:pk>/update/', TeeUpdateView.as_view(), name="post-update"),
        path('post/<int:pk>/delete/', TeeDeleteView.as_view(), name="post-delete"),
        path("second/", views.second, name="second"),
        path("register/", user_views.register, name="Register")
    ]

views.py

```
class TeeListView(ListView):
    model = Tee_times
    template_name = "testapp/index.html"
    context_object_name = "posts"
    ordering = ["-pub_date"]

class DetailTeeView(DetailView):
    model = Tee_times

class TeeCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView):
    model = Tee_times
    fields = ["title",
              "content"]

    success_message = "New Tee Time Created!"

    def form_valid(self, form):
        form.instance.player = self.request.user
        return super().form_valid(form)

class TeeDeleteView(LoginRequiredMixin, UserPassesTestMixin, SuccessMessageMixin, DeleteView):
    model = Tee_times
    success_url = "/"
    success_message = f"The tee time was successfully deleted!"

    def test_func(self):
        tee_time = self.get_object()
        if self.request.user == tee_time.player:
            return True
        else:
            return False



class TeeUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
    model = Tee_times
    fields = ["title",
              "content"]

    def form_valid(self, form):
        form.instance.player = self.request.user
        return super().form_valid(form)

    # goes through userpassestexstmixin
    def test_func(self):
        tee_time = self.get_object()
        if self.request.user == tee_time.player:
            return True
        else:
            return False

class CommentCreateView(CreateView):
    model = Comment
    fields = ["text"]

    def form_valid(self, form):
        form.instance.tee_time_id = self.kwargs["pk"]
        form.instance.player = self.request.user
        return super().form_valid(form)



class CommentDeleteView(LoginRequiredMixin, UserPassesTestMixin, SuccessMessageMixin, DeleteView):
    model = Comment
    success_url = "/"
    success_message = f"The comment was successfully deleted!"

    def test_func(self):
        comment = self.get_object()
        if self.request.user == comment.player:
            return True
        else:
            return False


class CommentUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
    model = Comment
    fields = ["text"]

    def form_valid(self, form):
        form.instance.tee_time_id = self.kwargs["pk"]
        form.instance.player = self.request.user
        return super().form_valid(form)

    # goes through userpassestexstmixin
    def test_func(self):
        comment = self.get_object()
        if self.request.user == comment.player:
            return True
        else:
            return False

the html page in question
<pre>
{% extends "testapp/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
{% load static %}
    <article >
        <img  src="{{ object.player.profile.profile_picture.url }}">
      <div >
        <div >
          <a  href="{% url 'profile' object.player %}">{{ object.player }}</a>
          <small >{{ object.pub_date }}</small>
            {% if object.player == user %}
                <a  href="{% url 'post-update' object.id %}">Update</a>
                <a  href="{% url 'post-delete' object.id %}">Delete</a>
            {% endif %}
        </div>
        <h2>{{ object.title }}</h2>
        <p >{{ object.content }}</p>
      </div>
    </article>
          {% for comment in object.comments.all %}
            <article >
              <div >
                <div >
                  <a  href="{% url 'profile' object.player %}">{{ comment.player }}</a>
                  <small >{{ comment.pub_date }}</small>
                    {% if comment.player == user %}
                        <a  href="{% url 'comment-update' comment.id %}">Update</a>
                        <a  href="{% url 'comment-delete' comment.id %}">Delete</a>
                    {% endif %}
                </div>
                <p >{{ comment.text }}</p>
              </div>
            </article>
          {% endfor %}
    <form>
    <article >
        <link rel="stylesheet" href="{% static 'testapp/button.css' %}">
            <form>
                <button formaction="{% url 'comment-create' object.id %}" type="submit"  role="button">Comment</button>
            </form>
    </article>
    </form>
{% endblock %}
</pre>

I know the <int:pkc> might not make sense - I just tried a bunch of stuff. And the problem with it all comes when i add these two lines, that are in the html file:

<pre>
<a  href="{% url 'comment-update' comment.id %}">Update</a>
                        <a  href="{% url 'comment-delete' comment.id %}">Delete</a>
</pre>

I get the following error:
"NoReverseMatch at /post/4/
Reverse for 'comment-update' with arguments '(4,)' not found. 1 pattern(s) tried: ['post/(?P<pk>[0-9] )/comment/(?P<pkc>[0-9] )/update/\\Z']"

I am very lost right now, and would be very thankful of some guidance...

CodePudding user response:

In your urls.py

  path('post/<int:pk>/comment/<int:pkc>/update/', CommentUpdateView.as_view(), name="comment-update"),
    path('post/<int:pk>/comment/<int:pkc>/delete/', CommentDeleteView.as_view(), name="comment-delete"),

You will see that each of these requires two variables, pk and pkc. However, when you are creating your URLS you only have one variable, comment.id

             {% if comment.player == user %}
                    <a  href="{% url 'comment-update' comment.id %}">Update</a>
                    <a  href="{% url 'comment-delete' comment.id %}">Delete</a>
                {% endif %}

You need to include the second variable, the pk for the post, for the URLs to match, eg

{% url 'comment-update' object.id comment.id %}
  • Related