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