Сохранение родительской и дочерней формы django
У меня есть страница, на которой пользователи вводят данные, относящиеся к двум моделям - модели, представляющей пациента, и модели, представляющей лекарства, принимаемые этим пациентом. Я разработал интерфейс таким образом, что несколько лекарств могут быть добавлены пользователем динамически
Однако я не уверен, как сохранить и записи для лекарств, и пациента, когда пользователь отправляет заявку. В текущей установке, приведенной ниже, я не могу успешно сохранить данные пациента, так как получаю ошибку "save() запрещено для предотвращения потери данных из-за несохраненного связанного объекта 'patient'."
models.py
class Patient(TimeStampedModel):
patient_id = models.UUIDField(primary_key=True, unique=True, default=uuid.uuid4, editable=False)
name = models.CharField("Patient Name", max_length=255)
class Med(TimeStampedModel):
med_name = models.CharField("MedName", max_length=20)
patient = models.ForeignKey(Patient, on_delete=models.CASCADE)
forms.py
from django.forms import inlineformset_factory, ModelForm
from .models import Med, Patient
MedFormSet = inlineformset_factory(Patient, Med, fields=("med_name",), extra=1)
class PatientForm(ModelForm):
class Meta:
model = Patient
fields = ['name', 'sex']
views.py
from .forms import MedFormSet, PatientForm
from .models import Patient, Med
class MedAddView(TemplateView):
model = Patient
template_name = "../templates/patient/med_add.html"
def get(self, *args, **kwargs):
# Create an instance of the formset
patient_form = PatientForm
formset = MedFormSet(queryset=Med.objects.none())
return self.render_to_response({'med_formset': formset, 'patient_form':patient_form})
def post(self, *args, **kwargs):
form = PatientForm(data=self.request.POST)
formset = MedFormSet(data=self.request.POST)
if form.is_valid() and formset.is_valid():
form.save()
formset.save()
return redirect('patient:med_list')
MedAddview html
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<h1>Add a new med</h1>
<form id="form-container" method="POST">
{% csrf_token %}
{{patient_form}}
{{med_formset.management_form}}
{% for form in med_formset %}
<div class="med-form">
{{form.as_p}}
</div>
{% endfor %}
<button id="add-form" type="button">Add Another Med</button>
<button type="submit">Create Meds</button>
</form>
<script>
let medForm = document.querySelectorAll(".med-form")
let container = document.querySelector("#form-container")
let addButton = document.querySelector("#add-form")
let totalForms = document.querySelector("#id_form-TOTAL_FORMS")
let formNum = medForm.length-1
addButton.addEventListener('click', addForm)
function addForm(e){
e.preventDefault()
let newForm = medForm[0].cloneNode(true)
let formRegex = RegExp(`form-(\\d){1}-`,'g')
formNum++
newForm.innerHTML = newForm.innerHTML.replace(formRegex, `form-${formNum}-`)
container.insertBefore(newForm, addButton)
totalForms.setAttribute('value', `${formNum+1}`)
}
</script>
{% endblock %}
Попробуйте этот код, он будет работать
def post(self, *args, **kwargs):
form = PatientForm(data=self.request.POST)
formset = MedFormSet(data=self.request.POST)
if form.is_valid():
patient_instance = form.save()
if formset.is_valid():
med_name = formset.save(commit = False)
for med in med_name:
med.patient = patient_instance
med.save()
return redirect('patient:med_list')