Crispy Forms: FormHelper для разделенных форм / два столбца одной модели - PullRequest
1 голос
/ 06 марта 2019

Мой шаблон разделен на две колонки.У меня есть только одна модель, но я хочу разделить форму на две части, одну часть в первом столбце, другую часть во втором столбце.Я стремлюсь использовать FormHelper для Crispy Forms.

Доступная документация дает загадочный намек, но без каких-либо примеров такая попытка объяснения оказывается несколько неудачной.

https://django -crispy-forms.readthedocs.io/en/d-0/tags.html#rendering-several-forms-with-helpers

Рендеринг нескольких форм с помощниками

Часто нас спрашивают: «Как вы отображаете две или более форм с их соответствующими помощниками, используя тег {% crispy%}, без отображения тегов дважды?» Легко , вам нужноУстановите для свойства помощника form_tag значение False для каждого помощника:

self.helper.form_tag = False

Затем вам придется написать небольшой HTML-код, окружающий формы:

<form action="{% url submit_survey %}" class="uniForm" method="post">
    {% crispy first_form %}
    {% crispy second_form %}
</form>

ОБНОВЛЕНИЕ: В этом посте объясняется, что такое документация Crispy. Определение контекстных имен хрустящих форм для двух форм в одной

Ниже приведен мой код.Два FormHelper делят модель на две части, первая часть с полями: ['car_model_make', 'status_is_secondhand'] вторая часть с полями: ['seller', 'buyer']

То, что я искал, это способ «вызвать» конкретный {% crispy form %}.Учитывая "справочную" документацию ", она будет выглядеть как {% crispy product-modelform_1 %} и {% crispy product-modelform_2 %}, которая не работает.

# models.py
class Product(models.Models):
    car_model_make = models.CharField(default='B', max_length=1, blank=True, choices=CAR_TYPE)
    status_is_secondhand = models.BooleanField(blank=True)
    seller = models.CharField(max_length=50, blank=True, choices=SELLER_TYPE)
    buyer = models.CharField(max_length=50, blank=True, choices=BUYER_TYPE)

# forms.py
class ProductForm(ModelForm):
    class Meta:
        model = Product
        fields = ('__all__')

    def __init__(self, *args, **kwargs):
        super(ProductForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_class = 'form-horizontal'
        self.helper.label_class = 'col-sm-4'
        self.helper.field_class = 'col-sm-8'
        self.helper.form_id = 'product-modelform'
        self.helper.form_tag = False


        model = 'car_model_make'
        secondhand = 'status_is_secondhand'

        self.fields[model].label = "Model"
        self.fields[secondhand].label = "Is Secondhand"

        self.helper.layout = Layout(
            Field(model),
            Field(secondhand),
            )

    def __init__(self, *args, **kwargs):
        super(ProductForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_class = 'form-horizontal'
        self.helper.label_class = 'col-sm-4'
        self.helper.field_class = 'col-sm-8'
        self.helper.form_id = 'product-modelform'
        self.helper.form_tag = False


        seller = 'seller'
        buyer = 'buyer'

        self.fields[seller].label = "Seller"
        self.fields[buyer].label = "buyer"

        self.helper.layout = Layout(
            Field(seller),
            Field(buyer),
            )

# views.py
class ProductFormView(FormView):
    form_class = ProductForm

    def form_valid(self, form):
        form.save()
        return super().form_valid(form)

    def get_success_url(self):
        return reverse('index')

# urls.py
urlpatterns = [
    path('', index, name='index'),
    path('product/', ProductFormView.as_view(template_name='product/product.html'),


# html template

{% extends "product/base.html" %}
{% load crispy_forms_tags %}

{% block col8_content %}
<form id="product-modelform" method="post">
    {% csrf_token %}
    {% crispy form %}
    {% endblock col8_content %}
    {% block col4_content %}   
</form>
    {% endblock col4_content %}
    <input type="submit" value="Submit">

Ответы [ 2 ]

1 голос
/ 06 марта 2019

У вас не может быть двух __init__ методов, и он вам на самом деле не нужен. Вы можете просто заключить эти два «столбца» в два отдельных тега <div> с помощью FormHelper ().

def __init__(self, *args, **kwargs):
      super(ProductForm, self).__init__(*args, **kwargs)
      self.helper = FormHelper()
      self.helper.form_class = 'form-horizontal'
      self.helper.label_class = 'col-sm-4'
      self.helper.field_class = 'col-sm-8'
      self.helper.form_id = 'product-modelform'
      self.helper.form_tag = False
      self.helper.layout = Layout(
      Div(
        Div('car_model_make','status_is_secondhand', css_class='col-lg-6 col-md-6 col-sm-12'),
        Div('seller','buyer', css_class='col-lg-6 col-md-6 col-sm-12'),
        css_class='row'
        )
      )

Надеюсь, это дает вам хитрость. См. Макеты для более.

0 голосов
/ 07 марта 2019

На данный момент это работает (в основном вдохновлено Определите имена контекста хрустящих форм для двух форм в одной , но здесь я создал две новые формы на основе ModelForm): Мне бы хотелось, чтобы я полностью понял решение лучше сам, но, по крайней мере, работает как задумано.

# models.py
class Product(models.Models):
    car_model_make = models.CharField(default='B', max_length=1, blank=True, choices=CAR_TYPE)
    status_is_secondhand = models.BooleanField(blank=True)
    seller = models.CharField(max_length=50, blank=True, choices=SELLER_TYPE)
    buyer = models.CharField(max_length=50, blank=True, choices=BUYER_TYPE)

# forms.py
class ProductForm(ModelForm):
    class Meta:
        model = Product
        fields = ('__all__')

class CarForm(ProductForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_class = 'form-horizontal'
        self.helper.label_class = 'col-sm-4'
        self.helper.field_class = 'col-sm-8'
        self.helper.form_tag = False
        self.helper.add_input(Submit('submit', 'Submit'))

        model = 'car_model_make'
        secondhand = 'status_is_secondhand'

        self.fields[model].label = "Model"
        self.fields[secondhand].label = "Is Secondhand"

        self.helper.layout = Layout(
            Field(model),
            Field(secondhand),
            )

class TransactionForm(ProductForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_class = 'form-horizontal'
        self.helper.label_class = 'col-sm-4'
        self.helper.field_class = 'col-sm-8'
        self.helper.form_tag = False


        seller = 'seller'
        buyer = 'buyer'

        self.fields[seller].label = "Seller"
        self.fields[buyer].label = "buyer"

        self.helper.layout = Layout(
            Field(Seller),
            Field(buyer),
            )

# views.py
class ProductFormView(FormView):
    form_class = CarForm
    model = Product

    def get_context_data(self, **kwargs):
        context = super(ProductFormView, self).get_context_data(**kwargs)
        context['form_2'] = TransactionForm(instance=self.model())
        return context

    def form_valid(self, form):
        self.object = form.save()
        return HttpResponseRedirect(self.get_success_url())

    def form_invalid(self, form):
        return self.render_to_response(
            self.get_context_data(
                form=form,
            )
        )

    def get_success_url(self):
        return reverse('index')

# urls.py
urlpatterns = [
    path('', index, name='index'),
    path('product/', ProductFormView.as_view(template_name='product/product.html'),


# html template

{% extends "product/base.html" %}
{% load crispy_forms_tags %}

{% block col8_content %}
<form id="product-modelform" method="post">
    {% csrf_token %}
    {% crispy form %}
    {% endblock col8_content %}
    {% block col4_content %}
    {% crispy form_2 %}
</form>
    {% endblock col4_content %}
...