1

DRF 3.1.3,Django 1.8.3

i have several model just like following code:

Post

class Post(models.Model):
    class Meta:
        ordering = ['-updated_time']

    author = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='+')
    circle = models.ForeignKey('circle')

    TYPE_CHOICES = (
        ('M', _('Members')),
        ('O', _('Org')),
    )
    type = models.CharField(_('Type'), choices=TYPE_CHOICES, default='M', max_length=1, help_text=u"帖子类型,是成员发帖,还是组织发帖?")

    created_time = models.DateTimeField(auto_now_add=True, db_index=True, editable=False)
    updated_time = models.DateTimeField(auto_now=True, db_index=True, editable=False)

    like = models.PositiveIntegerField(default=0)

    comments = GenericRelation(PostComment)
    images = GenericRelation(PostImage)
    likes = GenericRelation(PostLike)

    is_removed = models.BooleanField(_('Is Removed'), default=False, db_index=True)

RichPost

class RichPost(models.Model):
    title = models.CharField(max_length=100)
    summary = models.TextField(max_length=560)
    content = models.TextField(max_length=16000)

    post = models.OneToOneField(Post, related_name='rich')

SimplePost

class SimplePost(models.Model):
    content = models.TextField(max_length=560)
    post = models.OneToOneField(Post, related_name='simple')

PostSerializer

class PostSerializer(serializers.ModelSerializer):
    images = PostImageSerializer(many=True)

    simple = SimplePostSerializer(many=False)
    rich = RichPostSerializer(many=False)

    is_liked = serializers.SerializerMethodField('is_liked_by_user')

    def create(self, validated_data):
        simple = validated_data.pop('simple')
        rich = validated_data.pop('rich')
        post = Post.objects.create(**validated_data)
        return post

    def is_liked_by_user(self, obj):
        request = self.context['request']
        obj_type = ContentType.objects.get_for_model(obj)
        if PostLike.objects.filter(author=request.user, content_type__pk=obj_type.id, object_id=obj.id).exists():
            return True
        else:
            return False

    class Meta:
        model = Post
        fields = ('id', 'author', 'circle', 'type', 'created_time', 'updated_time', 'like', 'is_removed',
                  'images', 'comments_count', 'is_liked', 'simple', 'rich')
        read_only_fields = ('comments_count', 'is_liked', 'created_time', 'updated_time', 'like', 'author')

Post belongs one of RichPost and SimplePost.

when i created the Post,both of them are required.

for instance,when i sent simple.content,the rich.title,rich.summary,rich.content are required.

then,i found the api document: writable-nested-representations

i overrode .create() methods

but it does not been invoked at all,is_valid() before attempting to access the validated data, or save an object instance

Anyone has an idea?Thanks for any answer.

2
  • can you post your serializer code? Commented Aug 18, 2015 at 5:36
  • @soooooot sorry,i have posted it Commented Aug 18, 2015 at 5:44

2 Answers 2

2

Both rich and simple posts are required in your serializer. You should make them optional. If you need at least one of them to be required, you can do that in validate():

class PostSerializer(serializers.ModelSerializer):
    simple = SimplePostSerializer(required=False)
    rich = RichPostSerializer(required=False)
    ...
    def validate(self, data):
        data = super(PostSerializer, self).validate(data)
        if not any([data.get('simple'), data.get('rich')]):
            raise serializers.ValidationError('Either simple or rich is required')
        return data
Sign up to request clarification or add additional context in comments.

1 Comment

It is helpful,but this does not solve the problem.When i from DRF 3.1.3 upgraded to DRF 3.2.2,it works.Anyway,Thanks.
0

When i from DRF 3.1.3 upgraded to DRF 3.2.2,I don't know what was going on,it just works :(

It pass through .is_valid() to reach the .create().

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.