1๐
If you make a request, you always will end up triggering one view. That view can render, zero, one or more templates to generate a HTTP response, but it does not need any templates at all. Template are only a mechanism to make it more convenient to generate HTML.
If you thus make a request to the DetailView
, then this will not somehow include the CreateView
, it will simply let the DetailView
decide what should be done to generate a response and in this case that is rendering a template.
You can however easily use the FormMixin
[Django-doc] to render the form:
from django.views.generic.edit import FormMixin
class PostDetailView(FormMixin, LoginRequiredMixin, DetailView):
model = Post
form_class = CommentCreationForm
context_object_name = 'post'
template_name = 'post/details.html'
def post(self, request, *args, **kwargs):
form = self.get_form()
self.object = self.get_object()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
def form_valid(self, form):
form.instance.author = self.request.user
form.instance.post = self.object
return super().form_valid(form)
Here we thus make use of the mixin to handle the logic to create a form and pass it to the context. We have to implement the post
method that will check if the form is valid, and if it is, adds the author
and the post
to the instance wrapped in the form.
Note: It is normally better to make use of the
settings.AUTH_USER_MODEL
[Django-doc] to refer to the user model, than to use theUser
model [Django-doc] directly. For more information you can see the referencing theUser
model section of the documentation.
0๐
I usually do it by functions instead class
this is my sample code:
views.py: (after all post views)
@login_required
def add_comment_to_post(request ,pk):
post = get_object_or_404(Post,pk=pk)
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.post = post
comment.save()
return redirect('post_detail',pk=post.pk)
else:
form = CommentForm()
return render(request,'blog/comment_form.html',{'form':form})
@login_required
def comment_approve(request,pk):
comment = get_object_or_404(Comment,pk=pk)
comment.approve()
return redirect('post_detail',pk=comment.post.pk)
@login_required
def comment_remove(request,pk):
comment = get_object_or_404(Comment,pk = pk)
post_pk = comment.post.pk
comment.delete()
return redirect('post_detail',pk=post_pk)
models.py:
class Post(models.Model):
author = models.ForeignKey('auth.User',on_delete=models.CASCADE)
title = models.CharField(max_length = 50)
text = models.CharField(max_length=500)
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
def publish(self):
self.published_time = timezone.now()
self.save()
def approve_comments(self):
return self.comments.filter(approved_comment=True)
def get_absolute_url(self):
return reverse("post_detail",kwargs={'pk':self.pk})
def __str__(self):
return self.title
class Comment(models.Model):
post=
models.ForeignKey('blog.Post',related_name='comments',on_delete=models.CASCAD)
author = models.CharField(max_length=16)
text = models.CharField(max_length=220)
created_date = models.DateTimeField(default=timezone.now)
approved_comment = models.BooleanField(default=False)
def approve(self):
self.approved_comment = True
self.save()
def get_absolute_url(self):
return reverse('post_list')
def __str__(self):
return self.text
- [Answered ]-Soft Delete. Move records or create "deleted" column
- [Answered ]-How to query filter self foreign key
- [Answered ]-Django perform a join on multiple tables
- [Answered ]-Django raw sql query
- [Answered ]-Use variable as key name for model