Круговая зависимость в сериализаторах
Я играю с 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
Кто-нибудь помогает?
Ответы
Ответ 1
Когда файл импортируется, его содержимое выполняется сверху вниз. Поэтому строка author = AuthorSerializer(many=False)
пытается создать экземпляр класса AuthorSerializer
до его определения.
Даже если вы можете исправить проблему с круговой зависимостью, это будет плохой дизайн. Всякий раз, когда вы сериализуете Автора, вы включаете список всех его книг, которые, в свою очередь, включают объект Author с его списком книг. Это приведет к другой ошибке для превышения предела глубины рекурсии.
Что вам нужно решить, в каком направлении вы хотите сохранить включенную сериализацию: хотите ли вы создать полный авторский объект в каждой сериализации книг или хотите, чтобы список книг со всей его информацией для каждого объекта Author?
Обратное отношение затем может быть включено с использованием любой формы RelatedField
как это предусмотрено в Django REST Framework.
Ответ 2
Я знаю, что вопрос довольно старый, но я нашел простое решение.
Вам необходимо определить вспомогательные сериализаторы для обработки ссылки в обоих направлениях:
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
без бесконечной круговой зависимости Книги, имеющей автора, у которого есть Книги, у которых есть Автор, у которого есть Книги...