Пример #1
0
class ArticleSerializer(serializers.ModelSerializer):
    author = ProfileSerializer(read_only=True)
    description = serializers.CharField(required=False)
    slug = serializers.SlugField(required=False)

    # Django REST Framework makes it possible to create a read-only field that
    # gets its 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', 'slug',
                  'title', 'updatedAt')

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

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

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

    def get_udpated_at(self, instance):
        return instance.updated_at.isoformat()
Пример #2
0
class LocalSerializer(serializers.ModelSerializer):
    createdAt = serializers.SerializerMethodField(method_name='get_created_at')
    updatedAt = serializers.SerializerMethodField(method_name='get_updated_at')
    author = ProfileSerializer(read_only=True)

    class Meta:
        model = Local
        fields = (
            'id',
            'nombre',
            'telefono',
            'createdAt',
            'direccion',
            'poblacion',
            'provincia',
            'latitud',
            'longitud',
            'foto',
            'updatedAt',
            'categoria',
            'author',
        )

    def create(self, validated_data):
        author = self.context.get('author', None)
        local = Local.objects.create(author=author, **validated_data)
        return local

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

    def get_updated_at(self, instance):
        return instance.updated_at.isoformat()
Пример #3
0
class ArticleSerializer(serializers.ModelSerializer):
    author = ProfileSerializer(read_only=True)
    description = serializers.CharField(required=False)
    slug = serializers.SlugField(required=False)

    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',
            'slug',
            'title',
            'updatedAt',
        )

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

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

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

    def get_updated_at(self, instance):
        return instance.updated_at.isoformat()
Пример #4
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')

    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()
Пример #5
0
class UserSerializer(serializers.ModelSerializer):
    password = serializers.CharField(max_length=255,
                                     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', 'username', 'password', 'token', 'profile', 'bio',
                  'image')
        read_only_fields = ('token', )

    def update(self, instance, validated_data):
        password = validated_data.pop('password', None)
        profile_data = validated_data.pop('profile', {})

        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
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()
Пример #7
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)

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

        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()
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',
            'score',
            '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()
Пример #9
0
class UserSerializer(serializers.ModelSerializer):
    """
    Handles serialization and deserialization of User objects.
    """

    # Passwords must have at >= 8 character, <= 128
    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',
            'username',
            'password',
            'token',
            'profile',
            'bio',
            'image',
        )

        # 'read_only_fields' option is alternative for explicitly specifying
        # field with 'read_only=True', like with password above
        read_only_fields = ('token', )

    def update(self, instance, validated_data):
        """
        Performs an update on a User.
        """
        password = validated_data.pop('password', None)

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

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

        if password is not None:
            # '.set_password()' handles all of the
            # security stuff that we shouldn't be concered with
            instance.set_password(password)

        # Save model
        instance.save()

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

        instance.profile.save()

        return instance
Пример #10
0
class UserSerializer(serializers.ModelSerializer):
    password = serializers.CharField(min_length=8,
                                     max_length=128,
                                     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',
            'username',
            'password',
            'token',
            'profile',
            'bio',
            'image',
        )

        read_only_fields = ('token', )

    def update(self, instance, validated_data):

        # passwords should not be updated with setattr. Will use Django's hashing and salt function
        # but need to extract it before iterating over the validated_data
        password = validated_data.pop('password', None)

        # handling profile data separately too
        profile_data = validated_data.pop('profile', {})

        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
Пример #11
0
class PlayerSerializer(serializers.ModelSerializer):
    username = ProfileSerializer(read_only=True)
    image = serializers.CharField(required=False)
    slug = serializers.SlugField(required=False)

    # 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.

    class Meta:
        model = Player
        fields = (
            'slug',
            'username',
            'image',
        )
Пример #12
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.create_at.isoformat()

    def get_updated_at(self, instance):
        return instance.create_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()
Пример #13
0
class GrantApplicationSerializer(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 = GrantApplication
        fields = (
            'id',
            'author',
            'body',
            'createdAt',
            'updatedAt',
        )

    def create(self, validated_data):

        if self.context['grant'] is None:
            raise ValueError(
                'grant should be in the context when creating a grant application'
            )

        if self.context['author'] is None:
            raise ValueError(
                'author should be in the context when creating a grant application'
            )

        grant = self.context['grant']
        author = self.context['author']

        return GrantApplication.objects.create(author=author,
                                               grant=grant,
                                               **validated_data)

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

    def get_updated_at(self, instance):
        return instance.updated_at.isoformat()
Пример #14
0
class CommentSerializer(serializers.ModelSerializer):

    author = ProfileSerializer(read_only=True)
    body = serializers.CharField()

    # Why this is not needed?
    #article = ArticleSerializer(read_only=True)

    # Call get_[~~~]_at
    createdAt = serializers.SerializerMethodField(method_name='get_created_at')
    updatedAt = serializers.SerializerMethodField(method_name='get_updated_at')

    class Meta:
        model = Comment
        # Why id is here and article is not in the fields?
        fields = (
            'id',
            'body',
            'author',
            'createdAt',
            'updatedAt',
        )

    def create(self, validated_data):

        # Where context fame from?
        author = self.context.get('author', None)
        article = self.context.get('article', None)

        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()
Пример #15
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):
        author = None
        article = None
        request = self.context.get("request")

        if request and hasattr(request, "user"):
            author = request.user.profile

        request = self.context.get("request")
        if request and hasattr(request, "article"):
            article = request.article

        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()
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()
Пример #17
0
class ArticleSerializer(serializers.ModelSerializer):
    author = ProfileSerializer(read_only=True)
    description = serializers.CharField(required=False)
    slug = serializers.SlugField(required=False)

    # Note that because we use the method get_favorited as the method_name here, we do not need to
    # specify it, as SerializerMethodField defaults to get_<field_name>
    favorited = serializers.SerializerMethodField()
    favoritesCount = serializers.SerializerMethodField(
        method_name='get_favorites_count')

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

    # DRF makes it possible to create a read-only field that gets its value by calling a function
    # In this case, the client expects created to be called createdAt and updated_at to be updatedAt.
    # serializers.SerializerMethodField is a good way to avoid having the requirements of the client
    # to leak into our previous 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_updated_at(self, instance):
        return instance.updated_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()
Пример #18
0
class UserSerializer(serializers.ModelSerializer):
    """Handles serialization and deserialization of User objects."""

    # Passwords must be 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 whil 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,
    # UserSerializers 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 user read_only_fields here is that
        # we don't need to specify anything else about the field. The
        # password field needed the min_length and max_length properties,
        # but token don't care
        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.
        # Django provides a function that handles hashing and salting passwords.
        # TRhat means 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_dictionary dict.
        profile_data = validated_data.pop('profile', {})

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

        if password is not None:
            # .set_password() handles all that good security stuffs
            instance.set_password(password)

        # 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 now with items in the Profile Model.
            setattr(instance.profile, key, value)

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

        return instance
Пример #19
0
class UserSerializer(serializers.ModelSerializer):
    """Handles serialization and deserialization of User objects."""

    # Passwords must be at least 5 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 lets 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 that
    # we don't need to specify anything else about the field. The
    # password field needed the `min_length` and
    # `max_length` properties, but that isn't the case for the token
    # field.
    read_only_fields = ('token', )

    def update(self, instance, validated_error):
        '''Performs an update on a User'''

        # Passwords should not be handled with `setattr`, unlike other fields.
        # Django provides a function that handles hashing and
        # salting passwords. That means
        # we need to remove the password field from the
        # `validated_data` dictionary before iterating over it.
        password = validated_error.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()`  handles all
            # of the security stuff that we shouldn't be concerned with.
            instance.set_password(password)

        # 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
Пример #20
0
class FoundationSerializer(serializers.ModelSerializer):
    name = serializers.CharField(
    )  # TODO: Not sure if this should be read_only
    description = serializers.CharField(required=False)
    website = serializers.URLField(required=False,
                                   allow_blank=True,
                                   allow_null=True,
                                   default=None)

    # TODO: See issue #22
    grantees = serializers.CharField(required=False)

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

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

    followed = serializers.SerializerMethodField()
    followersCount = serializers.SerializerMethodField(
        method_name='get_followers_count')

    img = serializers.SerializerMethodField(method_name='get_image_link')

    founder = ProfileSerializer(read_only=True)

    class Meta:
        model = Foundation
        fields = ('name', 'description', 'website', 'createdAt', 'founder',
                  'grantees', 'followed', 'followersCount', 'img', 'tagList',
                  'updatedAt')

    def create(self, validated_data):
        founder = self.context.get('founder', None)
        tags = validated_data.pop('tags', [])
        foundation = Foundation.objects.create(founder=founder,
                                               **validated_data)

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

        return foundation

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

    def get_followed(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.is_following_foundation(instance)

    def get_followers_count(self, instance):
        return instance.followed_by.count()

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

    def get_image_link(self, instance):
        if instance.img and hasattr(instance.img, 'url'):
            return instance.img.base_url
        return ''
Пример #21
0
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 lets just stick with the defaults.

    password = serializers.CharField(max_length=128,
                                     min_length=8,
                                     read_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 that
        # we don't need to specify anything else about the field. The
        # password field needed the `min_length` and
        # `max_length` properties, but that isn't the case for the token
        # field.
        read_only_fields = ("token", )

    def update(self, instance, validated_data):

        # password should be deleted from validated_data
        # without deleting password, password is stored as
        # usual variable
        password = validated_data.pop("password", None)

        # profile is separated table, so we do not want to
        # include profile data when updating user table
        profile_data = validated_data.pop("profile", {})

        for key, value in validated_data.items():

            setattr(instance, key, value)

        # password should be hashed nd salted
        # set_password method takes care of it
        if password is not None:
            instance.set_password(password)

        # Update User model(table)
        instance.save()

        # Update profile model(table)
        for key, value in profile_data.items():
            setattr(instance.profile, key, value)
        instance.profile.save()

        return instance
Пример #22
0
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)

    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',
            '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():
            # Set the other keys as attributes for the user instance.
            setattr(instance, key, value)

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

        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)

        instance.profile.save()

        return instance
Пример #23
0
class ArticleSerializer(serializers.ModelSerializer):

    # Three variables are specified here because they are not used
    # directly from Article model

    # This is my guess, but
    # author came from profiles.Profile model
    # Therefore, assigned ProfileSerializer with read_only=True

    # author field is defined in models.py like below
    # author = models.ForeignKey(
    #    'profiles.Profile', on_delete=models.CASCADE, related_name='articles')

    author = ProfileSerializer(read_only=True)

    # There are no TextField in serializer
    # Therefore use CharField with required=False
    description = serializers.CharField(required=False)
    body = serializers.CharField(required=False)

    favorited = serializers.SerializerMethodField()
    favoritedCount = serializers.SerializerMethodField(
        method_name='get_favorited_count')

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

    # Call get_[~~~]_at
    createdAt = serializers.SerializerMethodField(method_name='get_created_at')
    updatedAt = serializers.SerializerMethodField(method_name='get_updated_at')

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

    # override create to retrieve author from context
    # What is the context of serializers.ModelSerializer?
    def create(self, validated_data):

        print("validated_data")
        print(validated_data)
        # Where context fame from?
        author = self.context.get('author', None)

        # Why have to use pop instead get
        tags = self.validated_data.pop('tags', [])
        # tags = self.validated_data.get('tags', [])
        article = Article.objects.create(author=author, **validated_data)

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

        return article

    # Why created_at? the variable came from client like this?
    def get_created_at(self, instance):
        return instance.created_at.isoformat()

    def get_updated_at(self, instance):
        return instance.updated_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

        # check out the client already favorite an article or not
        return request.user.profile.has_favorited(instance)

    # Check out how many favorite has the article
    # It look at the instance favorited_by table
    # (It is the intermiddle table connect to profile and article
    # ManyToMany relationship)
    def get_favorited_count(self, instance):
        return instance.favorited_by.count()