在使用Django Rest Framework 3编写的web API中,我正在与序列化程序中的循环依赖性作斗争.虽然我知道项目中的循环依赖几乎总是糟糕设计的标志,但我无法找到一种体面的方法来避免它,而不让应用成为一场巨大的噩梦.
一个简单的简化示例很好地描述了在我遇到类似问题的所有地方发生的情况.
让我们在两个应用程序中有两个简单的模型:
配置文件应用程序
# 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)
遵循fat models的原则,我经常在模型中使用多个导入,以便使用Profile上的方法轻松检索相关对象,但这很少导致循环依赖,因为我很少从另一端执行同样的操作.
当我试图将serializers加到这一串中时,问题就开始了.为了使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结果:
配置文件应用程序 at /profiles
[{
'name': 'Test profile',
'recent_images': [{
'title': 'Test image 1'
}, {
'title': 'Test image 2'
}]
]]
图像应用程序 at /images
[{
'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
但这感觉像是ugly,ugly,uuuugly次黑客攻击.
您能分享一下您遇到类似问题的经验吗?
谢谢!