Django динамический набор форм сохраняет только последнюю запись
Я создал страницу, на которой пользователи могут вводить данные в формы, относящиеся к родительской модели (Patient) и двум дочерним моделям (CurrentMed и PastMed), связанным с этой родительской моделью.
В обеих дочерних формах используются динамические наборы форм, где пользователь может добавлять или удалять строки в форме. Моя проблема заключается в том, что только последняя строка наборов форм currentmed и pastmed сохраняется в моей базе данных, когда пользователь отправляет форму?
models.py
class Patient(TimeStampedModel):
# get a unique id for each patient - could perhaps use this as slug if needed
patient_id = models.UUIDField(primary_key=True, unique=True, default=uuid.uuid4, editable=False)
name = models.CharField("Patient Name", max_length=255)
creator = models.ForeignKey(
settings.AUTH_USER_MODEL,
null=True,
on_delete=models.SET_NULL)
class Med(TimeStampedModel):
med_name = models.CharField(“med name“, max_length=20)
dose = models.IntegerField("Dose (mg)", default=0)
timepoint = models.CharField(
"timepoint", max_length=20,
choices=[('current','current'), ('past', 'past')], default='unspecified')
patient = models.ForeignKey(Patient, on_delete=models.CASCADE)
class Meta:
abstract = True
class CurrentMed(Med):
timepoint = models.CharField(
"", max_length=20,
choices=[('current','current'), ('past', 'past')], default='current')
class PastMed(Med):
timepoint = models.CharField(
"", max_length=20,
choices=[('current','current'), ('past', 'past')], default='past')
forms.py
from .models import CurrentMed, PastMed, Patient
CurrentmedFormSet = inlineformset_factory(
Patient, CurrentMed, fields=("med_name", "dose",), extra=2)
PastmedFormSet = inlineformset_factory(
Patient, PastMed, fields=("med_name", "dose",), extra=2)
class PatientForm(ModelForm):
class Meta:
model = Patient
fields = ['name', 'sex', 'age', 'diagnosis']
views.py
class PatientAddView(LoginRequiredMixin,TemplateView):
model = Patient
template_name = "../templates/patient/add.html"
def get(self, *args, **kwargs):
patient_form = PatientForm
currentmed_formset = CurrentmedFormSet(queryset=CurrentMed.objects.none())
pastmed_formset = PastmedFormSet(queryset=PastMed.objects.none())
return self.render_to_response({'currentmed_formset': currentmed_formset,
'pastmed_formset': pastmed_formset,
'patient_form': patient_form})
def post(self, *args, **kwargs):
form = PatientForm(data=self.request.POST)
currentmed_formset = CurrentmedFormSet(data=self.request.POST)
pastmed_formset = PastmedFormSet(data=self.request.POST)
if form.is_valid():
patient_instance = form.save()
if currentmed_formset.is_valid():
med_name = currentmed_formset.save(commit=False)
for med in med_name:
med.patient = patient_instance
med.save()
if pastmed_formset.is_valid():
med_name = pastmed_formset.save(commit=False)
for med in med_name:
med.patient = patient_instance
med.save()
return redirect(reverse(
'patient:treatment_detail',
kwargs={"patient_id": patient_instance.patient_id}))
html
{% extends "base.html" %}
{% load static %}
{% load crispy_forms_tags %}
{% block javascript %}
<script type="text/javascript" src="{% static 'js/jquery/dist/jquery-1.3.2.min.js' %}"></script>
<script type="text/javascript" src="{% static 'js/jquery.formset.js' %}"></script>
<script type="text/javascript">
$(function() {
$('#currentmeds_table tbody tr').formset({
prefix: 'current_meds'
})
});
$(function() {
$('#pastmeds_table tbody tr').formset({
prefix: 'past_meds'
})
});
</script>
<style type="text/css">
.delete-row {
margin-left:5px;
}
</style>
{% endblock %}
{% block content %}
<div>
<div class="entry">
<form id="form" method="POST">
<h1>Patient Details</h1>
{% csrf_token %}
<h3>Demographics</h3>
{{patient_form}}
<h3>Current Medication</h3>
<table id="currentmeds_table" border="0" cellpadding="0" cellspacing="5">
<thead>
<tr>
<th scope="col">Medication</th>
<th scope="col">Dose</th>
</tr>
</thead>
<tbody>
{% for form in currentmed_formset %}
<tr id="{{ form.prefix }}-row"></tr>
<td>
{% for fld in form.hidden_fields %}{{ fld }}{% endfor %}
{% if form.instance.pk %}{{ form.DELETE }}{% endif %}
{{ form.med_name}}
</td>
<td>{{ form.dose }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{{currentmed_formset.management_form}}
<h3>Past Medication</h3>
<table id="pastmeds_table" border="0" cellpadding="0" cellspacing="5">
<thead>
<tr>
<th scope="col">Medication</th>
<th scope="col">Dose</th>
</tr>
</thead>
<tbody>
{% for form in pastmed_formset %}
<tr id="{{ form.prefix }}-row"></tr>
<td>
{% for fld in form.hidden_fields %}{{ fld }}{% endfor %}
{% if form.instance.pk %}{{ form.DELETE }}{% endif %}
{{ form.med_name}}
</td>
<td>{{ form.dose }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{{pastmed_formset.management_form}}
<button type="submit">Create Patient</button>
</form>
</div>
</div>
{% endblock %}
Префиксы в javascript были неправильными, нашел правильные, посмотрев html-источник, вместо
$('#currentmeds_table tbody tr').formset({
prefix: 'current_meds'
})
Должно было быть
$('#currentmeds_table tbody tr').formset({
prefix: 'currentmed_set'
})