使用布局切片时,Django脆皮表单“提供给{%crispy%}标记的辅助对象必须是crispy.helper.FormHelper对象”

时间:2020-11-06 14:57:03

标签: python django django-crispy-forms

尝试访问表单的一部分时出现helper object provided to {% crispy %} tag must be a crispy.helper.FormHelper object错误。如下面的 forms.py 所示,我想使用布局切片(https://django-crispy-forms.readthedocs.io/en/latest/dynamic_layouts.html)访问第一个Div,这样我只能在选项卡中显示该Div。在我的HTML中。在下面的 ref_detail.html 中,我尝试使用{% crispy form form_helper.0 %}完成此操作。我也尝试过{% crispy form form_helper[0] %},但这也不起作用。

python版本3.8.3 django版本3.1.2

views.py

from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render
from django.urls import reverse_lazy

from crispy_forms.utils import render_crispy_form

from .models import reference
from .forms import ReferenceForm

def ref_detail(request, ref_id):

    try:
        ref = reference.objects.get(pk=ref_id)
    except ref.DoesNotExist:
        raise Http404("Reference does not exist")
    
    #If this is a POST request, process the form data
    if request.method == 'POST':
        #create a form instance and populate it with data from the request
        form = ReferenceForm(request.POST)
        #check whether it's valid
        if form.is_valid():
            #process the data in form.cleaned_data as required (i.e. save to database, etc.)
            #...
            print(form.cleaned_data)
            new_reference = form.save() #save a new reference object to the database, from the form's data
            #redirect to a new URL:
            return HttpResponseRedirect('thanks/')
    #if a GET (or any other method) we'll create a blank form
    else:
        form = ReferenceForm()
    
    return render(request, 'test_cedar_app/ref_detail.html', {'ref': ref, 'form': form, 'form_helper': form.helper})

forms.py

from django.forms import ModelForm
from django import forms
from test_cedar_app.models import factor, reference
from django.utils.translation import gettext_lazy as _

from crispy_forms.bootstrap import Tab, TabHolder, FormActions
from crispy_forms.helper import FormHelper
from crispy_forms.layout_slice import LayoutSlice
from crispy_forms.layout import Submit, Layout, Div
from crispy_forms.utils import render_crispy_form

class ReferenceForm(ModelForm):
    class Meta:
        model = reference
        fields = '__all__'
        
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_tag = False
        self.helper.layout = Layout(
            Div('study_title', 
                'name_author',
                'publication_year',
                'publisher',
                'ident_doi',
                'ident_pmid',
                'exclude_extraction',
                'exclude_extraction_reason',
                css_id='main-tab-md',
                css_class='tab-pane fade show active',
            ), 
            Div('study_design',
                'study_design_detail',
                'study_sample_method',
                'ast_method',
                'has_breakpoint',
                'has_mic_table',
                css_id='study-tab-md',
                css_class='tab-pane fade',
            ),
        )

ref_detail.html

{% extends './base.html' %}

<!-- {% load static %} -->

{% load crispy_forms_tags %}

{% load widget_tweaks %}


{% block content %}
    <form action="" method="post" id="leadform" enctype="multipart/form-data" role="form">
        {% csrf_token %}
        <ul class="nav nav-tabs md-tabs" id="myTabMD" role="tablist">
            <li class="nav-item">
                <a class="nav-link active" id="main-tab-md" data-toggle="tab" href="#main-md" role="tab" aria-controls="main-md"
                    aria-selected="true">Main</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" id="study-tab-md" data-toggle="tab" href="#study-md" role="tab" aria-controls="study-md"
                    aria-selected="false">Study Design</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" id="location-tab-md" data-toggle="tab" href="#location-md" role="tab" aria-controls="location-md"
                    aria-selected="false">Location</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" id="history-tab-md" data-toggle="tab" href="#history-md" role="tab" aria-controls="history-md"
                    aria-selected="false">History</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" id="notes-tab-md" data-toggle="tab" href="#notes-md" role="tab" aria-controls="notes-md"
                    aria-selected="false">Notes and Issues</a>
            </li>
        </ul>
        <div class="tab-content card pt-5" id="myTabContentMD">
            <div class="tab-pane fade show active" id="main-md" role="tabpanel" aria-labelledby="main-tab-md">
                {% crispy form form_helper.0 %}
            </div>
            <div class="tab-pane fade" id="study-md" role="tabpanel" aria-labelledby="study-tab-md">
                <p>Study</p>
            </div>
            <div class="tab-pane fade" id="location-md" role="tabpanel" aria-labelledby="location-tab-md">
                <p>Location</p>
            </div>
            <div class="tab-pane fade" id="history-md" role="tabpanel" aria-labelledby="history-tab-md">
                <p>History</p>
            </div>
            <div class="tab-pane fade" id="notes-md" role="tabpanel" aria-labelledby="notes-tab-md">
                <p>Notes</p>
            </div>
        </div>
    </form>
{% endblock %}

base.html

{% load static %}

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
    <title>Update a Reference</title>
    <script src="http://code.jquery.com/jquery-1.9.1.js">
    </script>
    <script src="http://code.jquery.com/ui/1.11.0/jquery-ui.js">
    </script>
    <script type="text/javascript" src="{% static 'bootstrap-tab.js' %}"> </script>

    <!-- MDB icon -->
    <link rel="icon" href="{% static 'img/mdb-favicon.ico' %}" type="image/x-icon">
    <!-- Font Awesome -->
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.11.2/css/all.css">
    <!-- Google Fonts Roboto -->
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap">
    <!-- Bootstrap core CSS -->
    <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
    <!-- Material Design Bootstrap -->
    <link rel="stylesheet" href="{% static 'css/mdb.min.css' %}">
    <!-- Your custom styles (optional) - -->
    
  </head>
  <body>
    <div class="container">
      <div class="row justify-content-left">
        <div class="col-8">
          <h1 class="mt-2">{{ref.study_title}}</h1>
          <hr class="mt-0 mb-4">
          {% block content %}
          {% endblock %}
        </div>
      </div>
    </div>

    <!-- SCRIPTS -->
    <!-- jQuery -->
    <script type="text/javascript" src="{% static 'js/jquery.min.js' %}"></script>
    <!-- Bootstrap tooltips -->
    <script type="text/javascript" src="{% static 'js/popper.min.js' %}"></script>
    <!-- Bootstrap core JavaScript -->
    <script type="text/javascript" src="{% static 'js/bootstrap.min.js' %}"></script>
    <!-- MDB core JavaScript -->
    <script type="text/javascript" src="{% static 'js/mdb.min.js' %}"></script>
    <!-- MDBootstrap Datatables  -->
    <!-- <script type="text/javascript" src="{% static 'js/addons/datatables.min.js' %}"></script> -->
    <!-- Your custom scripts (optional) -->

  </body>
</html>

1 个答案:

答案 0 :(得分:0)

您可以在视图中删除布局对象。最后几行如下:

    form = ReferenceForm()
    form.helper.layout.pop(1)

return render(request, 'test_cedar_app/ref_detail.html', {'ref': ref, 'form': form})

然后像平常一样显示表单:

{% crispy form %}
相关问题