我玩django-rest-framework,我会做以下事情:
from rest_framework import serializers
from .models import Author, Book
class BookSerializer(serializers.ModelSerializer):
author = AuthorSerializer(many=False)
class Meta:
model = Book
fields = ('slug', 'name')
class AuthorSerializer(serializers.ModelSerializer):
books = BookSerializer(many=True)
class Meta:
model = Author
fields = ('slug', 'name', 'books')
但它失败了。
NameError at /api/books/authors/
name 'AuthorSerializer' is not defined
有人帮忙吗?
答案 0 :(得分:15)
导入文件时,内容从上到下执行。因此,行author = AuthorSerializer(many=False)
尝试在定义之前实例化AuthorSerializer
类。
即使您可以修复循环依赖问题,也可能是糟糕的设计。每当您序列化作者时,您都会列出他所有书籍的列表,而这些书籍又包含作者对象及其书籍列表。这将导致超出递归深度限制的另一个错误。
您需要决定的是在哪个方向上保留包含的序列化:您是否希望每个书籍序列化中都有完整的作者对象,或者您是否希望每个作者对象都包含其所有信息的书籍列表?
然后可以使用任何形式的RelatedField
as provided by the Django REST Framework来包含反向关系。
答案 1 :(得分:4)
我知道问题已经很久了,但我找到了一个简单的解决方案。
您需要定义辅助序列化程序以双向处理引用:
class BookUnrelatedSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = ('slug', 'name')
class AuthorUnrelatedSerializer(serializers.ModelSerializer):
class Meta:
model = Author
fields = ('slug', 'name')
class BookSerializer(BookUnrelatedSerializer):
author = AuthorUnrelatedSerializer()
class Meta(BookUnrelatedSerializer.Meta):
fields = (*BookUnrelatedSerializer.Meta.fields, 'author')
class AuthorSerializer(AuthorUnrelatedSerializer):
book_set = BookUnrelatedSerializer(many = True)
class Meta(AuthorUnrelatedSerializer.Meta):
fields = (*AuthorUnrelatedSerializer.Meta.fields, 'book_set')
通过这种方式,您可以使用BookSerializer
和AuthorSerializer
,而无需具有作者的图书的无限循环依赖关系,该图书的作者具有书籍的作者...
答案 2 :(得分:2)
一种解决方法是使用 serializers.SerializerMethodField():
from rest_framework import serializers
from .models import Author, Book
class BookSerializer(serializers.ModelSerializer):
author = serializers.SerializerMethodField()
class Meta:
model = Book
fields = ('slug', 'name', 'author')
def get_author(self, obj):
return AuthorSerializer(obj.author).data
class AuthorSerializer(serializers.ModelSerializer):
books = BookSerializer(many=True)
class Meta:
model = Author
fields = ('slug', 'name', 'books')