Home > Software design >  TypeError: Field 'id' expected a number but got <django.db.models.fields.related_descri
TypeError: Field 'id' expected a number but got <django.db.models.fields.related_descri

Time:02-14

I have a simple view for showing all the current users that are conditionally filtered based on the user type that is requesting the data.

models.py

class User(AbstractBaseUser, PermissionsMixin):

    class SEX(models.TextChoices):
        MALE = "MALE", "Male"
        FEMALE = "FEMALE", "Female"

    class TYPES(models.TextChoices):
        ...

    type = models.CharField(
        _("User Type"), max_length=50, choices=TYPES.choices, default=None, blank=True, null=True)
    sex = models.CharField(
        _("Sex Type"), max_length=50, choices=SEX.choices, default=None, blank=True, null=True)
    email = models.EmailField(
        _("Your Email"), max_length=254, unique=True, default=None, blank=True, null=True)
    student_id = models.CharField(
        _("student id"), unique=True, max_length=10, blank=True, null=True)
    firstname = models.CharField(max_length=250, blank=False, null=True)
    middlename = models.CharField(max_length=250, blank=True, null=True)
    lastname = models.CharField(max_length=250, blank=False, null=True)
    # grade = models.ForeignKey(Grade, verbose_name=_(
    #     "grade"), on_delete=models.CASCADE, blank=True, null=True)
    room = models.ForeignKey(Class, verbose_name=_(
        "class"), on_delete=models.CASCADE, blank=True, null=True)
    phone = models.CharField(
        _("phone number"), max_length=13, blank=True, null=True)
    age = IntegerRangeField(min_value=1, max_value=99,
                            default=25, blank=True, null=True)

    owns = models.ManyToManyField(School, verbose_name=_(
        "School_owner"), related_name='Schoolowner', blank=True)

    workes = models.ForeignKey(School, verbose_name=_(
        "School_workes"), related_name='Schoolworkes', on_delete=models.SET_NULL, blank=True, null=True)

    learns = models.ForeignKey(School, verbose_name=_(
        "School_learns"), related_name='Schoollearns', on_delete=models.SET_NULL, blank=True, null=True)

    image = models.ImageField(
        _("photo"), upload_to='user/pp', max_length=None, blank=False, null=True)
    joined_date = models.DateTimeField(
        _("created at"), auto_now=False, auto_now_add=True)
    is_active = models.BooleanField(default=False)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    last_login = models.DateTimeField(
        _("last login"), auto_now=True, auto_now_add=False)

serializers.py

  class MyAccountSerializer(serializers.ModelSerializer):
        image = serializers.ImageField()
    
        class Meta:
            model = User
            fields = ['id', 'sex', 'type', 'phone', 'image', 'email', 'student_id', 'firstname', 'middlename', 'lastname',
                      'image', 'joined_date', 'is_active', 'is_superuser', 'is_staff', 'last_login']

views.py

class TeacherList(generics.ListAPIView):
permission_classes = [IsAuthenticated, ]
serializer_class = ListUsersSerializer
queryset = User.objects.filter(type=User.TYPES.TEACHER)

A simple filter like this works without any errors but since I need to filter the response based on the requesting user

this is what I want to use

class TeacherList(generics.ListAPIView):
    permission_classes = [IsAuthenticated, ]
    serializer_class = ListUsersSerializer
    # queryset = User.objects.filter(type=User.TYPES.TEACHER)

    def get_queryset(self):
        request = self.request.user
        if request.type == User.TYPES.OWNER:
            queryset = User.objects.filter(
                type=User.TYPES.TEACHER, workes=request.owns)
        elif request.type in [User.TYPES.STAFF, User.TYPES.DIRECTOR, User.TYPES.VICE_DIR]:
            queryset = User.objects.filter(
                type=User.TYPES.TEACHER, workes=request.workes)
        return queryset

however this shows me an error that goes like this:

Field 'id' expected a number but got <django.db.models.fields.related_descriptors.create_forward_many_to_many_manager.<locals>.ManyRelatedManager object at 0x0000019D64AE7D60>.

I suspect it has something to do with a many-to-many field of which I have one named owns which is what I'm using to filter in 1 of the conditions but don't know why it throws error

CodePudding user response:

I think instead of

queryset = User.objects.filter(
            type=User.TYPES.TEACHER, workes=request.owns)

You should try something like:

queryset = User.objects.filter(
            type=User.TYPES.TEACHER, workes__in=request.owns.all())

or

queryset = User.objects.filter(
            type=User.TYPES.TEACHER, workes__in=request.owns.values_list("id", flat=True))

It should match all Users that have all ids from request.owns ids.

CodePudding user response:

The error is for the foreign key filter workes=request.owns as it expects an id, you can simply try workes_id=request.workes_id in the filter

  • Related