1

我有一個叫做UserProfile的模型,它是一個OneToOneField到默認的User模型。我有一個Post型號,其UserManyToManyField。我無法爲Post編寫一個序列化程序,其中包括User作爲響應。如何序列化Django的Rest框架中有多到多的字段

UserProfile型號:

class UserProfile(models.Model): 
    user = models.OneToOneField(User) 
    name = models.CharField(max_length=255, null=True) 
    profile_picture = models.CharField(max_length=1000, null=True) 

Post型號:

class Post(models.Model): 
    text = models.TextField(null=True) 
    title = models.CharField(max_length=255, null=True) 
    created_at = models.DateTimeField(auto_now_add=True) 
    updated_at = models.DateTimeField(auto_now=True) 

    user = models.ManyToManyField(User) 

Post串行:

class PostSerializer(serializers.ModelSerializer): 
    users = UserProfileSerializer(source='user.userprofile', many=True) 

    class Meta: 
     model = Post 
     fields = ('id', 'text', 'title', 'users') 

隨着上述串行我收到以下錯誤:

Got AttributeError when attempting to get a value for field `users` on serializer `WorkSerializer`. 
The serializer field might be named incorrectly and not match any attribute or key on the `Work` instance. 
Original exception text was: 'ManyRelatedManager' object has no attribute 'userprofile'. 

編輯:我創建了另一個串行UserSerializerForPost這是在PostSerializer使用:

class UserSerializerForPost(serializers.ModelSerializer): 
    user = UserProfileSerializer(source='userprofile') 

    class Meta: 
     model = User 
     fields = ('user',) 


class PostSerializer(serializers.ModelSerializer): 
    users = UserSerializerForPost(source='user', many=True) 

    class Meta: 
     model = Post 
     fields = ('id', 'text', 'title', 'users') 

雖然這工作,但我正在逐漸在user字典UserProfile響應爲users列表:

"users": [ 
    { 
    "user": { 
     "id": 2, 
     ... 
    }, 
    { 
    "user": { 
     "id": 4, 
     ... 
    } 
    } 
] 

但我想:

"users": [ 
    { 
    "id": 2, 
    ... 
    }, 
    { 
    "id": 4, 
    ... 
    } 
    } 
], 
+0

這是因爲您正在'UserSerializerForPost'序列化程序中定義'user'字段。刪除該字段。 – Gocht

+0

沒有定義它如何提供'源'? – avi

+0

你只需要在你的Meta類中定義一個模型。 – Gocht

回答

2

以下解決方案工作對我來說,它甚至不要求創建UserSerializerForPost

class PostSerializer(serializers.ModelSerializer): 
    users = serializers.SerializerMethodField() 

    class Meta: 
     model = Post 
     fields = ('id', 'text', 'title', 'users') 

    def get_users(self, obj): 
     response = [] 
     for _user in obj.user.all(): 
      user_profile = UserProfileSerializer(
       _user.userprofile, 
       context={'request': self.context['request']}) 
      response.append(user_profile.data) 
     return response 

編輯:好吧,我發現比上面一個更好的方法。首先添加get_user_profilesPost

class Post(models.Model): 
    text = models.TextField(null=True) 
    title = models.CharField(max_length=255, null=True) 
    created_at = models.DateTimeField(auto_now_add=True) 
    updated_at = models.DateTimeField(auto_now=True) 

    user = models.ManyToManyField(User) 

    def get_user_profiles(self): 
     return UserProfile.objects.filter(user__post=self) 

然後,我更新了我的PostSerializer有:

class PostSerializer(serializers.ModelSerializer): 
    users = UserProfileSerializer(source='get_user_profiles', many=True) 

    class Meta: 
     model = Post 
     fields = ('id', 'text', 'title', 'users') 

這是太清潔版本較早的企業之一。

相關問題