【问题标题】:ManyToMany Relationships. Returning fields in def __str__ method多对多关系。在 def __str__ 方法中返回字段
【发布时间】:2017-02-05 08:32:02
【问题描述】:

我有两个模型:

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

还有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)

我有另一个名为 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'
)

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

据我了解,在ManyToMany 关系中,会使用两个表的 ID 字段创建一个中间表,从而形成这种m2m 关系:

我的问题是:

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

任何方向都非常有用 :)

【问题讨论】:

    标签: django python-3.x django-models many-to-many


    【解决方案1】:

    问题是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)
    

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

    【讨论】:

    • 感谢您的回复。当您告诉我每个项目的额外 SQL 查询时,这是真的。有一些方法可以在这样的情况下衡量这种性能.. ?
    • 我没有想到一个特定的工具来衡量性能。如果页面加载速度对您来说足够快,那么我不会太担心。如果速度很慢,那么您可以使用prefetch_related 来加快速度(请参阅this answer)。如果这仍然太慢,您需要考虑一种不同的方法。 django-debug-toolbar 可用于查看页面的 SQL 查询。
    猜你喜欢
    • 2022-12-12
    • 1970-01-01
    • 1970-01-01
    • 2018-01-24
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 2014-09-22
    • 2017-12-23
    相关资源
    最近更新 更多