FormMixin on DetailView Django



我想在我的DetailView的同一页有一个评论部分,所以我决定使用FormMixin作为一种方式来添加评论。它没有引起任何错误,但提交的评论似乎无处可去,它也没有显示在管理网站。

models.py

from django.db import models
from django.utils import timezone
from django.urls import reverse
from embed_video.fields import EmbedVideoField
from django.contrib.auth.models import User
class Post(models.Model):
title = models.CharField(max_length = 100)
content = models.TextField()
video = EmbedVideoField()
date_posted = models.DateTimeField(default = timezone.now)
author = 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 PostComment(models.Model):
post = models.ForeignKey(Post, related_name='comments', on_delete = models.CASCADE)
author = models.ForeignKey(User, on_delete = models.CASCADE)
date_posted = models.DateTimeField(default = timezone.now)
body = models.TextField()
def __str__(self):
return f'{self.post} - {self.author}'

forms.py

from django import forms
from django.forms import ModelForm
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit, Fieldset, Button, Layout, Div, ButtonHolder, Field, Reset
from .models import Post, PostComment
from crispy_forms.bootstrap import FormActions
from django.urls import reverse
class CommentForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_method = 'POST'
self.fields['body'].required = True
self.fields['body'].label = False
self.helper.layout = Layout(
Field('body', style='max-height: 90px', placeholder='Write a comment...'),
ButtonHolder(
Submit('submit', 'Post', css_class='m-2 ms-3'),
Reset('Reset This Form', 'Cancel', css_class='btn btn-secondary')
),
)
class Meta:
model = PostComment
fields = ['body','post',]

views.py我主要是从django文档中得到的。

from django.shortcuts import render
from django.views.generic import (
ListView,
DetailView,
CreateView,
UpdateView,
DeleteView
)
from .models import Post, PostComment
from .forms import PostCreateForm, CommentForm
from django.views.generic.edit import FormMixin
class PostDetailView(FormMixin, DetailView):
model = Post
context_object_name = 'posts'
form_class = CommentForm
def get_success_url(self):
return reverse('post-detail', kwargs={'pk': self.object.id})
def get_context_data(self, **kwargs):
context = super(PostDetailView, self).get_context_data(**kwargs)
context['form'] = CommentForm(initial={'post': self.object})
return context
def post(self, request, *args, **kwargs):
self.object = self.get_object()
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
def form_valid(self, form):
form.save()
return super(PostDetailView, self).form_valid(form)

urls . py

urlpatterns = [
path('', PostListView.as_view(), name = 'home-home'),
path('post/new/', PostCreateView.as_view(), name = 'post-create'),
path('post/<int:pk>/', PostDetailView.as_view(), name = 'post-detail'),
]

post_detail.html

{% extends 'videosite/base.html' %}
{% load crispy_forms_tags %}
{% load embed_video_tags %}
{% block body %}
<div class="container mt-5">
<div class="card border-dark">
<div class="row row-cols-2 gutter-0">
<div class="col-7 pe-0" style="height: 526px;">
<div class="card-body border-end border-dark">
<div class="embed-responsive embed-responsive-16by9">
{% video posts.video '720x490' %}
</div>
</div>
</div>
<div class="col-5 ps-0" style="height: 526px;">
<div class="card-body bg-light" style="height: 526px;">
{% for comment in posts.comments.all %}
<a class="h5 text-dark text-decoration-none me-5" href="#"> {{ comment.author }}</a>
<span class="ms-3" >{{ comment.date_posted|date:"F d, Y" }}</span>
<p class="card-text">{{ comment.body }} </p>
{% endfor %}
</div>
{% csrf_token %}
{% crispy form %}
</div>
<div class="col-7 pe-0" >
<div class="card-body border-top border-end border-dark">
<h5><a class="fw-bold text-dark text-decoration-none" href="#">{{ posts.title }}</a></h5>
<p class="card-text">{{ posts.content }}</p>
</div>
<div class="card-body border-end border-dark" >
<span class="text-muted text-decoration-none">Posted by <a class="text-muted" href="#"> {{ posts.author }}</a> </span>
<span class="ms-3 text-muted" >{{ posts.date_posted|date:"F d, Y" }}</span>
</div>
</div>
</div>
</div>
</div>
{% endblock body %}

使用FormView而不是DetailView作为基类。我希望一切都能顺利。

一个无价的资源是Classy基于class的视图。它表明DetailView没有POST处理程序(方法),FormMixin也没有提供,这可能就是为什么你所拥有的不工作。

POST处理是由FormView自己定义的。

最新更新