来自动态领域的外键资源

时间:2015-03-16 14:53:26

标签: python django tastypie

我有一个名为TrackMinResource的API端点,它返回音乐曲目的最小数据,包括作为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) + '/'

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

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

如果我从full=True的“艺术家”字段中取出TrackMinResource并添加null=True,我会在返回的数据中获取艺术家字段的空值。如果我然后按照dehydrate分配艺术家:

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

...我只是在返回的JSON中获取艺术家名称,而不是代表dict的{​​{1}}(以及我需要的相关ArtistMinResource)。< / p>

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

1 个答案:

答案 0 :(得分:1)

你可以在TrackMinResource中使用ArtistMinResource这样脱水(假设main_artist()返回ArtistMinResource所代表的对象):

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现在应该包含您的完整艺术家代表。此外,如果您传递了请求并且已填充内容类型标头,我确定您不必传递格式。