I am building a form based on some models in one of which I have attributes with ManyToMany relationships to others. The situation is the following:
ModelCorporalSegment
class CorporalSegment(models.Model):
SEGMENTO_HOMBRO = 'Hombro'
SEGMENTO_CODO = 'Codo'
SEGMENTO_ANTEBRAZO = 'Antebrazo'
SEGMENTO_MANO = 'Mano'
SEGMENT_CHOICES = (
(SEGMENTO_HOMBRO, u'Hombro'),
(SEGMENTO_CODO, u'Codo'),
(SEGMENTO_ANTEBRAZO, u'Antebrazo'),
(SEGMENTO_MANO, u'Mano'),
)
corporal_segment = models.CharField(
max_length=12,
choices=SEGMENT_CHOICES,
blank=False,
)
class Meta:
verbose_name_plural = 'Segmentos Corporales'
def __str__(self):
return "%s" % self.corporal_segment
ModelMovement
class Movements(models.Model):
name = models.CharField(
max_length=255,
verbose_name='Movimiento'
)
class Meta:
verbose_name_plural = 'Movimientos'
def __str__(self):
return "%s" % self.name
ModelMetric
class Metrics(models.Model):
name = models.CharField(
max_length=255,
blank=True,
verbose_name='Nombre'
)
value = models.DecimalField(
max_digits = 5,
decimal_places = 3,
verbose_name = 'Valor',
null = True,
blank = True
)
class Meta:
verbose_name = 'Métrica'
def __str__(self):
return "{},{}".format(self.name, self.value)
My purpose is to be able to store in a form multiple values/instances of the models CorporalSegment
, Movement
and Metric
, for which I have created the model PatientMonitoring
in this way:
class PatientMonitoring(models.Model):
patient = models.ForeignKey(...)
medical = models.ForeignKey(...)
# Mis campos que son many to many a los modelos en cuestión mencionados
corporal_segment = models.ManyToManyField(CorporalSegment, verbose_name='Segmentos Corporales')
movement = models.ManyToManyField(Movements, verbose_name='Movimientos')
metrics = models.ManyToManyField(Metrics, verbose_name='Métricas', )
class Meta:
verbose_name = 'Monitoreo del paciente'
def __str__(self):
return "%s" % self.patient
This is my views.py file in relation to the write operations with the modelPatientMonitoring
class PatientMonitoringCreate(CreateView):
model = PatientMonitoring
form_class = PatientMonitoringForm
success_url = reverse_lazy('patientmonitoring:list')
class PatientMonitoringUpdate(UpdateView):
model = PatientMonitoring
form_class = PatientMonitoringForm
success_url = reverse_lazy('patientmonitoring:list')
This is my forms.py file which in your method save(...)
is where I think I should put more emphasis...
from django import forms
from .models import PatientMonitoring
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit
class PatientMonitoringForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(PatientMonitoringForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.add_input(Submit('submit', u'Save'))
# I think so that here is my problem ...
def save(self, commit=True):
patient_monitoring = super(PatientMonitoringForm, self).save(commit=False)
patient = self.cleaned_data['patient']
if commit:
patient_monitoring.save()
return patient_monitoring
class Meta:
model = PatientMonitoring
fields = ['patient', 'medical','corporal_segment','movement','metrics']
And my template patientmonitoring_form.html
is:
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block title %}Crear Registro de Monitoreo de Paciente{% endblock %}
{% block content %}
<div>
{% crispy form %}
{% csrf_token %}
</div>
{% endblock %}
What happens to me is that when I want to record a record or instance of PatientMonitoring
in its respective form, the attributes corporal_segment
(Body Segments) movement
(Movements) and metrics
(Metrics) in the form are not stored (red boxes), but the others are stored .
This behavior is somewhat strange to me, since through the Django admin form, the PatientMonitoring model is stored with all of its fields, including the mentioned many to many.
What can I be ignoring when storing values in my form PatientMonitoringForm
in forms.py
?
I was overriding in forms.py the method
save()
where I was givingcommit = False
it like thisand if I give
commit = False
it no, the form is immediately saved in the POSTAccording to the documentation https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#the-save-method , pass it to
commit = True
and it saves the data that I want the form.But I'm also here saving the patient in a variable called patient that I don't use at all: In this part
If I don't override the method
save()
, that is, if I remove it, the form also saves all the fields that correspond to the models ofCorporalSegment
, andMovement
.That same link that I refer to in the documentation talks about calling the method
save_m2m()
when you have itcommit = False
and in my case it was like that and I have two fields in my PatientMonitoring model that have ManyToMany relations to two other models (Movement and CorporalSegment)What it says is that ManyToMany relationships require the parent object to be saved first and commit=False doesn't allow that.
I have to look at this part of
save_m2m()
what I think is suitable for what I want.