2015-07-27 2 views
1

У меня есть DetailView, который отображает Post. Теперь я хочу добавить возможность создать Comment для Post. Для этого мне нужно CommentForm, в пределах DetailView, чтобы я мог создавать комментарии, находясь на одной странице с Post.Django ModelForm в DetailView

Возможно ли это, или я должен искать другой подход, например, делать обработку формы вручную?

class Comment(models.Model): 
    body = models.TextField() 
    created_at = models.DateTimeField(auto_now_add=True) 
    author_name = models.CharField(max_length=255) 
    parent_post = models.ForeignKey('Post',related_name='comments') 

class PostDetailView(BlogMixin,DetailView): 
    """ A view for displaying a single post """ 
    template_name = 'post.html' 
    model = Post 
    #Add some code for the CommentForm here? 

class CommentForm(forms.ModelForm): 
    class Meta: 
     model = Comment 
     exclude = ("parent_post","created_at") 

    def create_view(request, **kwargs): 
     if request.method == "POST": 
      parent_fk = request.args['parent_fk'] #Im hoping to find how this will work soon 
      form = CommentForm(request.POST) 
      if form.is_valid(): 
       new_comment = form.save(commit=False) 
       new_comment.parent_post = parent_fk 
       new_comment.save() 
       return HttpResponseRedirect(request.META.get('HTTP_REFERER')) 

** Alternative **

Я пытался применить решение - A better alternative - но я получаю

Exception Value: __init__() takes exactly 1 argument (3 given) 
Exception Location: .../sitepackages/django/core/handlers/base.py in get_response, line 112 

и не были в состоянии проследить его пока.

class PostView(BlogMixin,DetailView): 
    """ A view for displaying a single post """ 
    template_name = 'post.html' 
    model = Post 
    def get_context_data(self, **kwargs): 
     context = super(PostView, self).get_context_data(**kwargs) 
     context['form'] = CommentForm() 
     return context 

class PostDetailView(View): 

    def get(self, request, *args, **kwargs): 
     view = PostView.as_view() 
     return view(request, *args, **kwargs) 

    def post(self, request, *args, **kwargs): 
     view = PostComment.as_view() 
     return view(request, *args, **kwargs) 

class PostComment( SingleObjectMixin , FormView): 
    template_name = 'post.html' 
    form_class = CommentForm 
    model = Post 

    def post(self, request, *args, **kwargs): 
     self.object = self.get_object() 
     return super(PostComment, self).post(request, *args, **kwargs) 

    def get_success_url(self): 
     return reverse('post-detail', kwargs={'pk': self.object.pk}) 
class BlogMixin(object): 
    """ 
    Basic mixin for all the views. Update the context with additional 
    information that is required across the whole site, typically 
    to render base.html properly 
    """ 
    def get_context_data(self, *args, **kwargs): 
     context = super(BlogMixin, self).get_context_data(*args, **kwargs) 
     blog = Blog.get_unique() 
     context.update({ 
      'blog': blog, 
      'active_user': users.get_current_user(), 
      'is_admin': users.is_current_user_admin() 
     }) 
     return context 

urls.py: URL (г '^ пост/(Р [\ d] +)/$?', Views.PostDetailView, имя = "пост-деталь".),

ответ

0

В конце концов, я не мог заставить его работать с переадресацией, но следующий работает:

class PostDetailView(BlogMixin,CreateView): 
    """ A view for displaying a single post """ 
    template_name = 'post.html' 
    model = Comment 
    fields = ['body','author_name'] 
    def get_context_data(self, **kwargs): 

     context = super(PostDetailView, self).get_context_data(**kwargs) 
     context['post'] = Post.objects.get(pk=self.kwargs['pk']) 
     return context 

    def form_valid(self, form): 
     # self.object = form.save() 
     obj = form.save(commit=False) 
     obj.parent_post = Post.objects.get(pk=self.kwargs['pk']) 
     obj.save() 

     return redirect('post-detail', self.kwargs['pk']) 
1

Если вы хотите использовать свой первый метод, вы можете сделать FK скрытым полем. На ваш взгляд, вы можете сохранить FK перед тем, как комментировать базу данных. Как это:

if form.is_valid(): 
    comment = form.save(commit=False) 
    comment.parent_post = parent_post 
    comment.save() 

Edit: Если вы хотите получать комментарии, то вы можете использовать фильтр по почте, чтобы получить QuerySet комментариев.

+0

Я предположил, что почта будет работать в шаблоне? Хавент добрался так далеко. – Giannis

+0

Вам необходимо отправить комментарии, связанные с «Постом», в словарь при визуализации. –

+0

{% for comment in post.comments.all%} работает. Я также задал порядок в классе модели, используя: класс Meta: ordering = ["-created_at"] – Giannis

0

Почему бы вам не отправить форму в контексте с точки зрения детализации:

class YourDetailView(DetailView): 
    #Your stuff here 
    def get_context_date(self, **kwargs): 
     context = super(YOurDetailView, self).get_context_data(**kwargs) 
     context['form'] = YourForm 
     return context 

PS. Ищите параметры в get_context_date ..

+0

Следуя советам в google-группах, я вместо этого использую CreateView. См. Мой ответ – Giannis