8
Cannot cast AnonymousUser to int.
Are you trying to use it in place of User?

I am unsure how to adjust my code to stop generating this error when i make a post request to my url. I have attached code for my serializers, views and models.

class ActivitySessionSerializer(serializers.Serializer):
    activity_name = serializers.CharField(min_length=1, max_length=100)

    def create(self, validated_data):
        activity, created = Activity.objects.get_or_create(name=validated_data['activity_name'], 
        owner=self.context['request'].user)

        return ActivitySession.objects.create(activity=activity, start_time=datetime.datetime.now())



class StartSessionView(generics.CreateAPIView):
    serializer_class = serializers.ActivitySessionSerializer


    User = get_user_model()
    
    class ActivityType(models.Model):
        name = models.CharField(max_length=100)
        user = models.ForeignKey(User, on_delete=models.CASCADE)

    class Activity(models.Model):
        name = models.CharField(max_length=100)
        owner = models.ForeignKey(User, on_delete=models.CASCADE)
        activity_type = models.ForeignKey(ActivityType, on_delete=models.CASCADE, null=True, blank=True)

    class ActivitySession(models.Model):
        activity = models.ForeignKey(Activity, on_delete=models.CASCADE)
        start_time = models.DateTimeField()
        end_time = models.DateTimeField()


    urlpatterns = [
        path('starting_session/', views.StartSessionView.as_view()),
    ]

I believe i solved it by changing line

Activity.objects.get_or_create(name=validated_data['activity_name'], 
        owner=self.context['request'].user)

to

Activity.objects.get_or_create(name=validated_data['activity_name'], 
        owner=self.context['request'].user.id)

I had to add id field specifically instead of the total user object

Brad Solomon
  • 38,521
  • 31
  • 149
  • 235
Daniel W
  • 99
  • 1
  • 1
  • 4
  • Does this answer your question? [ForeignKey to AnonymousUser](https://stackoverflow.com/questions/60512180/foreignkey-to-anonymoususer) – Brad Solomon Jul 18 '20 at 17:09

3 Answers3

8

just need to add request.user.id /// this will solve for sure..

Bharath Kumar
  • 893
  • 9
  • 8
4

For those who also come here, one possible bug is (and this is what I encountered):

you might call the anonymous user instance somewhere else through foreignkey or reverse foreignkey.

For example, in my code:

  1. I received the anonymous request in my CustomView like this:
class CustomView(RetrieveAPIView):
    serializer_class = CustomSerializer
    queryset =CustomModel.objects.all()
  1. The CustomModel of the CustomView has a reverse foreignkey-which_model, like this:
from django.contrib.auth import get_user_model
User = get_user_model()

class CustomModel(BaseModel):
    name = models.CharField(verbose_name="Custom name", max_length=256)
 
class CustomRecord(BaseModel):
    which_user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="related user")
    which_model = models.ForeignKey("CustomModel", on_delete=models.CASCADE, verbose_name="related model",related_name="user_record",)

  1. To get the related CustomRecord instance simultaneously when getting the CustomModel instance in the anonymous request, I used the SerializerMethodField in the CustomSerializer like this:
class CustomSerializer(ModelSerializer):
    related_user_record = SerializerMethodField(read_only=True, source="user_record")
    def get_related_user_record(self, obj):
        # This is where the problem is !!!!
        user_record = CustomRecord.objects.filter(
            which_model=obj.id, which_user=self.context["request"].user
        )
        if not user_record:
            return None
        else:
            return CustomRecordSerializer(user_record.get()).data

Because I used the self.context["request"].user in get_related_user_record function, django try to convert the id of user instance to int; However, like @Brad Solomon said, the anonymous user's id or pk is None., that's where the error comes from. And honestly, djano didn't do well in reporting the bug source when this error happens.

What I did to sovle this problem is that I added a check before using the user instance, to see if it's an anonymous user, like this:

def get_related_user_record(self, obj):
    # check if it's an anonymous user
    if not self.context["request"].user.pk:
        return None
    # This is where the problem is !!!!
    user_record = CustomRecord.objects.filter(
        which_model=obj.id, which_user=self.context["request"].user
    )
    if not user_record:
        return None
    else:
        return CustomRecordSerializer(user_record.get()).data
sdsy888
  • 41
  • 5
3

AnonymousUser has id=None and pk=None, so is not directly useable in this situation. Instead, the recommendation is to create an instance of user that reflects an anonymous user.

Brad Solomon
  • 38,521
  • 31
  • 149
  • 235