Ejemplo n.º 1
0
class CommentSerializer(serializers.ModelSerializer):
    author = ProfileSerializer(read_only=True)
    createdAt = serializers.SerializerMethodField(method_name='get_created_at')
    updatedAt = serializers.SerializerMethodField(method_name='get_updated_at')

    class Meta:
        model = Comment
        fields = ['id', 'title', 'body', 'createdAt', 'updatedAt', 'author']
        read_only_fields = ['id']

    def validate(self, args):
        user = self.context.get('user', None)
        if user is None or not user.is_authenticated:
            msg = _('Comment author not set.')
            raise ValidationError(msg)
        post = self.context.get('post', None)
        if post is None:
            msg = _('Post to be commented not set.')
            raise ValidationError(msg)
        args['author'] = user.profile
        args['post'] = post
        return args

    def get_created_at(self, comment):
        return comment.created_at.isoformat()

    def get_updated_at(self, comment):
        return comment.modified_at.isoformat()
Ejemplo n.º 2
0
class CommentSerializer(serializers.ModelSerializer):
    author = ProfileSerializer(required=False)

    createdAt = serializers.SerializerMethodField(method_name='get_created_at')
    updatedAt = serializers.SerializerMethodField(method_name='get_updated_at')

    class Meta:
        model = Comment
        fields = (
            'id',
            'author',
            'body',
            'createdAt',
            'updatedAt',
        )

    def create(self, validated_data):
        article = self.context['article']
        author = self.context['author']

        return Comment.objects.create(author=author,
                                      article=article,
                                      **validated_data)

    def get_created_at(self, instance):
        return instance.created_at.isoformat()

    def get_updated_at(self, instance):
        return instance.updated_at.isoformat()
Ejemplo n.º 3
0
class OutingAttendanceSerializer(serializers.HyperlinkedModelSerializer):
    profile = ProfileSerializer(many=False)

    class Meta:
        model = Attendance
        fields = ('url', 'profile', 'accepted_at', 'status', 'role',
                  'is_driver', 'attendance_notes')
Ejemplo n.º 4
0
 def test_get_profile_info_not_follows(self):
     follower = Profile.objects.get(user__username='******')
     followee = Profile.objects.get(user__username='******')
     serializer = ProfileSerializer(followee,
                                    context={'user': follower.user})
     self.assertEqual(serializer.data['username'], followee.user.username)
     self.assertEqual(serializer.data['about'], followee.about)
     self.assertEqual(serializer.data['pic'], followee.pic)
     self.assertFalse(serializer.data['following'])
class ArticleCommentSerializer(serializers.ModelSerializer):
    user = ProfileSerializer(read_only=True, required=False)
    # user = serializers.PrimaryKeyRelatedField(read_only=True, required=False)
    user__user = AccountSerializer(read_only=True, required=False)
    # article = ArticleSerializer(read_only=True, required=False)
    article = serializers.PrimaryKeyRelatedField(read_only=True,
                                                 required=False)
    liked = serializers.SerializerMethodField()
    likes_count = serializers.SerializerMethodField()
    dislikes_count = serializers.SerializerMethodField()

    class Meta:
        model = ArticleComment
        fields = (
            'id',
            'content',
            'created_at',
            'updated_at',
            'user',
            'user__user',
            'article',
            'liked',
            'likes_count',
            'dislikes_count',
        )
        read_only_fields = (
            'created_at',
            'updated_at',
            'liked',
        )

    @staticmethod
    def setup_eager_loading(queryset):
        queryset = queryset.select_related(
            'user',
            'user__user',
        )
        return queryset

    def get_liked(self, obj):
        request = self.context.get('request')
        article_comment_like_obj = None
        if not request.user.is_authenticated:
            return article_comment_like_obj
        try:
            article_comment_like_obj = ArticleCommentLike.objects.get(
                user=request.user.profile, article_comment__id=obj.id)
        except ArticleCommentLike.DoesNotExist:
            return article_comment_like_obj

        return article_comment_like_obj.liked

    def get_likes_count(self, obj):
        return obj.article_comment_likes.filter(liked=True).count()

    def get_dislikes_count(self, obj):
        return obj.article_comment_likes.filter(liked=False).count()
Ejemplo n.º 6
0
class UserSerializer(serializers.ModelSerializer):
    profile = ProfileSerializer(source='user_profile',
                                many=False,
                                read_only=True)

    class Meta:
        model = User
        fields = ('id', 'mobile', 'email', 'username', 'nickname', 'avatar',
                  'profile', 'is_superuser', 'weixin_openid',
                  'weixin_userinfo', 'merchant', 'date_joined')
        read_only_fields = ('id', 'date_joined')
Ejemplo n.º 7
0
class AttendanceSerializer(serializers.HyperlinkedModelSerializer):
    outing = OutingSerializer(many=False)
    profile = ProfileSerializer(many=False)

    class Meta:
        model = Attendance
        fields = ('url', 'outing', 'profile', 'accepted_at', 'status', 'role',
                  'is_driver', 'attendance_notes')

    def create(self, validated_data):
        profile_data = validated_data.pop('profile')
        profile = Profile.objects.get(**profile_data)

        outing_data = validated_data.pop('outing')
        outing = Outing.objects.get(**outing_data)

        return Attendance.objects.create(profile=profile,
                                         outing=outing,
                                         **validated_data)
Ejemplo n.º 8
0
class UserSerializer(serializers.ModelSerializer):
    """Handle seralization and deserialization of User objects."""

    password = serializers.CharField(max_length=128,
                                     min_length=8,
                                     write_only=True)

    profile = ProfileSerializer(write_only=True)

    bio = serializers.CharField(source='profile.bio', read_only=True)

    image = serializers.CharField(source='profile.image', read_only=True)

    class Meta:
        model = User
        fields = ('email', 'last_name', 'first_name', 'password', 'token',
                  'bio', 'image', 'profile')

        read_only_fields = ('token', )

    def update(self, instance, validated_data):
        """Update some informations about the user."""

        profile_data = validated_data.pop('profile', {})

        password = validated_data.pop('password', None)

        for (key, value) in validated_data.items():
            setattr(instance, key, value)

        if password is not None:
            instance.set_password(password)

        instance.save()

        for (key, value) in profile_data.items():
            setattr(instance.profile, key, value)

        instance.profile.save()

        return instance
Ejemplo n.º 9
0
class CommentSerializer(serializers.ModelSerializer):
    author = ProfileSerializer(read_only=True)

    text = serializers.CharField()

    created_at = serializers.SerializerMethodField(
        method_name="get_created_at")
    updated_at = serializers.SerializerMethodField(
        method_name="get_updated_at")

    class Meta:

        model = Comment

        fields = ('author', 'text', 'created_at', 'updated_at')

    def create(self, validated_data):
        author = self.context['author']
        event = self.context['event']

        return Comment.objects.create(author=author,
                                      event=event,
                                      **validated_data)

    def get_updated_at(self, instance):
        return instance.updated_at.isoformat()

    def get_created_at(self, instance):
        return instance.created_at.isoformat()

    def get_favorited(self, instance):
        request = self.context.get('request', None)

        if request is None:
            return False

        if not request.user.is_authenticated:
            return False

        return request.user.profile.has_favorited(instance)
Ejemplo n.º 10
0
class PostCommentLikeSerializer(serializers.ModelSerializer):
    user = ProfileSerializer(read_only=True, required=False)
    post_comment = serializers.PrimaryKeyRelatedField(read_only=True,
                                                      required=False)

    class Meta:
        model = PostCommentLike
        fields = (
            'id',
            'created_at',
            'updated_at',
            'post_comment',
            'user',
            'liked',
        )
        read_only_fields = (
            'created_at',
            'updated_at',
        )

    @staticmethod
    def setup_eager_loading(queryset):
        queryset = queryset.select_related('user', 'user__user')
        return queryset

    def create(self, validated_data):
        request = self.context.get('request')
        kwargs = self.context.get('view').kwargs
        if self.Meta.model.objects.filter(
                user=validated_data.get('user'),
                post_comment=validated_data.get('post_comment')).exists():
            liked_obj = self.Meta.model.objects.get(
                user=validated_data.get('user'),
                post_comment=validated_data.get('post_comment'))
            liked_obj.liked = validated_data.get('liked')
            liked_obj.save()
        else:
            liked_obj = self.Meta.model.objects.create(**validated_data)

        return liked_obj
Ejemplo n.º 11
0
class ArticleLikeSerializer(serializers.ModelSerializer):
    user = ProfileSerializer(read_only=True, required=False)
    article = serializers.PrimaryKeyRelatedField(read_only=True,
                                                 required=False)

    class Meta:
        model = ArticleLike
        fields = (
            'id',
            'liked',
            'created_at',
            'updated_at',
            'article',
            'user',
        )
        read_only_fields = (
            'created_at',
            'updated_at',
        )

    @staticmethod
    def setup_eager_loading(queryset):
        queryset = queryset.select_related('user', 'user__user')
        return queryset

    def create(self, validated_data):
        request = self.context.get('request')
        kwargs = self.context.get('view').kwargs
        article = Article.objects.get(pk=kwargs.get('article__id'))
        if self.Meta.model.objects.filter(user=request.user.profile,
                                          article=article).exists():
            liked_obj = self.Meta.model.objects.get(user=request.user.profile,
                                                    article=article)
            liked_obj.liked = validated_data.get('liked')
            liked_obj.save()
        else:
            liked_obj = self.Meta.model.objects.create(**validated_data)

        return liked_obj
Ejemplo n.º 12
0
class MembershipSerializer(serializers.HyperlinkedModelSerializer):
    community = CommunitySerializer(required=True)
    profile = ProfileSerializer(required=True)

    class Meta:
        model = Membership
        fields = ('url', 'community', 'profile', 'status')

    def create(self, validated_data):
        profile_data = validated_data.pop('profile')
        profile = Profile.objects.get(**profile_data)

        community_data = validated_data.pop('community')
        if ('url' in community_data.keys()):
            community = Community.objects.get(**community_data)
        else:
            community = Community.objects.create(created_by=profile,
                                                 **community_data)

        return Membership.objects.create(community=community,
                                         profile=profile,
                                         **validated_data)
Ejemplo n.º 13
0
class EventSerializer(serializers.ModelSerializer):

    author = ProfileSerializer(read_only=True)

    description = serializers.CharField(required=True)

    event_name = serializers.CharField(required=True)

    event_date = serializers.DateField(required=True)

    event_time = serializers.TimeField(required=True)

    location = serializers.CharField(required=True)

    favorited = serializers.SerializerMethodField()

    favoritesCount = serializers.SerializerMethodField(
        method_name="get_favorites_count")

    image = serializers.SerializerMethodField()

    slug = serializers.SlugField(required=False)

    createdAt = serializers.SerializerMethodField(method_name="get_created_at")

    updateAt = serializers.SerializerMethodField(method_name='get_updated_at')

    class Meta:

        model = Event

        fields = ('author', 'description', 'event_name', 'event_date',
                  'event_time', 'favorited', 'favoritesCount', 'location',
                  'image', 'slug', 'createdAt', 'updateAt')

    def create(self, validated_data):
        author = self.context.get('author', None)

        return Event.objects.create(author=author, **validated_data)

    def get_favorited(self, instance):
        request = self.context.get('request', None)

        if request is None:
            return False

        if not request.user.is_authenticated:
            return False

        return request.user.profile.has_favorited(instance)

    def get_favorites_count(self, instance):
        return instance.favorited_by.count()

    def get_created_at(self, instance):
        return instance.created_at.isoformat()

    def get_image(self, obj):
        if obj.image:
            return obj.image
        return ''

    def get_updated_at(self, instance):
        return instance.updated_at.isoformat()
class UserSerializer(serializers.ModelSerializer):
    """Handles serialization and deserialization of User objects."""

    # Passwords must be at least 8 characters, but no more than 128
    # characters. These values are the default provided by Django. We could
    # change them, but that would create extra work while introducing no real
    # benefit, so let's just stick with the defaults.
    password = serializers.CharField(max_length=128,
                                     min_length=8,
                                     write_only=True)

    # When a field should be handled as a serializer, we must explicitly say
    # so. Moreover, `UserSerializer` should never expose profile information,
    # so we set `write_only=True`.
    profile = ProfileSerializer(write_only=True)

    # We want to get the `bio` and `image` fields from the related Profile
    # model.
    bio = serializers.CharField(source='profile.bio', read_only=True)
    image = serializers.CharField(source='profile.image', read_only=True)

    class Meta:
        model = User
        fields = (
            'email',
            'username',
            'password',
            'token',
            'profile',
            'bio',
            'image',
        )

        # The `read_only_fields` option is an alternative for explicitly
        # specifying the field with `read_only=True` like we did for password
        # above. The reason we want to use `read_only_fields` here is because
        # we don't need to specify anything else about the field. For the
        # password field, we needed to specify the `min_length` and
        # `max_length` properties too, but that isn't the case for the token
        # field.
        read_only_fields = ('token', )

    def update(self, instance, validated_data):
        """Performs an update on a User."""

        # Passwords should not be handled with `setattr`, unlike other fields.
        # This is because Django provides a function that handles hashing and
        # salting passwords, which is important for security. What that means
        # here is that we need to remove the password field from the
        # `validated_data` dictionary before iterating over it.
        password = validated_data.pop('password', None)

        # Like passwords, we have to handle profiles separately. To do that,
        # we remove the profile data from the `validated_data` dictionary.
        profile_data = validated_data.pop('profile', {})

        for (key, value) in validated_data.items():
            # For the keys remaining in `validated_data`, we will set them on
            # the current `User` instance one at a time.
            setattr(instance, key, value)

        if password is not None:
            # `.set_password()` is the method mentioned above. It handles all
            # of the security stuff that we shouldn't be concerned with.
            instance.set_password(password)

        # Finally, after everything has been updated, we must explicitly save
        # the model. It's worth pointing out that `.set_password()` does not
        # save the model.
        instance.save()

        for (key, value) in profile_data.items():
            # We're doing the same thing as above, but this time we're making
            # changes to the Profile model.
            setattr(instance.profile, key, value)

        # Save the profile just like we saved the user.
        instance.profile.save()

        return instance
Ejemplo n.º 15
0
 def put(self, request, pk=None):
     user = request.user
     serializer = ProfileSerializer(user, data=request.data, partial=True)
     if serializer.is_valid(raise_exception=True):
         serializer.save(user=user)
         return response.Response(serializer.data)
Ejemplo n.º 16
0
 def list(self, request, format=None):
     user = request.user
     serializer = ProfileSerializer(user)
     return response.Response(serializer.data)
Ejemplo n.º 17
0
class PostSerializer(serializers.ModelSerializer):
    createdAt = serializers.SerializerMethodField(method_name='get_created_at')
    updatedAt = serializers.SerializerMethodField(method_name='get_updated_at')
    likes = serializers.SerializerMethodField()
    dislikes = serializers.SerializerMethodField()
    favorited = serializers.SerializerMethodField()
    author = ProfileSerializer(read_only=True)
    tagList = TagSerializer(many=True, required=False, source='tags')

    class Meta:
        model = Post
        fields = [
            'slug', 'title', 'body', 'tagList', 'createdAt', 'updatedAt',
            'favorited', 'likes', 'dislikes', 'author'
        ]
        read_only_fields = ['slug']

    def validate(self, args):
        if args == {}:
            msg = _('No data were provided.')
            raise ValidationError(msg)
        user = self.context.get('user', None)
        if user is None or not user.is_authenticated:
            msg = _(
                'You must pass a valid user in order to perform this operation.'
            )
            raise ValidationError(msg)
        args['author'] = user.profile
        args['slug'] = unique_slugify(model=self.Meta.model,
                                      text=args['title'])
        return args

    def create(self, validated_data):
        tag_data_list = validated_data.pop('tags', [])
        post = Post.objects.create(**validated_data)
        for tag_data in tag_data_list:
            tag = Tag.objects.get_or_create(**tag_data)[0]
            post.tags.add(tag)
        return post

    def update(self, instance, validated_data):
        new_tags = validated_data.pop('tags', [])
        for key, value in validated_data.items():
            setattr(instance, key, value)
        if new_tags:
            old_tags = {tag['body'] for tag in instance.tags.values('body')}
            new_tags = {tag['body'] for tag in new_tags}
            tags_to_add = new_tags.difference(old_tags)
            tags_to_remove = old_tags.difference(new_tags)
            for tag_body in tags_to_add:
                tag = Tag.objects.get_or_create(body=tag_body)[0]
                instance.tags.add(tag)
            for tag_body in tags_to_remove:
                tag = Tag.objects.get(body=tag_body)
                instance.tags.remove(tag)
        return instance

    def get_likes(self, post):
        return post.get_likes()

    def get_dislikes(self, post):
        return post.get_dislikes()

    def get_favorited(self, post):
        user = self.context.get('user', None)
        if user and user.is_authenticated:
            return user.profile.has_in_favorites(post)
        return False

    def get_created_at(self, post):
        return post.created_at.isoformat()

    def get_updated_at(self, post):
        return post.modified_at.isoformat()
Ejemplo n.º 18
0
class PostSerializer(serializers.ModelSerializer):
    # user__user = AccountSerializer(read_only=True, required=False)
    user = ProfileSerializer(read_only=True, required=False)
    # comments_count = serializers.SerializerMethodField(read_only=True, required=False)
    comments_count = serializers.IntegerField(read_only=True, required=False)
    likes_count = serializers.IntegerField(read_only=True, required=False)
    dislikes_count = serializers.IntegerField(read_only=True, required=False)
    liked = serializers.SerializerMethodField()

    class Meta:
        model = Post
        fields = (
            'id',
            'title',
            'content',
            'created_at',
            'updated_at',
            'file',
            'user',
            # 'user__user',
            'comments_count',
            'likes_count',
            'dislikes_count',
            'liked',
        )
        read_only_fields = (
            'created_at',
            'updated_at',
            'liked',
        )

    # @staticmethod
    # def get_comments_count(post):
    #     return post.get_comments_count()

    # def get_user(self, instance):
    #     request = self.context.get('request')
    #     serializer = ProfileSerializer(instance.user, context={'request': request})
    #     return serializer.data

    @staticmethod
    def setup_eager_loading(queryset):
        queryset = queryset.select_related('file', 'user', 'user__user')
        return queryset

    @staticmethod
    def annotate_comments_count(queryset):
        queryset = queryset.annotate(
            comments_count=models.Count('post_comments', distinct=True))
        return queryset

    @staticmethod
    def annotate_likes_dislikes_count(queryset):
        queryset = queryset.annotate(likes_count=models.Count(models.Case(
            models.When(post_likes__liked=True,
                        then=models.F('post_likes__pk')),
            output_field=models.IntegerField()),
                                                              distinct=True))

        queryset = queryset.annotate(dislikes_count=models.Count(
            models.Case(models.When(post_likes__liked=False,
                                    then=models.F('post_likes__pk')),
                        output_field=models.IntegerField()),
            distinct=True))

        return queryset

    def get_liked(self, obj):
        request = self.context.get('request')
        post_like_obj = None
        if not request.user.is_authenticated:
            return post_like_obj
        try:
            post_like_obj = PostLike.objects.get(user=request.user.profile,
                                                 post__id=obj.id)
        except PostLike.DoesNotExist:
            return post_like_obj

        return post_like_obj.liked
Ejemplo n.º 19
0
class ArticleSerializer(serializers.ModelSerializer):
    user = ProfileSerializer(read_only=True, required=False)
    tags = serializers.PrimaryKeyRelatedField(many=True,
                                              queryset=Tag.objects.all(),
                                              required=False)
    comments_count = serializers.IntegerField(read_only=True, required=False)
    likes_count = serializers.IntegerField(read_only=True, required=False)
    dislikes_count = serializers.IntegerField(read_only=True, required=False)
    liked = serializers.SerializerMethodField()

    class Meta:
        model = Article
        fields = (
            'id',
            'title',
            'content',
            'description',
            'slug',
            'created_at',
            'updated_at',
            'user',
            'tags',
            # 'user__user',
            'comments_count',
            'likes_count',
            'dislikes_count',
            'liked',
        )
        read_only_fields = (
            'slug',
            'created_at',
            'updated_at',
            'liked',
        )

    @staticmethod
    def setup_eager_loading(queryset):
        queryset = queryset.select_related('user', 'user__user')
        return queryset

    @staticmethod
    def annotate_comments_count(queryset):
        queryset = queryset.annotate(
            comments_count=models.Count('article_comments', distinct=True))
        return queryset

    @staticmethod
    def annotate_likes_dislikes_count(queryset):
        queryset = queryset.annotate(likes_count=models.Count(models.Case(
            models.When(article_likes__liked=True,
                        then=models.F('article_likes__id')),
            output_field=models.IntegerField(),
            default=None),
                                                              distinct=True))

        queryset = queryset.annotate(dislikes_count=models.Count(
            models.Case(models.When(article_likes__liked=False,
                                    then=models.F('article_likes__id')),
                        output_field=models.IntegerField(),
                        default=None),
            distinct=True))

        return queryset

    def get_liked(self, obj):
        request = self.context.get('request')
        article_like_obj = None
        if not request.user.is_authenticated:
            return article_like_obj
        try:
            article_like_obj = ArticleLike.objects.get(
                user=request.user.profile, article__id=obj.id)
        except ArticleLike.DoesNotExist:
            return article_like_obj

        return article_like_obj.liked

    def create(self, validated_data):
        tags = validated_data.pop('tags', [])
        article = Article.objects.create(**validated_data)

        for tag in tags:
            article.tags.add(tag)

        return article

    def update(self, instance, validated_data):
        tags = validated_data.pop('tags', [])
        for attr, value in validated_data.items():
            setattr(instance, attr, value)
        instance.save()
        instance.tags.clear()
        for tag in tags:
            instance.tags.add(tag)

        return instance
Ejemplo n.º 20
0
class FileUploadSerializer(serializers.ModelSerializer):
    user = ProfileSerializer(read_only=True, required=False)

    class Meta:
        model = FileUpload
        fields = (
            'id',
            'file',
            'file_name',
            'file_type',
            'file_content_type',
            'file_size',
            'file_path',
            'created_at',
            'updated_at',
            'user',
        )
        read_only_fields = (
            'id',
            'file_name',
            'file_type',
            'file_content_type',
            'file_size',
            'file_path',
            'created_at',
            'updated_at',
        )

    def validate(self, data):
        if data.get('file', None) is None:
            raise serializers.ValidationError(
                {'file': 'No file was submitted.'})

        if len(data['file'].name) > 75:
            raise serializers.ValidationError({
                'file':
                'File name should be less than or equal to 75 characters.'
            })

        data['file_type'] = self.get_filetype(data['file'])

        if data['file_type'] == 'image' and data[
                'file'].content_type not in ALLOWED_IMAGE_TYPES:
            raise serializers.ValidationError({
                'file':
                'Image format should be of {0}.'.format(
                    ', '.join(ALLOWED_IMAGE_TYPES))
            })
        elif data['file_type'] == 'audio' and data[
                'file'].content_type not in ALLOWED_AUDIO_TYPES:
            raise serializers.ValidationError({
                'file':
                'Audio format should be of {0}.'.format(
                    ', '.join(ALLOWED_AUDIO_TYPES))
            })
        elif data['file_type'] == 'video' and data[
                'file'].content_type not in ALLOWED_VIDEO_TYPES:
            raise serializers.ValidationError({
                'file':
                'Video format should be of {0}.'.format(
                    ', '.join(ALLOWED_VIDEO_TYPES))
            })

        return data

    @staticmethod
    def setup_eager_loading(queryset):
        queryset = queryset.select_related('user', 'user__user')
        return queryset

    # @staticmethod
    # def set_filename(file):
    #     filename_list = file.name.lower().replace(' ', '_').split('.')
    #     ext = filename_list.pop()
    #     filename = ''.join(filename_list) + get_random_string(25) + '.' + ext
    #     return filename

    @staticmethod
    def get_filetype(file):
        if file.content_type.split('/')[0] not in ALLOWED_FILE_TYPES:
            raise serializers.ValidationError({
                'file':
                'File type should be of {0}'.format(
                    ', '.join(ALLOWED_FILE_TYPES))
            })
        return ALLOWED_FILE_TYPES[ALLOWED_FILE_TYPES.index(
            file.content_type.split('/')[0])]
Ejemplo n.º 21
0
class ArticleSerializer(serializers.ModelSerializer):
    author = ProfileSerializer(read_only=True)
    description = serializers.CharField(required=False)
    slug = serializers.SlugField(required=False)

    favorited = serializers.SerializerMethodField()
    favoritesCount = serializers.SerializerMethodField(
        method_name='get_favorites_count')

    tagList = TagRelatedField(many=True, required=False, source='tags')

    # Django REST Framework makes it possible to create a read-only field that
    # gets it's value by calling a function. In this case, the client expects
    # `created_at` to be called `createdAt` and `updated_at` to be `updatedAt`.
    # `serializers.SerializerMethodField` is a good way to avoid having the
    # requirements of the client leak into our API.
    createdAt = serializers.SerializerMethodField(method_name='get_created_at')
    updatedAt = serializers.SerializerMethodField(method_name='get_updated_at')

    class Meta:
        model = Article
        fields = (
            'author',
            'body',
            'createdAt',
            'description',
            'favorited',
            'favoritesCount',
            'slug',
            'tagList',
            'title',
            'updatedAt',
        )

    def create(self, validated_data):
        author = self.context.get('author', None)

        tags = validated_data.pop('tags', [])

        article = Article.objects.create(author=author, **validated_data)

        for tag in tags:
            article.tags.add(tag)

        return article

    def get_created_at(self, instance):
        return instance.created_at.isoformat()

    def get_favorited(self, instance):
        request = self.context.get('request', None)

        if request is None:
            return False

        if not request.user.is_authenticated():
            return False

        return request.user.profile.has_favorited(instance)

    def get_favorites_count(self, instance):
        return instance.favorited_by.count()

    def get_updated_at(self, instance):
        return instance.updated_at.isoformat()