Django Crispy表单-未显示复选框

Django Crispy表单-未显示复选框,django,django-templates,bootstrap-4,django-crispy-forms,Django,Django Templates,Bootstrap 4,Django Crispy Forms,我试图在我的表单上添加一个布尔字段,并用crispyforms标记呈现它。除复选框外,所有内容都显示出来 我的项目使用django 2.1、python 3.6和Bootstrap-4。我的Django Crispy Forms版本是:1.7.2 该字段为投资 模型字段不工作: class CreateProjectForm(forms.ModelForm): class Meta: model = Project fields = ('name', 's

我试图在我的表单上添加一个布尔字段,并用crispyforms标记呈现它。除复选框外,所有内容都显示出来

我的项目使用django 2.1、python 3.6和Bootstrap-4。我的Django Crispy Forms版本是:1.7.2

该字段为
投资

模型字段不工作:

class CreateProjectForm(forms.ModelForm):
    class Meta:
        model = Project
        fields = ('name', 'short_description', 'category', 'investment')
        widgets = {
            'name': forms.TextInput(attrs={'placeholder': 'enter the project name here...'}),
            'short_description': forms.Textarea(attrs={'rows': '2', 'maxlength': '135', 'class': 'textarea-limited',
                                                        'placeholder': 'enter a short description of your project limited to 135 characters'}),
        }

    def __init__(self, *args, **kwargs):
        # first call parent's constructor
        super(CreateProjectForm, self).__init__(*args, **kwargs)
        # there's a `fields` property now
        self.fields['investment'].required = True
        self.fields['investment'].widget = forms.CheckboxInput()
        self.fields['name'].widget = forms.TextInput(
            attrs={'placeholder': 'enter the project name here...'})
        self.fields['short_description'].widget = forms.Textarea(
            attrs={'rows': '2',
                   'maxlength': '135',
                   'class': 'textarea-limited',
                   'placeholder': 'enter a short description of your project limited to 135 characters'})
        # evade all labels and help text to appear when using "as_crispy_tag"
        self.helper = FormHelper(self)
        self.helper.form_show_labels = False
        self.helper._help_text_inline = True

class ProjectCreateView(SuccessMessageMixin, generic.CreateView):
    template_name = 'webplatform/project_create_form.html'
    model = Project
    form_class = CreateProjectForm
    success_message = 'Project created! Now try to add all the details and then publish it!'

    def get_success_url(self):
        return reverse_lazy('project-edit-general', args=(self.object.id,))

    # Set field as current user
    def form_valid(self, form):
        form.instance.user = self.request.user
        form.instance.start_date = timezone.now()
        form.instance.history_change_reason = 'Project Created'
        return super(ProjectCreateView, self).form_valid(form)
investment=models.BooleanField(默认值=False,帮助_text='Want accept Investments?'))
我的表格:

class CreateProjectForm(forms.ModelForm):
    class Meta:
        model = Project
        fields = ('name', 'short_description', 'category', 'investment')
        widgets = {
            'name': forms.TextInput(attrs={'placeholder': 'enter the project name here...'}),
            'short_description': forms.Textarea(attrs={'rows': '2', 'maxlength': '135', 'class': 'textarea-limited',
                                                        'placeholder': 'enter a short description of your project limited to 135 characters'}),
        }

    def __init__(self, *args, **kwargs):
        # first call parent's constructor
        super(CreateProjectForm, self).__init__(*args, **kwargs)
        # there's a `fields` property now
        self.fields['investment'].required = True
        self.fields['investment'].widget = forms.CheckboxInput()
        self.fields['name'].widget = forms.TextInput(
            attrs={'placeholder': 'enter the project name here...'})
        self.fields['short_description'].widget = forms.Textarea(
            attrs={'rows': '2',
                   'maxlength': '135',
                   'class': 'textarea-limited',
                   'placeholder': 'enter a short description of your project limited to 135 characters'})
        # evade all labels and help text to appear when using "as_crispy_tag"
        self.helper = FormHelper(self)
        self.helper.form_show_labels = False
        self.helper._help_text_inline = True

class ProjectCreateView(SuccessMessageMixin, generic.CreateView):
    template_name = 'webplatform/project_create_form.html'
    model = Project
    form_class = CreateProjectForm
    success_message = 'Project created! Now try to add all the details and then publish it!'

    def get_success_url(self):
        return reverse_lazy('project-edit-general', args=(self.object.id,))

    # Set field as current user
    def form_valid(self, form):
        form.instance.user = self.request.user
        form.instance.start_date = timezone.now()
        form.instance.history_change_reason = 'Project Created'
        return super(ProjectCreateView, self).form_valid(form)
我的观点:

class CreateProjectForm(forms.ModelForm):
    class Meta:
        model = Project
        fields = ('name', 'short_description', 'category', 'investment')
        widgets = {
            'name': forms.TextInput(attrs={'placeholder': 'enter the project name here...'}),
            'short_description': forms.Textarea(attrs={'rows': '2', 'maxlength': '135', 'class': 'textarea-limited',
                                                        'placeholder': 'enter a short description of your project limited to 135 characters'}),
        }

    def __init__(self, *args, **kwargs):
        # first call parent's constructor
        super(CreateProjectForm, self).__init__(*args, **kwargs)
        # there's a `fields` property now
        self.fields['investment'].required = True
        self.fields['investment'].widget = forms.CheckboxInput()
        self.fields['name'].widget = forms.TextInput(
            attrs={'placeholder': 'enter the project name here...'})
        self.fields['short_description'].widget = forms.Textarea(
            attrs={'rows': '2',
                   'maxlength': '135',
                   'class': 'textarea-limited',
                   'placeholder': 'enter a short description of your project limited to 135 characters'})
        # evade all labels and help text to appear when using "as_crispy_tag"
        self.helper = FormHelper(self)
        self.helper.form_show_labels = False
        self.helper._help_text_inline = True

class ProjectCreateView(SuccessMessageMixin, generic.CreateView):
    template_name = 'webplatform/project_create_form.html'
    model = Project
    form_class = CreateProjectForm
    success_message = 'Project created! Now try to add all the details and then publish it!'

    def get_success_url(self):
        return reverse_lazy('project-edit-general', args=(self.object.id,))

    # Set field as current user
    def form_valid(self, form):
        form.instance.user = self.request.user
        form.instance.start_date = timezone.now()
        form.instance.history_change_reason = 'Project Created'
        return super(ProjectCreateView, self).form_valid(form)
对于模板,我尝试了两种方法,但都不起作用:

我的模板01:

class CreateProjectForm(forms.ModelForm):
    class Meta:
        model = Project
        fields = ('name', 'short_description', 'category', 'investment')
        widgets = {
            'name': forms.TextInput(attrs={'placeholder': 'enter the project name here...'}),
            'short_description': forms.Textarea(attrs={'rows': '2', 'maxlength': '135', 'class': 'textarea-limited',
                                                        'placeholder': 'enter a short description of your project limited to 135 characters'}),
        }

    def __init__(self, *args, **kwargs):
        # first call parent's constructor
        super(CreateProjectForm, self).__init__(*args, **kwargs)
        # there's a `fields` property now
        self.fields['investment'].required = True
        self.fields['investment'].widget = forms.CheckboxInput()
        self.fields['name'].widget = forms.TextInput(
            attrs={'placeholder': 'enter the project name here...'})
        self.fields['short_description'].widget = forms.Textarea(
            attrs={'rows': '2',
                   'maxlength': '135',
                   'class': 'textarea-limited',
                   'placeholder': 'enter a short description of your project limited to 135 characters'})
        # evade all labels and help text to appear when using "as_crispy_tag"
        self.helper = FormHelper(self)
        self.helper.form_show_labels = False
        self.helper._help_text_inline = True

class ProjectCreateView(SuccessMessageMixin, generic.CreateView):
    template_name = 'webplatform/project_create_form.html'
    model = Project
    form_class = CreateProjectForm
    success_message = 'Project created! Now try to add all the details and then publish it!'

    def get_success_url(self):
        return reverse_lazy('project-edit-general', args=(self.object.id,))

    # Set field as current user
    def form_valid(self, form):
        form.instance.user = self.request.user
        form.instance.start_date = timezone.now()
        form.instance.history_change_reason = 'Project Created'
        return super(ProjectCreateView, self).form_valid(form)
这是我想在最后使用的方法。单独显示每个恶魔,以便我可以直接在模板上进行布局

...
{% load crispy_forms_tags %}
...
<form id="my_form" method="post" enctype="multipart/form-data" novalidate>
                    {% csrf_token %}
                    <div class="row">
                        <div class="col-md-5 col-sm-5">
                            <h6>Name
                                <span class="icon-danger">*</span>
                            </h6>
                            {{ form.name|as_crispy_field }}

                            <h6>Categories
                                <span class="icon-danger">*</span>
                            </h6>
                            {{ form.category|as_crispy_field }}

                        </div>
                        <div class="col-md-7 col-sm-7">
                            <h6>Short Description
                                <span class="icon-danger">*</span>
                            </h6>
                            {{ form.short_description|as_crispy_field }}
                            <h5>
                                <small>
                                    <span id="textarea-limited-message" class="pull-right">135 characters left</span>
                                </small>
                            </h5>
                            <h6>Investment
                                <span class="icon-danger">*</span>
                            </h6>
                            {{ form.investment|as_crispy_field }}
                        </div>
                    </div>
                    <div class="row buttons-row">
                        <div class="col-md-4 col-sm-4">
                            <button type="submit" class="btn btn-outline-primary btn-block btn-round">Create</button>
                        </div>
                    </div>
                </form>
我检查了呈现的HTML,发现问题似乎在哪里,但我不知道如何解决它:

Crispy表单创建一个元素,添加相应的div和其他必要的元素,例如在名称输入上:

<div id="div_id_name" class="form-group"> 
        <label for="id_name" class="col-form-label  requiredField">Name
            <span class="asteriskField">*</span> 
        </label> 
    <div class=""> 
        <input type="text" name="name" placeholder="enter the project name here..." class="textinput textInput form-control" required="" id="id_name"> 
            <small id="hint_id_name" class="form-text text-muted">Add a title to your project.</small> 
    </div> 
</div>

名称
* 
为项目添加标题。
但对于复选框,将创建以下结构:

<div class="form-group"> 
    <div id="div_id_investment" class="form-check"> 
        <label for="id_investment" class="form-check-label requiredField"> 
            <input type="checkbox" name="investment" class="checkboxinput form-check-input" required="" id="id_investment">
                    Investment
                <span class="asteriskField">*</span> 
        </label> 
        <small id="hint_id_investment" class="form-text text-muted">Want to accept Investments?</small> 
    </div> 
</div>

投资
* 
想要接受投资吗?
如您所见,带有
id
div
位于另一个
div
中。那么,如果我删除这个额外的
div
formgroup
)的类,并用
id
更改
div
的类:
formcheck
,对于
formgroup
,复选框就会出现,并且功能完全正常


所以我的想法是尝试更改crispy表单为复选框创建的模板,但我不知道如何做到这一点。另外,如果还有其他更好的选择,我愿意接受。

尝试更改self.fields['investment'].required=False,因为似乎因为该字段未指定为可选,Django会忽略它。

尝试更改self.fields['investment'].required=False,'原因似乎是因为该字段未指定为可选Django会忽略它。

它们在Django crispy forms github中是一个开放问题,请参见:

根据这一点,问题在于bootsrap在上一版本中处理此表单元素的方式。 下面是一个js破解程序:

$(document).ready(function() {
    $( ":checkbox" ).each(function( index ) {
        $(this).prependTo($("#div_" + $(this).attr('id')))
    });
});

它们是django crispy表单的公开发行版,请参见:

根据这一点,问题在于bootsrap在上一版本中处理此表单元素的方式。 下面是一个js破解程序:

$(document).ready(function() {
    $( ":checkbox" ).each(function( index ) {
        $(this).prependTo($("#div_" + $(this).attr('id')))
    });
});

通过使用以下JS,我可以通过所需的元素对此进行半破解:

$(window).on('load',function(){
        $('#div_id_investment').addClass('form-group').removeClass('form-check');
});
但这只是让用户看到复选框并与之交互,并不能解决如果该字段是必需的,而您没有单击它,则不会显示错误消息的问题

如果任何人有一个改进的JS,使所有的复选框,并解决了错误消息的问题,我将不胜感激


注意:我没有将此标记为问题的有效答案,因为错误仍然存在,并且此“hack”并不能解决所有问题。

我可以通过使用以下JS使用所需的元素对此进行半破解:

$(window).on('load',function(){
        $('#div_id_investment').addClass('form-group').removeClass('form-check');
});
但这只是让用户看到复选框并与之交互,并不能解决如果该字段是必需的,而您没有单击它,则不会显示错误消息的问题

如果任何人有一个改进的JS,使所有的复选框,并解决了错误消息的问题,我将不胜感激


注意:我没有将此标记为问题的有效答案,因为错误仍然存在,而此“黑客”并不能解决所有问题。

它不起作用。一切都和我第一次尝试一样。我还试图删除所有小部件和帮助程序,每次都是一样的,但不起作用。一切都和我第一次尝试一样。我还试图删除所有小部件和帮助程序,每次都是这样。我将这个JS添加到我的项目中,但没有成功。它保持不变。我尝试将此JS添加到标题和正文的末尾,但没有任何效果。您是否像这样导入jquery:
是的,也尝试了标题和正文的末尾。我将此JS添加到我的项目中,但不起作用。它保持不变。我试着将这个JS添加到标题和正文的末尾,但是什么都没有。你是否像这样导入jquery:
是的,在标题和正文的末尾也尝试过。