-1

I'm looking to retrieve all employees (User) of the current User (id is given). Employees is a ManyToMany field of User. Currently my query retrieves the current user. And user.employees just returns the ids of all employees.

Would it be possible to make a query to retrieve all the Employees of the current User right away? Or am I just supposed to send more API calls (from the front end) for every user where I retrieve the data of the users by id?

Would be awesome if someone could steer me in the right direction. :)

views.py

# display all your employees
class EmployeeViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    def list(self, request):
        queryset = User.objects.filter(pk=request.user.pk) #get current user
        serializer = UserSerializer(queryset, many=True) 
        return Response(serializer.data)

models.py

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    employees = models.ManyToManyField(User, related_name='employees')

serializers.py

class UserSerializer(UserDetailsSerializer):

class Meta(UserDetailsSerializer.Meta):
    fields = UserDetailsSerializer.Meta.fields + ('employees')

def update(self, instance, validated_data):
    profile_data = validated_data.pop('userprofile', {})
    employees = profile_data.get('employees')

    instance = super(UserSerializer, self).update(instance, validated_data)

    # get and update user profile
    profile = instance.userprofile
    if profile_data:
        if employees:
            profile.employees = employees
        profile.save()
    return instance

rest_auth/serializers.py (dependency)

class UserDetailsSerializer(serializers.ModelSerializer):
    """
    User model w/o password
    """
    class Meta:
        model = UserModel
        fields = ('pk', 'username', 'email', 'first_name', 'last_name')
        read_only_fields = ('email', )

Example user

enter image description here

SJ19
  • 1,933
  • 6
  • 35
  • 68

2 Answers2

1
class EmployeeViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    def list(self, request):
        queryset = self.queryset.filter(id__in=request.user.employees.all())
        serializer = UserSerializer(queryset, many=True) 
        return Response(serializer.data)

Also, in the serializer you may have to do the following to get the desired response structure.

class UserSerializer(UserDetailsSerializer):
    employees = serializers.SerializerMethodField() 

    class Meta(UserDetailsSerializer.Meta):
        fields = UserDetailsSerializer.Meta.fields + ('employees')

    def get_employees(self, obj):
        return obj.userprofile.employees.all()

czarss
  • 111
  • 8
  • Getting the following error: 'AnonymousUser' object has no attribute 'employees' – SJ19 Jun 23 '20 at 19:48
  • Because that user has not logged in yet, `request.user` returns an AnonymousUser object. Django treats them as AnonymousUser and AnonymousUser does not have the employees property. Check this: https://stackoverflow.com/a/23157859/2415394 – czarss Jun 23 '20 at 19:53
  • @SJ19 You have to use [permission_classes](https://www.django-rest-framework.org/api-guide/permissions/) – JPG Jun 23 '20 at 19:56
  • you can have a look here, https://stackoverflow.com/questions/5376985/django-request-user-is-always-anonymous-user , maybe if you can share the Auth logic, we can help debug... – czarss Jun 23 '20 at 19:57
  • My bad, when I do retrieve the user first, I still get "'QuerySet' object has no attribute 'employees'" though. – SJ19 Jun 23 '20 at 20:04
  • User.objects.filter(pk=1) ... this returns a Queryset (a collection of objects). you need to do, User.objects.get(pk=1) , this will return 1 object, and it will have the employees attribute. – czarss Jun 23 '20 at 20:09
  • Ooh right, stupid mistake. Now I'm getting this weird error though "Got AttributeError when attempting to get a value for field `username` on serializer `UserSerializer`. The serializer field might be named incorrectly and not match any attribute or key on the `UserProfile` instance. Original exception text was: 'UserProfile' object has no attribute 'username'." – SJ19 Jun 23 '20 at 20:21
  • How is your UserSerializer written? The problem is over there. – czarss Jun 23 '20 at 20:22
  • Added my serializers.py to my post @czarss – SJ19 Jun 23 '20 at 20:26
  • @czarss Done. It's default from rest-auth. – SJ19 Jun 23 '20 at 20:41
  • also, mark the answer as useful, if it helped. Thanks :) – czarss Jun 23 '20 at 21:00
  • Most definitely. Thank you so much! It works now. :) Really appreciate all the help. – SJ19 Jun 23 '20 at 21:02
0

You can use a filter like: request.user.userprofile.employees.all() to fetch the employees for the specific user.

class EmployeeViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    def list(self, request):
        queryset = request.user.userprofile.employees.all() #get all employees for current user
        serializer = UserSerializer(queryset, many=True) 
        return Response(serializer.data)

This documention about One-to-one relationships would also be useful.

Jun Zhou
  • 1,077
  • 1
  • 6
  • 19