Django Dynami c Встроенный Formset без каких-либо полей в родительской модели не работает - PullRequest
0 голосов
/ 31 января 2020

Я новичок в Django, и я пытался создать динамическую c встроенную форму, но столкнулся с проблемой. Я пытаюсь создать встроенную форму с настраиваемым пользователем количеством встроенных форм (модели: DataSheetProperties) с внешним ключом для моделей: ProvisionalData. Однако в родительской модели (ProvisionalData) я не хочу, чтобы пользователь заполнял какие-либо поля, а я должен был заполнить поля в серверной части. Это означает, что пользователь должен видеть только дочернюю модель (DataSheetProperties) и иметь возможность добавлять или удалять экземпляры этой встроенной формы по своему усмотрению. Визуализация формы в порядке, но когда я нажимаю кнопку «Сохранить», я не могу сохранить ее, и она даже не запускается через метод form_valid () в views.py. Я подумал, что это потому, что не было полей в форме родительской модели, которые пользователь мог бы заполнить, поэтому django не распознает, что форма была отправлена. Поэтому я попытался добавить поле в forms.py (ProvisionalDataCreateForm) в разделе Div () метода __init_. После добавления поля я смог успешно сохранить встроенную форму. Однако я надеюсь, что пользователь не сможет увидеть и заполнить какие-либо поля в родительской модели и форме, поскольку я хотел бы, чтобы эта форма автоматически заполнялась в бэкэнде. Надеюсь, что вы, ребята, можете помочь дать некоторые предложения, все ответы приветствуются. Заранее спасибо!

Я скачал плагин django -dynami c -formset по этой ссылке, чтобы использовать его в своем динамическом c встроенном наборе форм. https://github.com/elo80ka/django-dynamic-formset

Кроме того, код для моего динамического c встроенного набора форм можно найти на этом сайте. https://dev.to/zxenia/django-inline-formsets-with-class-based-views-and-crispy-forms-14o6

forms.py

class ProvisionalDataForm(forms.ModelForm):
    class Meta:
        model = DataSheetProperties
        fields = ['properties', 'name','method','value','units']
        exclude = []

ProvisionalDataFormSet = inlineformset_factory(ProvisionalData, DataSheetProperties,
                                           form=ProvisionalDataForm, extra=1,
                                           can_delete=True)


class ProvisionalDataCreateForm(forms.ModelForm):

    class Meta:
        model = ProvisionalData
        exclude = []

    def __init__(self, *args, **kwargs):
        super(ProvisionalDataCreateForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_tag = True
        self.helper.form_class = 'form-horizontal'
        self.helper.label_class = 'col-md-3 create-label'
        self.helper.field_class = 'col-md-9'
        self.helper.layout = Layout(
            Div(
                Fieldset('Add properties',
                    Formset('data')),
                HTML("<br>"),
                ButtonHolder(Submit('submit', 'save')),
                )
            )

models.py

class ProvisionalData(models.Model):
    status = (
        ('active', 'Active'),
        ('inactive', 'Inactive'),
    )
    provisionaldata_id = models.AutoField(primary_key=True)
    rndProject = models.ForeignKey('RndProject', on_delete=models.CASCADE, null=True, blank=True)
    status = models.CharField(max_length = 20, choices=status, default='active')
    justification = models.TextField(max_length=200, null=True, blank=True) 

class DataSheetProperties(models.Model):
    options = (
        ('physical','Physical'),
        ('mechanical','Mechanical'),
        ('thermal','Thermal'),
    )

    status = (
        ('active', 'Active'),
        ('inactive', 'Inactive'),
    )
    name = models.CharField(max_length=50, default='Property Name')
    method = models.CharField(max_length=50, default='Test Method')
    units = models.CharField(max_length=50, default='Unit of Measurement')
    value = models.CharField(max_length=50, default='Typical Value')
    properties = models.CharField(max_length=50, choices=options)
    data = models.ForeignKey('ProvisionalData', on_delete=models.CASCADE)
    status = models.CharField(max_length = 20, choices=status, default='active')

views.py

class ProvisionalDataSheetView(CreateView):
    model = ProvisionalData
    form_class = ProvisionalDataCreateForm
    template_name = 'rnd/provisional_datasheet.html'

    def get_context_data(self, **kwargs):
        context = super(ProvisionalDataSheetView, self).get_context_data(**kwargs)
        if self.request.POST:
            context['data'] = ProvisionalDataFormSet(self.request.POST)
        else:
            context['data'] = ProvisionalDataFormSet()
        return context

    def form_valid(self, form):
        form.instance.rndProject = RndProject.objects.filter(rnd_project_id = self.kwargs['pk'])[0]
        context = self.get_context_data()
        data = context['data']
        with transaction.atomic():
            self.object = form.save()
            if data.is_valid():
                data.instance = self.object
                data.save()
        return super(ProvisionalDataSheetView, self).form_valid(form)

    def get_success_url(self):
        return reverse('rnd-project-details', kwargs={'pk': self.object.rndProject.rnd_project_id})

formset. html

{% load static %}
{% load crispy_forms_tags %}
<table>
{{ formset.management_form|crispy }}

{% for form in formset.forms %}
        <tr class="{% cycle 'row1' 'row2' %} formset_row-{{ formset.prefix }}">
            {% for field in form.visible_fields %}
            <td>
                {# Include the hidden fields in the form #}
                {% if forloop.first %}
                    {% for hidden in form.hidden_fields %}
                        {{ hidden }}
                    {% endfor %}
                {% endif %}
                {{ field.errors.as_ul }}
                {{ field|as_crispy_field }}
            </td>
            {% endfor %}
        </tr>
{% endfor %}

</table>
<br>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js">
</script>
<script src="{% static 'rnd/jquery.formset.js' %}" type="text/javascript"> </script>
<script type="text/javascript">
    $('.formset_row-{{ formset.prefix }}').formset({
        addText: 'add another',
        deleteText: 'remove',
        prefix: '{{ formset.prefix }}',
    });
</script>

provisional_datasheet. html

{% extends 'rnd/base.html' %}
{% load static %}
{% load crispy_forms_tags %}
{% block content %}
<div class="container">
    <div class="card">
        <div class="card-header">
            Create provisional datasheet
        </div>
        <div class="card-body">
             {% crispy form %}
        </div>
    </div>
</div>
{% endblock content %}
...