Reputation: 317
I am trying to make a comment form on a posting app with django, the problem is I can't seem to get it's own object's id, any idea?
#views.py
class MyFormView(FormView):
form_class = CommentForm
success_url = "/"
def form_valid(self,form,*args,**kwargs):
comment = form.save(commit=False)
comment.message=Message.objects.get(id=???)
comment.save()
return super(MyFormView, self).form_valid(form)
#urls.py
urlpatterns = [
path('', MessageListView.as_view(),name="messaging-main"),
path('new', MessageCreateView.as_view(),name="messaging-new"),
path('post/<int:pk>', MessageDetailView.as_view(),name="messaging-detail"),
path('my_form',MyFormView.as_view(),name="form-view")
]
#forms.py
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ['comment']
#models.py
class Message(models.Model):
date_posted = models.DateTimeField(default=timezone.now)
message = models.TextField()
image = models.ImageField(default="")
def __str__(self):
return self.message
class Comment(models.Model):
message = models.ForeignKey(Message,on_delete=models.CASCADE)
comment = models.TextField(max_length=50)
date_posted = models.DateTimeField(default=timezone.now)
def __str__(self):
return "Comment on {}".format(str(self.date_posted))
def get_absolute_url(self):
return reverse("messaging-detail",kwargs={"id":self.id})
If i were to replace the ??? with for example 7, it will post every comment on message(or post) with the id 7, but I want the comment to be posted on the message i am seeing. Any help appreciated
Upvotes: 3
Views: 2567
Reputation: 477641
You will need to encode the primary key (or another attribute) of the message in the request. You can do that in several ways: by encoding it in the URL that is triggered for example, or by a hidden field in the form that will then be send as a POST parameter.
We can thus for example add a message_id
parameter to the url:
#urls.py
urlpatterns = [
# …,
path('my_form/<int:message_pk>', MyFormView.as_view(), name="form-view")
]
Then in the form, we can use the parameter, by accessing it in self.kwargs
:
#views.py
class MyFormView(FormView):
form_class = CommentForm
success_url = "/"
def form_valid(self,form,*args,**kwargs):
form.instance.message_id = self.kwargs['message_pk']
self.object = form.save()
return super(MyFormView, self).form_valid(form)
By using message_id
, we avoid making an extra call to the the database to fetch the corresponding Message
.
In the template you render for the MessageDetailView
view, the <form>
will then need to use as action URL a URL with the corresponding primary key of the message. For example if the context object name is 'message'
, you can pass it with:
<form action="{% url 'form-view' message_pk=message.pk %}" method="post">
…
</form>
Upvotes: 3