hel*_*ate 57 python django django-rest-framework
我正在使用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
Run Code Online (Sandbox Code Playgroud)
要为我要做的类别创建一个序列化器:
class CategorySerializer(serializers.ModelSerializer):
items = serializers.RelatedField(many=True)
class Meta:
model = Category
Run Code Online (Sandbox Code Playgroud)
......这会为我提供:
[{'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'}]
Run Code Online (Sandbox Code Playgroud)
我如何从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'}]
Run Code Online (Sandbox Code Playgroud)
我已经阅读了关于其余框架的反向关系的文档,但这看起来与非反向字段的结果相同.我错过了一些明显的东西吗
Tom*_*tie 61
只需使用相关字段而无需设置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')
Run Code Online (Sandbox Code Playgroud)
Say*_*k88 53
在目前的DRF(3.6.3)版本中,这对我有用
class ItemSerializer(serializers.ModelSerializer):
category_name = serializers.CharField(source='category.name')
class Meta:
model = Item
fields = ('id', 'name', 'category_name')
Run Code Online (Sandbox Code Playgroud)
hse*_*ian 20
你可以做的另一件事是:
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
Run Code Online (Sandbox Code Playgroud)
你的序列化器看起来像这样.请注意,序列化程序将category_name通过命名具有相同名称的字段来自动获取model属性的值.
class ItemSerializer(serializers.ModelSerializer):
category_name = serializers.ReadOnlyField()
class Meta:
model = Item
Run Code Online (Sandbox Code Playgroud)
这对我来说很好:
class ItemSerializer(serializers.ModelSerializer):
category_name = serializers.ReadOnlyField(source='category.name')
class Meta:
model = Item
fields = "__all__"
Run Code Online (Sandbox Code Playgroud)
简单的解决方案
source='category.name',其中category为外键和.name它的属性。
from rest_framework.serializers import ModelSerializer, ReadOnlyField
from my_app.models import Item
class ItemSerializer(ModelSerializer):
category_name = ReadOnlyField(source='category.name')
class Meta:
model = Item
fields = "__all__"
Run Code Online (Sandbox Code Playgroud)
在08/08/2018和DRF版本3.8.2上工作:
class ItemSerializer(serializers.ModelSerializer):
category_name = serializers.ReadOnlyField(source='category.name')
class Meta:
model = Item
read_only_fields = ('id', 'category_name')
fields = ('id', 'category_name', 'name',)
Run Code Online (Sandbox Code Playgroud)
使用元数据,read_only_fields我们可以准确地声明哪些字段应为read_only。然后,我们需要foreign在Meta上声明该字段fields(随着口头禅的发展,最好是明确的:zen of python)。
该解决方案更好,因为不需要定义源模型。但序列化器字段的名称应该与外键字段名称相同
class ItemSerializer(serializers.ModelSerializer):
category = serializers.SlugRelatedField(read_only=True, slug_field='title')
class Meta:
model = Item
fields = ('id', 'name', 'category')
Run Code Online (Sandbox Code Playgroud)