2

This is related to the question : Assymetric nature of GET and POST in a Django REST framework Serializer . I've put it as a fresh question, instead of putting more questions in that thread, accordingly to SO guidelines

I am writing a Viewset and a ModelSerializer for the User model to provide a /user endpoint

GET - returns list and information about all users, in the standard DRF way

POST - all I want the client to post is the facebook access_token (hence have put all other fields as read_only in serializer. The pre_save() in ViewSet is wired to use this access token and it uses django-facebook to pull data from facebook api (using access token) and automatically create a new user with that information. Since this new user is created automatically, I want to suppress the normal DRF flow during POST and not create another user via DRF. How do i do this?

views.py

from open_facebook import OpenFacebook
from django_facebook.api import FacebookUserConverter
from django_facebook.connect import connect_user

class UserViewSet(viewsets.ModelViewSet):

    queryset = models.User.objects.all()

    serializer_class = UserSerializer

    def pre_save(self, obj):


        access_token = obj.access_token
        facebook = OpenFacebook(access_token)
        conv = FacebookUserConverter(facebook)

        action, user = connect_user(self.request, access_token)
        # this creates an entire new row, just as required, in the variable "user", so all I want to do is suppress any other row creation in the standard POST method. connect_user fills in data like first_name, last_name, etc from facebook already, and that is exactly what I need to do.


        conv.get_and_store_friends(user)

        obj = user
        user.delete()
        # I am trying to do that by copying user to obj and deleting user, but at the end of it i 

        print obj.username

serializers.py

class UserSerializer(serializers.HyperlinkedModelSerializer):
    """
User Serializer
"""

    class Meta:
        model = models.User
        fields = ('id', 'username', 'first_name', 'last_name', 'activities', 'image_url', 'url', 'access_token')

        read_only_fields = ('username', 'first_name', 'last_name', 'image_url', 'activities') #todo: find out a shortcut to invert selection

        # show activities with user details rather than separately to remove an extra server call
        depth = 1
Community
  • 1
  • 1
dowjones123
  • 3,695
  • 5
  • 40
  • 83
  • OK, I am a bit confused. You are using a ReadOnlyModelViewSet, which is _A viewset that provides default `list()` and `retrieve()` actions._, hence only the GET method is mapped onto it. How exactly is your pre_save method being called? – AdelaN Jul 17 '14 at 08:51
  • You are right, it is ModelViewSet, not ReadOnlyModelViewSet - was playing around and playing to see how the latter works, and forgot to change back when I copied the code to this question. Have edited question now. Thanks – dowjones123 Jul 17 '14 at 09:13
  • OK, now all you have to do is put your code from **pre_save** to **create** in order to override the default behavior. Look [here](https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/mixins.py) to see what the method currently does and rewrite it to do what you want. :) – AdelaN Jul 17 '14 at 09:30
  • Using create() worked, thanks – dowjones123 Jul 22 '14 at 23:36

1 Answers1

1

using the create() function of ModelViewSet worked, instead of pre_save - to suppress saving the object

dowjones123
  • 3,695
  • 5
  • 40
  • 83