Skip to main content
 首页 » 编程设计

python之forms.ModelForm 不保存 ManyToMany 字段

2025年05月04日15mq0036

我正在使用表单 (forms.ModelForm),当我基于模型创建表单时遇到了一些小的不便。我的情况如下在我的 models.py 文件中:

我有 CorporalSegment 模型:

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 

我有运动模型

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 

我有 Metric 模型

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) 

我的目的是在一种形式中,我可以保存 CorporalSegment、Movement 和 Metric 模型的多个值(实例),并且由于为此,我有这种方式的 PatientMonitoring 模型:

class PatientMonitoring(models.Model): 
 
    patient = models.ForeignKey(...) 
    medical = models.ForeignKey(...) 
 
    # My fields pointing to my previous models with many to many relationship 
    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 

我的views.py 文件

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') 

我的forms.py是这样的:

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'] 

我的模板 patientmonitoring_form.html 是:

{% 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 %} 

当我想以各自的形式保存 PatientMonitoring 实例时,corporal_segment (Segmentos Corporales) movement (Movimientos) 和 metrics (Metricas) 表单中的字段,它们的值没有保存在表单中(红色方 block ),但其他字段被保存(不是红色方 block )

这种行为对我来说很奇怪,因为通过 Django 管理表单,可以保存一个 PatientMonitoring 实例及其所有属性。

在 forms.py 文件的 PatientMonitoringForm 中保存表单 save 方法时,我可以忽略什么?

请您参考如下方法:

https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#the-save-method

使用commit=False时,必须调用save_m2m()

m2m 关系需要先保存父对象,而使用 commit=False 则不会这样做。