TypeError: Field 'id' expected a number but got <django.db.models.fields.related_descriptors
TypeError: Field 'id' expected a number but got <django.db.models.fields.related_descriptors
我有一个简单的视图,用于显示根据请求数据的用户类型有条件地过滤的所有当前用户。
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)
像这样的简单过滤器没有任何错误,但因为我需要根据请求用户过滤响应
这就是我想要使用的
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
但是这向我显示了如下错误:
Field 'id' expected a number but got <django.db.models.fields.related_descriptors.create_forward_many_to_many_manager.<locals>.ManyRelatedManager object at 0x0000019D64AE7D60>.
我怀疑它与一个多对多字段有关,我有一个名为 owns 的字段,这是我在其中一种情况下用来过滤的字段,但不知道为什么会抛出错误
我认为不是
queryset = User.objects.filter(
type=User.TYPES.TEACHER, workes=request.owns)
你应该尝试这样的事情:
queryset = User.objects.filter(
type=User.TYPES.TEACHER, workes__in=request.owns.all())
或
queryset = User.objects.filter(
type=User.TYPES.TEACHER, workes__in=request.owns.values_list("id", flat=True))
它应该匹配具有来自 request.owns 个 ID 的所有 ID 的所有用户。
我有一个简单的视图,用于显示根据请求数据的用户类型有条件地过滤的所有当前用户。
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)
像这样的简单过滤器没有任何错误,但因为我需要根据请求用户过滤响应
这就是我想要使用的
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
但是这向我显示了如下错误:
Field 'id' expected a number but got <django.db.models.fields.related_descriptors.create_forward_many_to_many_manager.<locals>.ManyRelatedManager object at 0x0000019D64AE7D60>.
我怀疑它与一个多对多字段有关,我有一个名为 owns 的字段,这是我在其中一种情况下用来过滤的字段,但不知道为什么会抛出错误
我认为不是
queryset = User.objects.filter(
type=User.TYPES.TEACHER, workes=request.owns)
你应该尝试这样的事情:
queryset = User.objects.filter(
type=User.TYPES.TEACHER, workes__in=request.owns.all())
或
queryset = User.objects.filter(
type=User.TYPES.TEACHER, workes__in=request.owns.values_list("id", flat=True))
它应该匹配具有来自 request.owns 个 ID 的所有 ID 的所有用户。