2012-11-13 67 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