JasonTS
JasonTS

Reputation: 2589

How to deal with user_id field properly?

I'm working myself through a lot of examples, but I can't find a way that works 100%.

class QuestionViewSet(viewsets.ModelViewSet):
    queryset = QNAQuestion.objects.all()
    serializer_class = QuestionSerializer
    permission_classes = (IsOwnerOrReadOnly, )
    filter_fields = ('id', 'user')
    filter_backends = (filters.DjangoFilterBackend, filters.OrderingFilter)

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

This so far works fine, but it still requires the user_id to be given by the user input even though it's ignored and relpaced by request.user.

class QuestionSerializer(serializers.ModelSerializer):
    class Meta:
        user = serializers.ReadOnlyField()
        model = QNAQuestion
        fields = ('id','user','subject', 'body', 'solution')

So I think I have to modify my serializer. I tried HiddenInput and ReadOnly, but both don't really do the trick. If I make it hidden, than the the user_id is not required anymore, but it's also hidden when looking at existing objects. If I make it read only it's not required, but saving the serializer doesn't work anymore. I get the error message that the django object is not serializable to JSON.

class IsOwnerOrReadOnly(permissions.BasePermission):
    """
    Object-level permission to only allow owners of an object to edit it.
    Assumes the model instance has an `user` attribute.
    """
    def has_object_permission(self, request, view, obj):
        # Read permissions are allowed to any request,
        # so we'll always allow GET, HEAD or OPTIONS requests.
        if not request.user.is_authenticated():
          return False

        if request.method in permissions.SAFE_METHODS:
            return True
        # Instance must have an attribute named `owner`.
        return obj.user == request.user

So how can I get it fixed? The user_id should be visible, but I want it to be request.user and i don't want it to be required on creating new objects. Ideally it should also be hidden when using the auto generated api gui.

Thank you for your time. Sorry for spelling or grammar mistakes, I'm not a native speaker.

Upvotes: 0

Views: 106

Answers (1)

Todor
Todor

Reputation: 16010

Try to make the field only required=False instead of Hidden or ReadOnly.

class QuestionSerializer(serializers.ModelSerializer):
    class Meta:
        model = QNAQuestion
        fields = ('id','user','subject', 'body', 'solution')
        extra_kwargs = {
            'user': {'required': False}
        }

Upvotes: 1

Related Questions