How can I apply my form to multiple templates in django

105 Views Asked by At

I am creating a blog site where users can post articles on the home page which can then also be commented on using a form. These posts can also be viewed elsewhere on the site, under search results and on user profiles for example. What I am trying to do is allow users to comment on the posts anywhere that they appear. For this I am using an inclusion tag for my comment form which looks like this:

@register.inclusion_tag('posts/comment.html')
def comment_create_and_list_view(request):
    profile = Profile.objects.get(user=request.user)
    c_form = CommentModelForm()

    if 'submit_c_form' in request.POST:
        c_form = CommentModelForm(request.POST)
        if c_form.is_valid():
            instance = c_form.save(commit=False)
            instance.user = profile
            instance.post = Post.objects.get(id=request.POST.get('post_id'))
            instance.save()
            c_form = CommentModelForm()

    context = {
        'profile': profile,
        'c_form': c_form,
    }

    return context

And is registered to my urls like this:

from django.urls import path
from .templatetags.custom_tags import comment_create_and_list_view
from .views import *

app_name = 'posts'

urlpatterns = [
    path('comment/<int:pk>/', comment_create_and_list_view, name='comment'),
]

My form looks like this:

class CommentModelForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = ('body',)

comment.html looks like this:

<form action="{% url 'posts:comment' post.id %}" method="post">
    {% csrf_token %}
    <input type="hidden" name="post_id" value={{ post.id }}>
    {{ c_form }}
    <button type="submit" name="submit_c_form">Send</button>
</form>

And I am importing the inclusion tag to my base.html file using {% comment_create_and_list_view request %}

Upon attempting to load the page I receive the NoReverseMatch at / error:

Reverse for 'comment' with arguments '('',)' not found. 1 pattern(s) tried: ['comment/(?P<pk>[0-9]+)/$']

Been googling this for hours and can't understand where I am going wrong...

1

There are 1 best solutions below

0
On

In case this helps someone else someday, I fixed my problem by refactoring my inclusion tag to only render the form:

@register.inclusion_tag('posts/comment.html')
def comment_tag():
    c_form = CommentModelForm()

    return {'c_form': c_form}

And added a view to handle submissions:

def comment_view(request):
    profile = Profile.objects.get(user=request.user)

    if 'submit_c_form' in request.POST:
        c_form = CommentModelForm(request.POST)
        if c_form.is_valid():
            instance = c_form.save(commit=False)
            instance.user = profile
            instance.post = Post.objects.get(id=request.POST.get('post_id'))
            instance.save()

    return redirect('posts:index')

I then adjusted comment.html to simply apply the form with {{ c_form }} and wrapped my template tag with the form element in my index:

<form action="{% url 'posts:comment' %}" method="post">
    {% csrf_token %}
    <input typ="hidden" name="post_id" value={{ post.id }}>
    {% comment_tag %}
    <button type="submit" name="submit_c_form">Send</button>
</form>