2012-11-13 72 views
1

我有在Django稍微复杂的模型结构,包括一个用户配置如何在tastypie中创建自定义嵌套的ToMany资源?

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) 

人的购物清单,并返回用户配置对象的查询集。

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

我需要做的是,每当我收到优惠列表时,都会为每个优惠添加一个自定义字段,其中包含我关注的人的列表。

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

我知道我可以重写“脱水”的方法来添加自定义字段,但如果我在liked_by字段中添加

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

用户的结果列表是没有序列号或脱水。

任何想法?

回答

5

您可以“嵌入”捆绑使用lambda函数的ToManyField上的“属性”的说法你OfferResource。例如:

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.

+0

谢谢。这正是我所需要的,它只是在获取配置文件方面进行了一点小改动。我以为我读过所有的文档,但显然我错过了这一点。这在文档中并不突出。 – manuel

0

对我来说,看起来你可能需要阅读tastypie文档并找出你需要扩展的东西。 因为我的猜测是你需要在那里扩展一些东西。 不在模型中,但在tastypie(序列化器,字段)中。 IT很难回答,因为你的意图还没有100%清楚。

而且,因为你似乎要聚集更多的车型,看看是否this link帮助你:

+0

我完成大部分的tastypie文档中去,但是这是一个非常具体的问题,有什么也没有。你认为如何让这个问题更清楚,以便我可以改进它。 – manuel

+0

编辑包含链接。 –

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提供一个可调用的,但它不是”清楚你需要什么才能查找你的对象。如果你能在该范围内得到它,那么你只需要返回查询集:

class OfferResource(ModelResource): 

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

传递属性的callable是我需要找到的。我接受了布莱克的回答,因为是我需要的确切解决方案,但第一部分关于脱水的问题对我遇到的另一个问题也非常有用。感谢您的回答。 – manuel