Skip to content
This repository has been archived by the owner on Sep 27, 2022. It is now read-only.

Image in profile can't be updated #7

Open
priyadhoundiyal opened this issue May 19, 2017 · 5 comments
Open

Image in profile can't be updated #7

priyadhoundiyal opened this issue May 19, 2017 · 5 comments

Comments

@priyadhoundiyal
Copy link
Contributor

priyadhoundiyal commented May 19, 2017

On the endpoint {{apiUrl}}/user - the PUT request does not save the image in the user's profile since image field is a SerializerMethodField(which is readonly) in ProfileSerializer.

I was thinking that one way to allow image to be updated could be to remove image as a SerializerMethodField but keep it included in serializer fields like so:

class ProfileSerializer(serializers.ModelSerializer):
    username = serializers.CharField(source='user.username')
    bio = serializers.CharField(allow_blank=True, required=False)
    following = serializers.SerializerMethodField()

    class Meta:
        model = Profile
        fields = ('username', 'bio', 'image', 'following',)
        read_only_fields = ('username',)

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

        if request is None:
            return False

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

        follower = request.user.profile
        followee = instance

        return follower.is_following(followee)

But in this way we end up losing the default image for the profile in the {{apiUrl}}/profiles/ view.

To get the default image in the {{apiUrl}}/user view - we could include image as a SerializerMethodField there
image = serializers.SerializerMethodField()
and define get_image as:

def get_image(self, obj):
    if obj.profile.image:
        return obj.profile.image
    return 'https://static.productionready.io/images/smiley-cyrus.jpg'

but I don't think it's very consistent if the user endpoint shows a default value for the image but the profile endpoint does not.
Could anyone share another - hopefully consistent - way to do this?
TIA

@Brian-Azizi
Copy link

@priyadhoundiyal One way to keep it consistent is to extend your solution in the following way:

You can create a custom field that extends the URL Field.

This allows you override the to_representation method to give you a default value and theto_internal_value method to still allow you to write to the field:

class ImageSerializerField(serializers.URLField):
    def get_attribute(self, obj):
        # We pass the object instance onto `to_representation`,
        # not just the field attribute.
        return obj

    def to_representation(self, obj):
        if obj.image:
            return obj.image

        return settings.DEFAULT_IMAGE_URL

    def to_internal_value(self, data):
        return data

(I have set the value 'https://static.productionready.io/images/smiley-cyrus.jpg' as a constant in the settings since we are now using this value in two places)

Next, in your ProfileSerializer, you can add the image attribute as ImageSerializerField

class ProfileSerializer(serializers.ModelSerializer):
    ...
    image = ImageSerializerField(allow_blank=True)
    ...

I think this is working but do let me know if you run into any problems with it.

If someone has a cleaner solution, please share :)

@abhinavsharma629
Copy link

Can you assign me this task, please?

@priyadhoundiyal
Copy link
Contributor Author

Sure @abhinavsharma629, you can create a pull request with changes in the relevant sections

@abhinavsharma629
Copy link

abhinavsharma629 commented Sep 12, 2019

Instead of using the read-only Serializer method field or a custom made image serializer and returning the image we can return the image URL in the Profile serializer, that would be correct and more efficient while handling a large number of requests for the API.

In the next PR, I will implement this.

abhinavsharma629 added a commit to abhinavsharma629/django-realworld-example-app that referenced this issue Sep 30, 2019
abhinavsharma629 added a commit to abhinavsharma629/django-realworld-example-app that referenced this issue Sep 30, 2019
@abhinavsharma629
Copy link

Please review the changes.
I think we can close these two issues now. It returns image url for profile of a user as well as updates the image url.
Besides shows the models view in the admin panel too.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants