2017-08-13 1 views
1

générique Après avoir travaillé plusieurs pages de résultats de recherche Google, je suis toujours bloqué désespérément au même problème. J'essaie de mettre en place un champ de commentaire sous un article de blog. Je suis reconnaissant pour tous les conseils et astuces!Django: La mise en œuvre d'un formulaire dans un DetailView

Je travaille sur un blog dans Django qui est mis en place avec un premier ListView générique pour afficher brièvement tous les billets de blog disponibles et avec un second, DetailView générique pour afficher le blog plus en détail. Je veux maintenant placer un add_comment_field sous la publication de blog spécifique avec tous les autres commentaires montrés ci-dessous. Cela fonctionne lorsque le formulaire de commentaire est affiché sur une page séparée, mais pas sur la même page que le détail, qui est le résultat souhaité.

Je suppose que cela a à voir avec l'interaction entre views.py et forms.py mais je n'arrive pas à comprendre le problème.

Encore une fois, merci beaucoup pour votre aide!

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

{% 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

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 

Répondre

2

Utilisez FormMixin si vous voulez combiner DetailView et une forme:

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) 

Et ne pas oublier d'ajouter le champ post dans la forme (vous pouvez le faire caché):

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

Et la meilleure façon d'ajouter une date de création - utiliser auto_now_add=True:

created_date = models.DateTimeField(auto_now_add=True)