Я борюсь с круговыми зависимостями внутри сериализаторов в своем веб-API, написанном с использованием Django Rest Framework 3. Принимая во внимание, что круговые зависимости в проекте почти всегда являются признаком плохого дизайна, я не могу найти достойный способ избегая этого, не делая приложение большим монолитным кошмаром.
Простые урезанные примеры изображений достаточно хорошо, что происходит во всех местах, у меня такая же проблема.
Пусть в двух приложениях есть две простые модели:
Приложение профилей
# profiles/models.py
from images.models import Image
class Profile(models.Model):
name = models.CharField(max_length=140)
def recent_images(self):
return Image.objects.recent_images_for_user(self)
Приложение для изображений
# images/models.py
class Image(models.Model):
profile = models.ForeignKey('profiles.Profile')
title = models.CharField(max_length=140)
Следуя принципу моделей жира, я часто использую несколько импортов в своих моделях, чтобы облегчить поиск связанных объектов с использованием методов в профиле, но это редко вызывает круговые зависимости, поскольку я редко делаю то же самое с другого конца.
Проблема начинается, когда я пытаюсь добавить сериализаторы в связку. Чтобы уменьшить площадь интерфейса API и ограничить количество необходимых вызовов до минимума, я хочу сериализовать на обоих концах некоторые связанные объекты в упрощенных формах.
Я хочу получить профили на конечной точке /profile
, которая будет иметь упрощенную информацию о нескольких последних изображениях, созданных пользователем, вложенных. Кроме того, при получении изображений из конечной точки /images
я хотел бы иметь информацию профиля, встроенную в образ JSON.
Чтобы добиться этого и избежать рекурсивного вложения, у меня есть два сериализатора - один из которых содержит связанные объекты, а другой - для обоих приложений.
Приложение профилей
# profiles/serializers.py
from images.serializers import SimplifiedImageSerializer
class SimplifiedProfileSerializer(serializers.Serializer):
name = serializers.CharField()
class ProfileSerializer(SimplifiedProfileSerializer):
recent_images = SimplifiedImageSerializer(many=True)
Приложение для изображений
# images/serializers.py
from profiles.serializers import SimplifiedProfileSerializer
class SimplifiedImageSerializer(serializers.Serializer):
title = serializers.CharField()
class ImageSerializer(SimplifiedImageSerializer):
profile = SimplifiedProfileSerializer()
Ожидаемое поведение - получить следующие результаты JSON:
Приложение профилей в профилях
[{
'name': 'Test profile',
'recent_images': [{
'title': 'Test image 1'
}, {
'title': 'Test image 2'
}]
]]
Приложение для изображений в/изображениях
[{
'title': 'Test image 1',
'profile': {
'name': 'Test profile'
}
},
{
'title': 'Test image 2',
'profile': {
'name': 'Test profile'
}
}]
но затем я ударил стену круговыми ввозами сериализаторов.
Я чувствую, что присоединение этих двух приложений к одному, определенно, не к лучшему - ведь изображения - это нечто совершенно отличное от пользовательских профилей.
Сериализаторы также, на мой взгляд, должны относиться к их соответствующим приложениям.
Единственный способ обойти эту проблему, которую я нашел сейчас, - это импорт в методе следующим образом:
class ImageSerializer(SimplifiedProfileSerializer):
profile = SerializerMethodField()
def get_profile(self, instance):
from profiles.serializers import SimplifiedProfileSerializer
return SimplifiedProfileSerializer(instance.profile).data
но это похоже на уродливый, уродливый, неудобный хак.
Не могли бы вы поделиться своим опытом с подобными проблемами?
Спасибо!