我使用django rest框架来创建一个API。我有以下型号:
class Category(models.Model):
name = models.CharField(max_length=100)
def __unicode__(self):
return self.name
class Item(models.Model):
name = models.CharField(max_length=100)
category = models.ForeignKey(Category, related_name='items')
def __unicode__(self):
return self.name
要为类别创建序列化器,我会这样做:
class CategorySerializer(serializers.ModelSerializer):
items = serializers.RelatedField(many=True)
class Meta:
model = Category
……这将为我提供:
[{'items': [u'Item 1', u'Item 2', u'Item 3'], u'id': 1, 'name': u'Cat 1'},
{'items': [u'Item 4', u'Item 5', u'Item 6'], u'id': 2, 'name': u'Cat 2'},
{'items': [u'Item 7', u'Item 8', u'Item 9'], u'id': 3, 'name': u'Cat 3'}]
我该如何从Item序列化程序中获得相反的结果,即:
[{u'id': 1, 'name': 'Item 1', 'category_name': u'Cat 1'},
{u'id': 2, 'name': 'Item 2', 'category_name': u'Cat 1'},
{u'id': 3, 'name': 'Item 3', 'category_name': u'Cat 1'},
{u'id': 4, 'name': 'Item 4', 'category_name': u'Cat 2'},
{u'id': 5, 'name': 'Item 5', 'category_name': u'Cat 2'},
{u'id': 6, 'name': 'Item 6', 'category_name': u'Cat 2'},
{u'id': 7, 'name': 'Item 7', 'category_name': u'Cat 3'},
{u'id': 8, 'name': 'Item 8', 'category_name': u'Cat 3'},
{u'id': 9, 'name': 'Item 9', 'category_name': u'Cat 3'}]
我已经阅读了REST框架的反向关系文档,但这似乎与非反向字段的结果相同。我错过了什么明显的东西吗?
8条答案
按热度按时间lokaqttq1#
在DRF版本3中。6.3这对我很有用
更多信息可以在这里找到:序列化程序字段核心参数
tkqqtvp12#
只需使用相关字段,而不设置
many=True
。请注意,还因为您希望输出名为
category_name
,但实际字段是category
,所以您需要在序列化器字段上使用source
参数。下面的代码应该会给予您需要的输出。..
q5iwbnjs3#
你可以做的另一件事是:
Item
模型中创建一个属性,返回类别名称和ReadOnlyField
。你的模型看起来像这样。
您的序列化程序将如下所示。请注意,序列化程序将自动获得
category_name
模型属性的值,方法是用相同的名称命名字段。j1dl9f464#
这对我来说很有效:
zfycwa2u5#
简单的解决方案
source='category.name'
,其中category
是外键,.name
是属性。daolsyd06#
工作于2018年8月8日和DRF版本3。8.2:
使用 meta
read_only_fields
,我们可以准确地声明哪些字段应该是只读的。然后,我们需要在 metafields
上声明foreign
字段(最好像咒语一样显式:zen of python)。8ehkhllq7#
这种解决方案更好,因为不需要定义源模型。但序列化程序字段的名称应与外键字段名称相同
sxpgvts38#
对于那些想要 * 替换 * ForeignKey(显示ID)的字段的用户,为了方便起见,您仍然可以使用
__all__
语法,并简单地覆盖您认为合适的字段名称。例如:在我看来,这是很方便的B/c,你仍然可以使用
__all__
语法来捕获任何添加的字段。任何被覆盖的东西都是手动完成的,如果需要恢复,可以手动完成一些,而不需要更改任何其他语法。