【问题标题】:Django Rest Framework - how to get __unicode__() values in related fields for ModelSerializersDjango Rest Framework - 如何在 ModelSerializers 的相关字段中获取 __unicode__() 值
【发布时间】:2015-03-19 21:52:37
【问题描述】:

ModelSerializer() 出于某种原因不会显示相关模型的 __unicode__() 值,而是显示它们的 id - 有没有办法解决这个问题?或者我必须以某种方式明确定义所有相关字段?对于相关模型,我使用利用 HyperlinkedModelSerializer 的 ModelView。

型号

class ActionItem(CoreBase):
    project = models.ForeignKey(Project, null=True, blank=True, related_name='ProjectActionItems')
    portfolio = models.ForeignKey(Portfolio, null=True, blank=True, related_name='PortfolioActionItems')
    name = models.CharField(max_length=256, null=False)
    description = models.TextField(null=True, blank=True)
    parent = models.ForeignKey('ActionItem', null=True, blank=True)
    priority = models.ForeignKey(DicPriority, default=ActionItem_default_priority)
    status = models.ForeignKey(DicActionItemStatus, default=ActionItem_initial_status)
    resolution = models.TextField(null=True, blank=True)
    assignee = models.ForeignKey(User, null=True, blank=True, related_name='executor')
    due_date = models.DateField(null=True, blank=True)

相关模型(优先级):

class DicPriority(DicCoreBase):
    name = models.CharField(max_length=64, unique=True, blank=False, null=False)

    class Meta:
        verbose_name = '[D] Priority'
        verbose_name_plural = '[D] Priorities'

它的基类:

class DicCoreBase(CoreBase):
    order = models.PositiveSmallIntegerField(default=10, null=False, blank=False)

    class Meta:
        abstract = True
        ordering = ['order']

    def __unicode__(self):
        if hasattr(self, 'name'):
            return self.name
        else:
            return u'Dic (%s): %s' % (self.__class__.__name__, self.pk)

序列化器

class ActionItemTextSerializer(serializers.ModelSerializer):

    class Meta:
        model = ActionItem
        fields = ('id', 'created_by', 'created_date', 'project', 'portfolio', 'name', 'description', 'parent', 'priority', 'status')


class ActionItemViewSet(viewsets.ModelViewSet):
    queryset = ActionItem.objects.all()
    serializer_class = ActionItemTextSerializer

输出:

{
        "id": 5,
        "created_by": 1,
        "created_date": "2015-03-19T18:34:07Z",
        "project": 1,
        "portfolio": null,
        "name": "NEW TEST!!!",
        "description": "ACE TEST NEW XOXO",
        "parent": null,
        "priority": 2,
        "status": 2
    }

【问题讨论】:

    标签: django django-models django-rest-framework


    【解决方案1】:

    DRF 为相关字段提供 Keys,以便在相关对象之间轻松导航。如果要引用相关字段的属性,可以显式定义:

    class ActionItemTextSerializer(serializers.ModelSerializer):
    
        priority_text = serializers.CharField(source='priority')
        class Meta:
            model = ActionItem
            fields = ('id', 'created_by', 'created_date', 'project', 'portfolio', 'name', 'description', 'parent', 'priority_text', 'status')
    

    编辑: 我最初有source='priority__name',但凯文指出我使用的语法不正确,应该是source='priority.name',但后来我重新阅读了这个问题,它专门针对__unicode__,所以这只是定义的问题您的序列化器字段作为 CharField,它将自动在您的对象上调用 __unicode__。所以我们最终得到source='priority'

    【讨论】:

    • @KevinBrown 是的。抱歉,我没想到!
    • 谢谢你,确实可以。所以这是故意的,ModelSerializer 将忽略抽象类上的 __unicode__ 覆盖(这将返回优先级的名称)并且只获取 ID?是否有标签或其他东西我可以用来覆盖这个逻辑并让它默认使用__unicode__ 字段(而不是必须覆盖所有单个字段,并且有很多......)
    • 这就是模型序列化器的美妙之处,它为您提供了相关对象的键,因此您可以根据需要检索它们。如果您想要大量数据,您可以将depth = 1 添加到您的 Meta 类中,它应该返回嵌套在您的对象中的相关项目的所有属性。这可能是一个选项,具体取决于您的数据是什么样的以及您是否需要 POST 回它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-05
    • 2019-02-09
    • 2018-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多