2013-06-24 43 views
33

我正在使用django rest框架来创建API。 我有以下型号:使用django-rest-framework序列化器检索外键值

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

我将如何去从一个项目序列化程序获取反向,即:

[{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'}] 

我已阅读关于reverse relationships的其他框架的文档,但看起来与非反转字段的结果相同。我错过了明显的东西吗?

回答

50

只使用相关字段而不设置many=True

请注意,因为您想要输出名为category_name,但实际字段为category,您需要在序列化程序字段上使用source参数。

下应该给你你所需要的输出...

class ItemSerializer(serializers.ModelSerializer): 
    category_name = serializers.RelatedField(source='category', read_only=True) 

    class Meta: 
     model = Item 
     fields = ('id', 'name', 'category_name') 
+0

非常感谢汤姆 – hellsgate

+15

约retriving产品类别模型的所有字段什么?? – Clayton

+4

如果你想检索类别模型的所有字段使类别序列化,并在代码中有它像category_name = CategorySerliazer() –

13

你可以做的另一件事是:

  • 创建您的Item模型返回的类别名称的属性和
  • 将其公开为ReadOnlyField

您的模型看起来像这样。

class Item(models.Model): 
    name = models.CharField(max_length=100) 
    category = models.ForeignKey(Category, related_name='items') 

    def __unicode__(self): 
     return self.name 

    @property 
    def category_name(self): 
     return self.category.name 

你的序列化器看起来像这样。请注意,序列化器将通过命名具有相同名称的字段自动获取category_name模型属性的值。

class ItemSerializer(serializers.ModelSerializer): 
    category_name = serializers.ReadOnlyField() 

    class Meta: 
     model = Item 
+1

我没有用这个目的。但我不知道使用'@ property'。所以,非常感谢。这真的很有用。它可以帮助我使用序列化程序中的其他元素。 – joseglego

16

在当前DRF(3.6.3)版本,这为我工作

class ItemSerializer(serializers.ModelSerializer): 
    category_name = serializers.CharField(source='category.name') 

    class Meta: 
     model = Item 
     fields = ('id', 'name', 'category_name') 
+0

像魔术一样工作,谢谢! – UserNotFoundException