Джанго Crispy Forms - флажок не отображается - PullRequest
0 голосов
/ 20 февраля 2019

Я пытаюсь добавить в форму логическое поле и отобразить его с тегами хрустящих форм.И все показано, кроме флажка.

Мой проект работает с django 2.1, python 3.6 и Bootstrap-4.Моя версия Django Crispy Forms: 1.7.2

Поле investment.

Поле модели не работает:

investment = models.BooleanField(default=False, help_text='Want to 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)

А для шаблона я пробовал два метода, но ни одиниз них сработало:

Мой шаблон 01:

Это метод, который я хочу использовать в конце.Отображение каждого злодея по отдельности, чтобы я мог сделать макет прямо на шаблоне.

...
{% 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>

Мой шаблон 02:

Этот использует непосредственно {{ form|crispy }} дляпоказать все элементы автоматически.

...
{% load crispy_forms_tags %}
...
<form id="my_form" method="post" enctype="multipart/form-data" novalidate>
                    {% csrf_token %}
                    {{ form|crispy }}
                    <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-код и обнаружил, где проблема, кажется, но я не знаю, как ее решить:

Создание хрустящих формэлемент, добавляющий соответствующие элементы 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>

Как вы можете видетьdiv с id находится внутри другого div.Итак, если я удалю класс этого дополнительного div (form-group) и изменим класс div на id: form-check для form-group, флажок появится и будет полностью функциональным.

Итак, моя идея - попытаться изменить шаблон, который хрустящие формы создали для флажка, но я не знаю, как это сделать.Кроме того, если есть другой лучший вариант, я открыт для них.

Ответы [ 3 ]

0 голосов
/ 20 февраля 2019

Это открытая проблема в github django-crispy-forms, см .: https://github.com/django-crispy-forms/django-crispy-forms/issues/787

В соответствии с этим проблема заключается в том, как bootsrap обрабатывает этот элемент формы в последней версии.Вот взлом JS, чтобы заставить его работать:

$(document).ready(function() {
    $( ":checkbox" ).each(function( index ) {
        $(this).prependTo($("#div_" + $(this).attr('id')))
    });
});
0 голосов
/ 21 февраля 2019

Я мог бы сделать половину хака для этого нужным мне элементом, используя следующий JS:

$(window).on('load',function(){
        $('#div_id_investment').addClass('form-group').removeClass('form-check');
});

Но это просто позволяет пользователю видеть и взаимодействовать с флажком, это не решает, что еслиполе является обязательным, и вы не нажимаете на него, сообщение об ошибке не появляется.

Если у кого-то есть улучшенный JS, чтобы сделать это для всех флажков и решить проблему с сообщением об ошибке, я буду признателен.

примечание: я не отмечаю это как действительноеответьте на вопрос, потому что ошибка все еще существует, и этот «взлом» не решает все проблемы.

0 голосов
/ 20 февраля 2019

Попробуйте изменить self.fields ['investment']. Required = False, потому что кажется, что поле не указано как необязательное, Django игнорирует его.

...