我是DRF的新手,刚刚开始构建API。我有两个模型,一个子模型连接到具有外键的父模型。这是我所拥有的模型的简化版本:
class Parent(models.Model):
name = models.CharField(max_length=50)
class Child(models.Model):
parent = models.ForeignKey(Parent)
child_name = models.CharField(max_length=80)
要创建序列化程序,我按照DRF Serializer Relations进行了操作,并按以下方式创建了它们:
class ChildSerializer(serializers.HyperlinkedModelSerializer):
parent_id = serializers.PrimaryKeyRelatedField(queryset=Parent.objects.all(),source='parent.id')
class Meta:
model = Child
fields = ('url','id','child_name','parent_id')
def create(self, validated_data):
subject = Child.objects.create(parent=validated_data['parent']['id'], child_name=validated_data['child_name'])
return child
class ParentSerializer(serializers.HyperlinkedModelSerializer):
children = ChildSerializer(many=True, read_only=True)
class Meta:
model = Course
fields = ('url','id','name','children')
我正在尝试获取父级序列化程序中所有子项的列表。我想要的是能够得到这样的回应:
{
'url': 'https://dummyapidomain.com/parents/1/',
'id': '1',
'name': 'Dummy Parent Name',
'cildren': [
{'id': 1, 'child_name': 'Dummy Children I'},
{'id': 2, 'child_name': 'Dummy Children II'},
{'id': 3, 'child_name': 'Dummy Children III'},
...
],
}
由于父模型but it is the suggested way to do it in the documentation中父级和子级之间没有链接,并且它不起作用,我没想到这会起作用。
我收到以下错误消息:
Got AttributeError when attempting to get a value for field `children` on serializer `ParentSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `Parent` instance.
Original exception text was: 'Parent' object has no attribute 'children'.
我认为这是完全合理的,但我无法理解我在这里缺少的东西。
如何获取父级序列化程序中所有子项的列表?
答案 0 :(得分:14)
我认为您的问题是您忘记为您的儿童模型添加 related_name 。我会有这样的模型:
class Parent(models.Model):
name = models.CharField(max_length=50)
class Child(models.Model):
parent = models.ForeignKey(Parent, related_name='children') # <--- Add related_name
child_name = models.CharField(max_length=80)
我认为通过这种改变,你将解决你得到的错误
答案 1 :(得分:11)
您可以通过两种方式实现此目的:
SerializerMethodField
:
你的代码变成了这样:
class ParentSerializer(serializers.ModelSerializer):
children_list = serializers.SerializerMethodField('_get_children')
def _get_children(self, obj):
serializer = ChildSerializer(obj.child_list(), many=True)
return serializer.data
class Meta:
model = Course
fields = ('url','id','name','children_list')
每个字段都可以是模型或方法的属性,因此您可以在Parent
模型中定义get_children_list方法,然后在ParentSerializer
的字段列表中调用它:
class ParentSerializer(serializers.ModelSerializer):
class Meta:
model = Course
fields = ('url','id','name','get_children_list')
注意:您需要在此方案中继承serializers.ModelSerializer