[Answered ]-Returning queryset that uses a foreign key of a foreign key relationship

1👍

Honestly, your endpoint and view are a little bit strange. Probably because you are thinking of using a intermediate model as ViewSet.

Instead what makes more sense is to have a CompaniesViewSet with an extra action where you can list all users for a given company. Also, you can access User and UserExtended in both ways using relations:

views.py:

class CompaniesViewSet(mixins.ListModelMixin,
                        mixins.RetrieveModelMixin,
                        viewsets.GenericViewSet):
    
    queryset = Companies.objects.all()
    serializer_class = CompaniesSerializer

    @action(detail=False, methods=['get'])
    def users(self, request):
        pk = request.GET.get('company_uuid', None)
        if pk:
            try:
                instance  = self.get_queryset().get(pk=pk)
                # I Would also change this related name
                qs = instance.user_to_company.all()

                user_list = []
                for obj in qs:
                    # Odd way to access because of your models fields.
                    serializer = UserSerializer(obj.user_uuid.user_id)
                    user_list.append(serializer.data)

                return Response(user_list)
            except ValidationError:
                return Response(
                    {'msg': 'Object with does not exist'}, 
                    status=status.HTTP_404_NOT_FOUND
                )
        else:
            return Response(
                {'msg': 'missing query string param'}, 
                status=status.HTTP_400_BAD_REQUEST
            )

serializers.py

from django.contrib.auth import get_user_model
from django.forms import model_to_dict

class UserSerializer(serializers.ModelSerializer):
    user_extended = serializers.SerializerMethodField()
    
    class Meta:
        model = get_user_model()
        fields = ['username', 'email', 'user_extended']

    def get_user_extended(self, instance):
        # Another odd way to access because of model name
        return model_to_dict(instance.userextended)

class CompaniesSerializer(serializers.ModelSerializer):
    class Meta:
        model = Companies
        fields = '__all__'

So, if you register the following:

router = routers.DefaultRouter()
router.register(r'companies', views.CompaniesViewSet)
urlpatterns = [
    path('api/', include(router.urls))
]

endpoint:

/api/companies/users/?company_uuid=0450469d-cbb1-4374-a16f-dd72ce15cf67
👤Niko

0👍

To get the User object, you could do something like:

ext_user = UserExtended.objects.get(uuid=self.request.GET['user_uuid'])
auth_user = User.objects.get(id=ext_user.user_id)

Then to get the serialized format mentioned, create a AuthUserSerizalizer that matches the format,


class AuthUserSerializer(serializers.Serializer):
    auth_user_stuff_1 = serializers.Field(...)
    auth_user_stuff_2 = serializers.Field(...)
    user_extended = UserExtendedSerializer()

and pass your data to the serializer:

AuthUserSerializer(
    data={
        'auth_user_stuff_1': auth_user.auth_user_stuff_1, 
        'auth_user_stuff_2': auth_user.auth_user_stuff_2, 
        'user_extended': ext_user
    }
)

Leave a comment