如何在tastypie中创建自定义嵌套ToMany资源?

时间:2012-11-13 17:00:12

标签: django tastypie

我在django中有一个稍微复杂的模型结构,其中包含一个UserProfile

class UserProfile(models.Model):
    shoppinglist = models.ManyToManyField(Offer)
    user         = models.OneToOneField(User)
    follows = models.ManyToManyField('self', related_name='followers', symmetrical=False, blank=True)

和优惠

class Offer(models.Model):
    description = models.CharField(max_length=200)

这意味着每个用户都可以关注其他用户,并可以使用他们喜欢的优惠创建购物清单。

我可以创建一个查询,以查看优惠是否在我所关注的任何人的购物清单中

profile.follows.filter(shoppinglist=offer)

并返回UserProfile对象的查询集。

现在,我在我的tastypie API中有了OfferResource和UserProfileResource来代表这两个模型。

我需要做的是,每当我收到优惠清单时,都会在每个优惠中添加一个自定义字段,其中包含我所关注的人员列表,其中包含“赞”优惠。

offer: {
    description: 'Something'
    liked_by: [
        { ... },
        { ... }
    ]
}

我知道我可以覆盖'dehydrate'方法来添加自定义字段但是如果我添加

def dehydrate(self, bundle):
    bundle.data['liked_by'] = profile.follows.filter(shoppinglist=bundle.obj)

在likes_by字段中生成的用户列表未被序列化或脱水。

任何想法?

3 个答案:

答案 0 :(得分:5)

您可以通过对OfferResource上的ToManyField的“attribute”参数使用lambda函数来“嵌入”一个包。例如:

liked_by = fields.ToManyField(
    UserProfileResource,
    attribute=lambda bundle: bundle.request.user.get_profile().follows.filter(
        shoppinglist=bundle.obj),
    full=True,
    null=True)

A little bit of documentation on that.

答案 1 :(得分:2)

您可以使用UserProfileResource对对象列表进行脱水:

class OfferResource(ModelResource):

    ...
    users = fields.ToManyField(UserProfileResource, attribute='users', full=True)

    ...
    def dehydrate_users(self, bundle):
        res = UserProfileResource()
        objects = profile.follows.filter(shoppinglist=bundle.obj)
        bundles = [res.build_bundle(obj=obj, request=bundle.request) for obj in objects]
        return [res.full_dehydrate(bundle) for bundle in bundles]

也可以为attribute kwarg提供可调用内容,但不清楚你需要什么才能查找profile个对象。如果你可以在该范围内获得它,那么你只需要返回一个查询集:

class OfferResource(ModelResource):

    ...
    users = fields.ToManyField(UserProfileResource, 
        attribute=lambda bundle: get_profile(bundle.request).follows.filter(shoppinglist=bundle.obj),
        full=True)

答案 2 :(得分:0)

对我而言,您似乎可能需要阅读tastypie文档并找出您需要扩展的内容。 因为我的猜测是你需要扩展一些东西。 不在模型中,而是在tastypie(序列化器,字段)中。 IT很难回答,因为你的意图仍然没有100%明确。

此外,由于您似乎想要汇总更多模型,请查看this link是否可以帮助您: