InterSIS / django-rest-encrypted-lookup

Replace Rest Framework's IntegerField pk or id lookups with encrypted strings.
GNU General Public License v3.0
27 stars 8 forks source link

"Incorrect type. Expected json encoded string value, received str." #15

Open eileen-chen opened 7 years ago

eileen-chen commented 7 years ago

Hi:

I wanted to build a create comment API, Can you tell me why the following error occurs?

I need help, thank you!

HTTP 400 Bad Request Allow: POST, OPTIONS Content-Type: application/json Vary: Accept

{ "friend": [ "Incorrect type. Expected json encoded string value, received str." ] }

curl -X POST -H "Content-Type: application/json" -H "Authorization: JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VybmFtZSI6Im15c3lkbmV5bWFybGluQGdtYWlsLmNvbSIsImV4cCI6MTUwMjA5NDgxNywiZW1haWwiOiJteXN5ZG5leW1hcmxpbkBnbWFpbC5jb20iLCJvcmlnX2lhdCI6MTUwMjA5NDUxN30.YdErA8yXvsJD590OmL65XZj8OY_Pb-kSRBWhlC7s0v8" -d '{ "comment": "Test", "friend": "p7dvdkcokzksrdx5e4epmomnpq" }' http://localhost:8000/api/comment/create/

model.py: comment = models.CharField(max_length=30, verbose_name='Title') owner = models.ForeignKey(User, null=True, blank=True, on_delete=models.CASCADE, verbose_name='Owner', related_name='owner') friend = models.ForeignKey(User, null=True, blank=True, on_delete=models.CASCADE, verbose_name='friend', related_name='friend')

serializer.py class CommentCreateSerializer(EncryptedLookupModelSerializer): class Meta: model = Title fields = ('id', 'comment', 'owner', 'friend')

views.py class CommentCreateAPIView(CreateAPIView): serializer_class = CommentCreateSerializer permissions_classes = [IsAuthenticated] def perform_create(self, serializer): serializer.save(manager=self.request.user)

JASchilz commented 7 years ago

My head has been out of this for a while, so I'm not completely sure. I do remember encountering similar errors!

Just looking at the documentation, I do see that there is a view mixin that's required. See the README.md and ctrl-f # views.py.

Using that documentation as an example, you'll need to create your CommentCrateAPIView like so:

from rest_framework import viewsets

    class CommentCreateAPIView(EncryptedLookupGenericViewSet,
                      viewsets.mixins.CreateModelMixin,
                     )

        serializer_class = CommentCreateSerializer
        permissions_classes = [IsAuthenticated]

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

I'm taking a look now at DRF's CreateAPIView. You might also need to copy the post method from that class into your CommentCreateAPIView class.

Good luck! Hopefully that's your issue, or points you in the right direction!

eileen-chen commented 7 years ago

Dear @JASchilz :

I modify serializer.py, follow this:

    class CommentCreateSerializer(EncryptedLookupModelSerializer):
            friend = EncryptedLookupRelatedField(queryset=User.objects.all())
        class Meta:
            model = Title
            fields = ('id', 'comment', 'owner', 'friend')

But just error!>"< error block in ....

class EncryptedLookupRelatedField(EncryptedLookupFieldMixin,
                                  serializers.PrimaryKeyRelatedField):
    """
    Encrypted lookup field to be used in place of PrimaryKeyRelatedField
    """

    def to_internal_value(self, data):
        try:
            if isinstance(data, str):
                data = json.loads(data)   <---------------------this
            data = self.get_cipher().decode(data)
            return self.get_queryset().get(pk=data)
        except ObjectDoesNotExist:
            self.fail('does_not_exist', pk_value=data)
        except (TypeError, ValueError):
            self.fail('incorrect_type_encrypted_lookup', data_type=type(data).__name__)

    def to_representation(self, value):
        return self.get_cipher().encode(value.pk)

error message: data = json.loads(data) Expecting value: line 1 column 1 (char 0)

ps: data = 'p7dvdkcokzksrdx5e4epmomnpq'

Sorry, I' m beginner, so i don't know how to use EncryptedLookupGenericViewSet and viewsets.mixins.CreateModelMixin. Can you elaborate on it?

nubbnueng commented 3 years ago

@eileen-chen I think it too late. But this problem can fix by json.dumps(data) before pass it into Serializer.