Django Rest Framework - 限制嵌套序列化器的字段

时间:2017-04-01 13:57:47

标签: django serialization django-rest-framework

我有UserItem个模型,我在Items视图中遇到嵌套Item.objects.all()的问题。具体来说,我在ItemListView资源中获得了以下内容:

[  {
"id": 3,
"description": "Some test item description",
"user": {
  "id": 10,
  "username": "jason",
  "email": "test@test.com",
  "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0aW1lIjoiRnJpIE1hciAyNCAyMDo1NDo1OSAyMDE3IiwidXNlcm5hbWUiOiJqYXNvbiJ9.x4qdTF5eVKGLnrkcunm63n4d_X8xEzEYM0z48E5HKh4",
  "items": [
    {
      "id": 3,
      "description": "Some item description",
      "timestamp": "2017-03-25T15:50:08.265780Z",
      "user": 10
    },
    {
      "id": 2,
      "description": "test item description",
      "timestamp": "2017-03-24T22:28:49.904198Z",
      "user": 10
    }
  ]
},
"timestamp": "2017-03-25T15:50:08.265780Z"

},

我想要的是输出中排除的User.items。我怎么能用下面的序列化器和模型来做到这一点:

class UserSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only = True, required = False)
    confirm_password = serializers.CharField(required = False)

    class Meta:
        model = User
        fields = ('id', 'username', 'email', 'password', 'confirm_password', 'token', 'posts')
        read_only_fields = ('confirm_password', )
        depth = 1

    def create(self, validated_data):
        return User.objects.create_user(**validated_data)

    def validate(self, data):
        if data['password'] != data['confirm_password']:
        raise ValidationError('Passwords do not match')

        return data

class ItemSerializer(serializers.ModelSerializer):
    user = UserSerializer(read_only = True)

    def create(self, validated_data):
        return Item.objects.create(**validated_data)

    class Meta:
        fields = ('id', 'content', 'user', 'timestamp')
        read_only_fields = ('timestamp', )
        model = Item
        depth = 1

型号:

class User(AbstractBaseUser, PermissionsMixin):
    username = models.CharField(max_length = 50,
                                unique = True)
    email = models.EmailField(unique = True, blank = False, null = False)
    token = models.CharField(max_length = 255,
                             default = '')

    objects = UserManager()

    USERNAME_FIELD = 'username'

    def generate_token(self):
        self.token = User.objects.generate_token(user = self)
        self.save()

    @python_2_unicode_compatible
    def __str__(self):
        return '{} [Username: {}] [Email: {}]'.format(self.pk,
                                                      self.username,
                                                      self.email)

    class Meta:
        verbose_name = 'user'
        verbose_name_plural = 'users'  


class Item(models.Model):
    description = models.CharField(db_index = True, max_length = 1000)
    timestamp = models.DateTimeField(auto_now_add = True,  db_index = True)
    user = models.ForeignKey(User,
                             on_delete = models.CASCADE,
                             related_name = 'items')

    def __str__(self):
        return '{} [User: {}] [Timestamp: {}] [Slug {}]'.format(self.pk, self.user.pk, self.timestamp, self.description[:20])

    class Meta:      
        verbose_name = 'item'
        verbose_name_plural = 'items'
        ordering = ['-timestamp']

1 个答案:

答案 0 :(得分:0)

没有开箱即用的解决方案来动态设置您想要在相关模型上序列化的字段。

您需要定义UserSerializer的剥离副本并在ItemSerializer内使用它(可以在ItemSerializer类中定义它以不污染命名空间),或者扩展{{ 1}}并手动实现对动态字段序列化的一些支持,请参阅here了解一些想法(如果你想深入我想象的几层,这可能会变得棘手)。