来自动态字段的外键资源

Foreign Key Resource from dynamic field

我有一个名为 TrackMinResource 的 API 端点,它 return 是音乐曲目的最小数据,包括曲目的主要艺术家 returned 作为一个 ArtistMinResource。以下是两者的定义:

class TrackMinResource(ModelResource):
    artist = fields.ForeignKey(ArtistMinResource, 'artist', full=True)

    class Meta:
        queryset = Track.objects.all()
        resource_name = 'track-min'
        fields = ['id', 'artist', 'track_name', 'label', 'release_year', 'release_name']
        include_resource_uri = False
        cache = SimpleCache(public=True)

    def dehydrate(self, bundle):
        bundle.data['full_artist_name'] = bundle.obj.full_artist_name()
        if bundle.obj.image_url != settings.NO_TRACK_IMAGE:
            bundle.data['image_url'] = bundle.obj.image_url

class ArtistMinResource(ModelResource):
    class Meta:
        queryset = Artist.objects.all()
        resource_name = 'artist-min'
        fields = ['id', 'artist_name']
        cache = SimpleCache(public=True)

    def get_resource_uri(self, bundle_or_obj):
        return '/api/v1/artist/' + str(bundle_or_obj.obj.id) + '/'

问题是,Track 上的 artist 字段(以前是 ForeignKey)现在是一个名为 main_artist 的模型方法(我已经更改了结构数据库有点,但我希望 API 到 return 与以前相同的数据)。因此,我收到此错误:

{"error": "The model '<Track: TrackName>' has an empty attribute 'artist' and doesn't allow a null value."}

如果我从 TrackMinResource 的 'artist' 字段中取出 full=True 并改为添加 null=True,我会得到 [=45] 中艺术家字段的空值=]编辑数据。如果我然后像这样在 dehydrate 中分配艺术家:

bundle.data['artist'] = bundle.obj.main_artist()

...我只是在 returned JSON 中获取艺术家姓名,而不是 dict 表示 ArtistMinResource(连同相关的 resource_uris,我需要)。

知道如何将这些 ArtistMinResource 放入我的 TrackMinResource 吗?我可以使用 URL 端点访问一个 ArtistMinResource 并通过 ID 请求它。 TrackMinResourcedehydrate 函数中是否有函数可以获取结果?

您可以像这样在 TrackMinResource 的脱水中使用您的 ArtistMinResource(假设 main_artist() returns 您的 ArtistMinResource 代表的 object):

artist_resource = ArtistMinResource()
artist_bundle = artist_resource.build_bundle(obj=bundle.obj.main_artist(), request=request)
artist_bundle = artist_resource.full_dehydrate(artist_bundle)
artist_json = artist_resource.serialize(request=request, data=artist_bundle, format='application/json')

artist_json 现在应该包含您的完整艺术家代表。另外,我很确定如果您通过了请求并且它填充了 content-type header,则您不必通过格式。