'TypeError: Field 'id' expected a number but got <django.contrib.auth.models.AnonymousUser object at 0x048C7E90>
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
Solution 1:[1]
For those who also come here, one possible bug is (and this is what I encountered):
you might call the anonymous
userinstance somewhere else throughforeignkeyorreverse foreignkey.
For example, in my code:
- I received the anonymous request in my
CustomViewlike this:
class CustomView(RetrieveAPIView):
serializer_class = CustomSerializer
queryset =CustomModel.objects.all()
- The
CustomModelof theCustomViewhas 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",)
- To get the related
CustomRecordinstance simultaneously when getting theCustomModelinstance in the anonymous request, I used theSerializerMethodFieldin theCustomSerializerlike 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
Solution 2:[2]
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.
Solution 3:[3]
just need to add request.user.id /// this will solve for sure..
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Brad Solomon |
| Solution 3 | Bharath Kumar |
