2016-01-03 34 views
0

要了解更多關於Django和了解如何儘可能乾燥,我建立一個小網站,一對夫婦的功能設定多個模板形式:包括在GenericForeignKey模型(CBV)

  • 郵報博客
  • 後的圖像
  • 帖子收藏

在這些每個今日對象,用戶可以發表評論。所以我得到了 一個帶有GenericForeignKey的模型的評論APP。 (正常工作)

我想在博客,圖像和書籤的詳細信息視圖中顯示評論表單。爲了保持乾燥,我創建了一個包含標籤

@register.inclusion_tag('comments/add_comment.html') 
def show_comment_form(obj): 
    pk = obj.pk 
    content_type = ContentType.objects.get_for_model(obj) 
    form = AddCommentForm() 

    return {'pk': pk, 'content_type': content_type, 'form': form} 

它使用下面的模板呈現形式:

<form action="{% url 'comments:add' pk content_type %}" method="post"> 
    <div class="create-blog-container"> 
     <div class="box-top">{% trans "Leave your comment behind" %}...</div> 
     <div class="box-content"> 
      {% csrf_token %} 
      {{ form.as_div }} 
     </div> 
     <div class="box-footer"> 
      <input type="submit" class="btn btn-green" value="{% trans 'Add comment' %}" /> 
     </div> 
</form> 

當添加

{% show_comment_form blog %} 

在博客的詳細信息模板它使用正確的參數呈現窗體。當我點擊SUBMIT按鈕時,表單在下面的Add視圖中處理(當前只是通過一個服務接受表單,驗證並將其添加到數據庫中)。

class Add(LoginRequiredMixin, View): 
    model = Comment 

    def post(self, *args, **kwargs): 
     content_type = self.kwargs.get('content_type') 
     pk = self.kwargs.get('pk') 
     form = AddCommentForm(self.request.POST) 

     if form.is_valid(): 
      content = form.cleaned_data.get('content') 
      comments.services.comment.add(content_type, pk, self.request.user, content) 
      messages.add_message(self.request, messages.SUCCESS, _("Your comment has been posted")) 
     else: 
      print(form.errors) 

     return HttpResponseRedirect(reverse('blogs:detail', kwargs={'pk': pk})) 

但是,此解決方案不會回報帶有驗證錯誤的表單。我回到了基本要求,在博客的詳細視圖中創建了一個「硬編碼」表單,但它不靈活,也不幹。

有人能給我一個正確的方向,如何將這種形式(通過包含標籤,或其他建議的方法)轉換爲乾燥和靈活的形式發表評論一般的content_type?

回答

0

爲了完成DRY,我建議(如您所述)實施對Django contenttypes的評論並將其與AJAX混合使用。

另一個用於你的情況有可能生效的形式傳遞給你包含標籤(show_comment_form

@register.inclusion_tag('comments/add_comment.html') 
def show_comment_form(obj, form=None): 
    pk = obj.pk 
    content_type = ContentType.objects.get_for_model(obj) 
    form = form or AddCommentForm() 

    return {'pk': pk, 'content_type': content_type, 'form': form} 
0

更改包含標籤,所以它會發布意見,對不同的URL,這取決於對象類型。還要更改它,因此如果當前上下文中已有comment_form,它將不會創建新表單。例如:

@register.inclusion_tag('comments/add_comment.html', takes_context=True) 
def show_comment_form(context, obj): 
    pk = obj.pk 
    content_type = ContentType.objects.get_for_model(obj) 
    form = context.get('comment_form', AddCommentForm()) 

    url_id = "%s:%s:comment:add" % (content_type.app_label, content_type.model) 

    return {'pk': pk, 'content_type': content_type, 'form': form, url_id} 

模板:

{# content_type may be obsolete now #} 
<form action="{% url url_id pk content_type %}" method="post"> 
    <div class="create-blog-container"> 
     <div class="box-top">{% trans "Leave your comment behind" %}...</div> 
     <div class="box-content"> 
      {% csrf_token %} 
      {{ form.as_div }} 
     </div> 
     <div class="box-footer"> 
      <input type="submit" class="btn btn-green" value="{% trans 'Add comment' %}" /> 
     </div> 
</form> 

創建視圖混入,將添加到您的視圖處理註釋創建(或表單驗證),建立從普通視圖爲每個內容類型的新觀點該內容和您的新mixin並在單獨的URL上註冊該視圖(將URL命名爲您在模板標記中創建url_id的方式)。

乾燥,靈活,不需要很多的變化。