Python 在GenericForeignKey模型(CBV)的多个模板中包含表单

Python 在GenericForeignKey模型(CBV)的多个模板中包含表单,python,django,forms,generics,django-class-based-views,Python,Django,Forms,Generics,Django Class Based Views,为了了解更多关于Django的信息并了解如何尽可能干燥地编程,我正在构建一个具有以下几个功能的小型网站: 博文 后像 邮政书签 在这些应用程序中的每个对象上,用户都可以发表评论。所以我得到了 具有采用GenericForeignKey的模型的注释应用程序。(正常工作) 我想在博客、图像和书签的详细视图中显示评论表单。为了保持干燥,我创建了一个包含标签 @register.inclusion_tag('comments/add_comment.html') def show_comment_f

为了了解更多关于Django的信息并了解如何尽可能干燥地编程,我正在构建一个具有以下几个功能的小型网站:

  • 博文
  • 后像
  • 邮政书签
在这些应用程序中的每个对象上,用户都可以发表评论。所以我得到了 具有采用GenericForeignKey的模型的注释应用程序。(正常工作)

我想在博客、图像和书签的详细视图中显示评论表单。为了保持干燥,我创建了一个包含标签

@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>
在博客的细节模板中,它使用正确的参数呈现表单。当我点击SUBMIT按钮时,表单将在下面的Add视图中处理(当前仅获取表单、验证表单并通过服务将其添加到数据库)

但此解决方案不会返回带有验证错误的表单。我回到了基础,在博客的细节视图中创建了一个“硬编码”表单,但它既不灵活也不枯燥


有人能给我一个正确的方向吗?如何将这个表单(通过一个包含标签或其他建议的方法)转换成一个简单灵活的表单,在一个通用的内容类型上发表评论?

为了完成这个任务,我建议(正如你提到的)为AJAX实现评论并将其与AJAX混合

另一个适用于您的案例,可以将已验证的表单传递给您的包含标签(
show\u comment\u form


更改您的包含标记,这样它将根据对象类型在不同的URL上发布对的注释。还要更改它,这样,如果当前上下文中已经有
comment\u表单
,它就不会生成新表单。例如:

@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>
{#内容类型现在可能已过时}
{%trans“留下您的评论”%}。。。
{%csrf_令牌%}
{{form.as_div}}
创建视图mixin,它将添加到视图处理注释创建(或表单验证)中,从该内容和新mixin的普通视图中为每个内容类型创建新视图,并在单独的URL上注册该视图(以您在模板标记中创建
URL\u id
的方式命名该URL)

它是干的,灵活的,不需要太多的变化

@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}
@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>