[Answered ]-Set the value of a django HiddenInput widget to another object's id rendered in the template

1👍

✅

In general I’d do this by setting the post ID based on something other than a form value. In order to set the post to comment relationship your view has to know which post is being commented on – probably as a URL element – so I’d just use that directly rather than passing it around as form data. Something like:

from django.shortcuts import get_object_or_404

def comment(request, post_id):
    post = get_object_or_404(Post, id=post_id)
    if request.method == 'POST':
        form = CommentForm(request.POST)
        if form.is_valid():
            new_comment = form.save(commit=False)
            new_comment.post = post
            new_comment.save()
    # usual form boilerplate below here

One way you could implement this in your uris.py is:

uris:

url(r'(?P<post_id>\d+)/$', views.comment, name="comment")

Depending on the rest of your URL structure it might be clearer to include more context:

url(r'post/(?P<post_id>\d+)/comment/$', views.comment, name="comment")

But that’s basically down to personal preference unless you’re aiming for a REST-style API.

There’s no need to specify the form action differently – the usual action="" will submit the form to a URI that includes the ID, since it’s part of the URI that displays the form.

If for some reason you want to do this with the hidden input, use an initial argument when creating the form.

 if request.method == 'POST':
     form = CommentForm(request.POST, initial={'comment_post': post})
     # usual processing
 else:
     form = CommentForm(initial={'comment_post': post})
 # and render

1👍

I assume your model Comment has a foreign key relationship with Post, you can just use forms.ModelChoiceField for comment_post:

comment_post = forms.ModelChoiceField(queryset=Post.objects.all(),
                                      widget=forms.HiddenInput())

In the views, give current post object as initial data to the comment_post:

# assume you have a variable that called "current post"
comment_form = CommentForm(request.POST, initial={'comment_post': current_post})

Just in case you are not sure what’s the behavior, it’s going to create a hidden form field and pre-populate selected data with current_post, then when you POST the form, the form already contains the data, you call comment_form.save() and that’s it.

Leave a comment