Django:在通用DetailView中实现表单 [英] Django: Implementing a Form within a generic DetailView

查看:103
本文介绍了Django:在通用DetailView中实现表单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在浏览了多个Google搜索结果页面之后,我仍然拼命陷入同样的​​问题.我正在尝试在博客文章下实现评论字段.感谢您的任何提示和建议!

After working through several google search result pages, I am still desperately stuck at the same problem. I am trying to implement a comment field underneath a blog post. I am thankful for any hints and advice!

我正在开发Django中的Blog,该博客的第一个通用的ListView可以简要显示所有可用的博客文章,第二个通用的DetailView可以更详细地显示特定的博客文章.现在,我想在特定博客帖子下方放置一个add_comment_field,并在其下方显示所有其他注释.当注释表单显示在单独的页面上但与DetailView不在同一页面上时,它可以工作,这是理想的结果.

I am working on a Blog in Django which is set up with a first, generic ListView to display briefly all available blog posts and with a second, generic DetailView to show the specific blog post in more detail. I now want to place an add_comment_field underneath the specific blog post with all other comments shown underneath. It works when the comment form is displayed on a separate page but not on the same page as the DetailView, which is the desired outcome.

我怀疑这与views.py和forms.py之间的相互作用有关,但是我无法弄清楚问题所在.

I suspect this has to do with the interplay between views.py and forms.py but I cannot figure out the problem.

再次感谢您的帮助!

views.py

from django.shortcuts import render, get_object_or_404, redirect
from .models import Post, Comment
from .forms import CommentForm
from django.views.generic.detail import DetailView

class ParticularPost(DetailView):
    template_name='blog/post.html'
    model = Post

    def add_comment_to_post(self, pk):
        post = get_object_or_404(Post, pk=pk)
        if self.method == "POST":
            form = CommentForm(self.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 {'form': form}

urls.py

from django.conf.urls import url, include
from django.views.generic import ListView, DetailView
from .models import Post, Comment
from .views import ParticularPost

urlpatterns = [
    url(r'^$', ListView.as_view(queryset=Post.objects.all().order_by("-date")[:25], template_name="blog/blog.html")),
    url(r'^(?P<pk>\d+)$', ParticularPost.as_view(), name="post_detail"),
]

post.html

post.html

{% extends "personal/header.html" %}
{% load staticfiles %}
{% block content %}
<div class="container-fluid background_design2 ">
    <div class="header_spacing"></div>
    <div class="container post_spacing">
        <div class="row background_design1 blog_post_spacing inline-headers">
            <h3><a href="/blog/{{post.id}}">{{ post.title }}</a></h3>
            <h6> on {{ post.date }}</h6>
            <div class = "blog_text">
                {{ post.body|safe|linebreaks}}
            </div>
            <br><br>
        </div>
        <div>
            <form method="POST" class="post-form">{% csrf_token %}
        {{ form.as_p }}
        <button type="submit" class="save btn btn-default">Send</button>
    </form>
        </div>
        <div class=" row post_spacing background_design1 ">
            <hr>
            {% for comment in post.comments.all %}
                <div class=" col-md-12 comment">
                    <div class="date">{{ comment.created_date }}</div>
                    <strong>{{ comment.author }}</strong>
                    <p>{{ comment.text|linebreaks }}</p>
                </div>
            {% empty %}
                <p>No comments here yet :(</p>
            {% endfor %}
        </div>
    </div>
</div>
{% endblock %}

forms.py

from django import forms
from .models import Comment

class CommentForm(forms.ModelForm):

    class Meta:
        model = Comment
        fields = ('author', 'text',)

models.py

models.py

from django.db import models
from django.utils import timezone

class Post(models.Model):
    title = models.CharField(max_length=140)
    body = models.TextField()
    date = models.DateTimeField()

    def __str__(self):
        return self.title

class Comment(models.Model):
    post = models.ForeignKey('blog.Post', related_name='comments')
    author = models.CharField(max_length=200)
    text = models.TextField()
    created_date = models.DateTimeField(default=timezone.now)

    def __str__(self):
        return self.text

推荐答案

使用

Use FormMixin if you want combine DetailView and a form:

from django.shortcuts import render, get_object_or_404, redirect
from django.views.generic.detail import DetailView
from django.views.generic.edit import FormMixin
from .models import Post, Comment
from .forms import CommentForm


class ParticularPost(FormMixin, DetailView):
    template_name='blog/post.html'
    model = Post
    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(ParticularPost, 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(ParticularPost, self).form_valid(form)

不要忘记将post字段添加到表单中(您可以将其隐藏):

And don't forget to add the post field into the form (you can do it hidden):

class CommentForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = ('author', 'text', 'post',)

添加创建日期的更好方法-使用 auto_now_add=True :

And the better way to add a creation date - use auto_now_add=True:

created_date = models.DateTimeField(auto_now_add=True)

这篇关于Django:在通用DetailView中实现表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆