Mike Mike - 3 months ago 38
Python Question

Django REST: create CRUD operations for OneToOne Field

I'm trying to create basic CRUD operations for OneToOne field.
The user is not required to set the profile when signing in. How do I create/update/delete profile when needed (assuming the user is already in the DB)?

My models are the default User models from Django REST and:

class UserProfile(models.Model):
user = models.OneToOneField(User)
location = models.CharField(max_length=50,blank=True)
title = models.CharField(max_length=80,blank=True)
#picture = models.ImageField(upload_to='user_imgs', blank=True)
website = models.URLField(blank=True)


My Viewsets are:

class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
filter_fields = ['id', 'username', 'email', 'first_name', 'last_name']

class UserProfileViewSet(viewsets.ModelViewSet):
queryset = UserProfile.objects.all()
serializer_class = UserProfileSerializer
filter_fields = ['user_id', 'location', 'title', 'website']


And serializes:

class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
email = serializers.EmailField()
fields = ('id','username', 'email', 'first_name', 'last_name')


class UserProfileSerializer(serializers.HyperlinkedModelSerializer):
user_id = serializers.CharField(source='user.id')

class Meta:
model = UserProfile
fields = ('user_id', 'location','title','website')

Answer

I belive you want to restrict the profile creation to the current logged in user. You can filter the queryset of profiles to the current user, this way only that user's profile will be accessible by the logged in user.

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    filter_fields = ['id', 'username', 'email', 'first_name', 'last_name']


class UserProfileViewSet(viewsets.ModelViewSet):
    queryset = UserProfile.objects.all()
    serializer_class = UserProfileSerializer
    filter_fields = ['user_id', 'location', 'title', 'website']

    def get_queryset(self):
        return super(UserProfileViewSet, self).get_queryset().filter(
            user=self.request.user)

    def perform_create(self, serializer):
        serializer.save(user=user)

You make the user field read only and is being saved in the above method perform_create and assigned always to the current user.

class UserProfileSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = UserProfile
        fields = ('user', 'location','title','website')
        read_only_fields = ('user',)
Comments