多对多关系。在 def __str__ 方法中返回字段

bga*_*ial 2 django many-to-many django-models python-3.x

我有两个模型:

AffectedSegment 模型

class AffectedSegment(models.Model):

    SEGMENTO_ESCAPULA = 'Escápula'
    SEGMENTO_HOMBRO = 'Hombro'
    SEGMENTO_CODO = 'Codo'
    SEGMENTO_ANTEBRAZO = 'Antebrazo'
    SEGMENTO_CARPO_MUNECA = 'Carpo/Muñeca'
    SEGMENTO_MANO = 'Mano'
    SEGMENT_CHOICES = (
        (SEGMENTO_ESCAPULA, u'Escápula'),
        (SEGMENTO_HOMBRO, u'Hombro'),
        (SEGMENTO_CODO, u'Codo'),
        (SEGMENTO_ANTEBRAZO, u'Antebrazo'),
        (SEGMENTO_CARPO_MUNECA, u'Carpo/Muñeca'),
        (SEGMENTO_MANO, u'Mano'),
    )

    affected_segment = models.CharField(
        max_length=12,
        choices=SEGMENT_CHOICES,
        blank=False,
        verbose_name='Segmento afectado',
        help_text='Ingrese uno o mas segmentos corporal de miembros superiores'
    )

    class Meta:
        verbose_name_plural = 'Segmentos corporales'

    def __str__(self):
        return "%s" % self.affected_segment
Run Code Online (Sandbox Code Playgroud)

Movement模型。请__str__在最后查看此模型的方法:

class Movement(models.Model):
    type = models.CharField(
        max_length=255,
        verbose_name='Tipo de movimiento'
    )

    corporal_segment_associated = models.ManyToManyField(
        AffectedSegment,
        blank=True,
        verbose_name='Segmento corporal asociado')

    class Meta:
        verbose_name = 'Movimiento'

    def __str__(self):
        return "{},{}".format(self.type, self.corporal_segment_associated)
Run Code Online (Sandbox Code Playgroud)

我有另一个命名的模型RehabilitationSession,我希望允许选择多个受影响的段和多个移动,例如:

类 RehabilitationSession(models.Model):

affected_segment = models.ManyToManyField(
    AffectedSegment,
    verbose_name='Segmento afectado',
    #related_name='affectedsegment'
)
movement = models.ManyToManyField(
    Movement,  # Modelo encadenado
    verbose_name='Movimiento',
    #related_name = 'movement'
)
Run Code Online (Sandbox Code Playgroud)

在我的 Django Admin 中,当我转到RehabilitationSession模型时,我在movement字段中看到以下内容:

在此处输入图片说明

我知道在ManyToMany关系中,使用两个表的 ID 字段创建了一个中间表,这两个表形成了这种m2m关系:

在此处输入图片说明

我的问题是:

我如何才能在我的Movement模型中访问corporal_segment_associated我想要在__str__方法中调用的字段?

任何方向都非常有用:)

Ala*_*air 5

问题是这self.corporal_segment_associated不是相关项目的列表,而是一个ManyRelatedManager. 当您调用 时str(self.corporal_segment_associated),它会返回AffectedSegment.None您在屏幕截图中看到的字符串。

要获取相关段,您可以执行self.corporal_segment_associated.all(). 这将返回相关对象的查询集。然后,您必须先将此查询集转换为字符串,然后才能在__str__方法中使用它。例如,你可以这样做:

class Movement(models.Model):
    def __str__(self):
        corporal_segment_associated = ", ".join(str(seg) for seg in self.corporal_segment_associated.all())
        return "{},{}".format(self.type, corporal_segment_associated)
Run Code Online (Sandbox Code Playgroud)

self.corporal_segment_associated.all()__str__方法中访问可能不是一个好主意。这意味着 Django 将对下拉列表中的每个项目进行额外的 SQL 查询。您可能会发现这会导致性能不佳。

  • 我心里并没有一个特定的工具来衡量性能。如果页面加载速度对您来说足够快,那么我就不会太担心。如果速度很慢,那么您可以使用“prefetch_lated”来加快速度(请参阅[此答案](http://stackoverflow.com/a/39698396/113962))。如果这仍然太慢,您需要考虑其他方法。django-debug-toolbar 对于查看页面的 SQL 查询非常有用。 (2认同)