Я новичок в 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 %}