保存 django 父子表单

Saving django parent and child form

我有一个页面,用户可以在其中输入与两个模型相关的详细信息 - 一个代表患者,另一个代表该患者服用的药物。我设计了界面,以便用户可以动态添加多种药物。

但是,我不确定如何在用户提交时同时保存药物和患者的条目。在下面的当前设置中,我没有成功保存患者数据,因为我收到错误“save() prohibited to prevent data loss due to unsaved related object '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')