DRF Allow AnonymousUser owner with HyperlinkedModelSerializer

Question:

When the book owner is authenticated it’s ok, but if the book owner is not authenticated this error appears ValueError: Cannot assign "<django.contrib.auth.models.AnonymousUser object at 0x000002677F18EE00>": "Book.owner" must be an instance of " CustomUser".. I think this problem is caused by HyperlinkedModelSerializer. The owner of the book is specified in the perform_create() method, which is taken from self.request.user. I want authenticated users or non-authenticated users to be able to create books.

models.py

class Book(models.Model):
    owner = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        blank=True,
        null=True, # allow Anonymous user
        on_delete=models.CASCADE,
        related_name="books",
    )
    title = models.TextField()

serializers.py

class BookSerializer(serializers.HyperlinkedModelSerializer):
    owner_username = serializers.ReadOnlyField(source="owner.username")

    class Meta:
        model = Book
        fields = (
            "url",
            "owner",
            "owner_username",
            "title",
        )
        read_only_fields = ("owner",)

views.py

class BookViewSet(viewsets.ModelViewSet):
    serializer_class = BookSerializer
    queryset = Book.objects.all()

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

I need your help to fix this problem.

Asked By: whoami

||

Answers:

AnonymousUser is a different model, instead of using that, you can check request.user.is_authenticated and if it’s False, set owner=None

Here’s an example:

class BookViewSet(viewsets.ModelViewSet):
    serializer_class = BookSerializer
    queryset = Book.objects.all()

    def perform_create(self, serializer):
        user = self.request.user if self.request.user.is_authenticated else None
        serializer.save(owner=user)
Answered By: NelttjeN