Fetching one object using DRF retrieve viewset without pk or uuid

25 Views Asked by At

I'm designing an api using python DRF for a merchant profile page. ID should not be required to be passed into the api.

I'm trying to do a simple fetch to get one object to return as a result and I read that retrieve can be used for this function.

So here's my code:

models.py:

# Create your models here.
class Merchant(models.Model):
    uuid = models.UUIDField(default=uuid.uuid4, editable=False, db_index=True)
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

    def __str__(self):
        return self.merchantprofile.organization_name


class MerchantProfile(models.Model):
    uuid = models.UUIDField(default=uuid.uuid4, editable=False, db_index=True)
    merchant = models.OneToOneField(Merchant, on_delete=models.CASCADE)
    organization_name = models.CharField(max_length=255)
    since = models.DateTimeField(auto_now_add=True)
    mobile_number = models.CharField(max_length=20, null=True, blank=True)
    email = models.EmailField(null=True, blank=True)
    website_url = models.CharField(max_length=100, null=True, blank=True)

views.py:

class MerchantProfileViewSet(AuthenticationMixin, RetrieveModelMixin, ListModelMixin, UpdateModelMixin, GenericViewSet):
    queryset = MerchantProfile.objects.all()
    serializer_class = MerchantProfileSerializer
    lookup_field = "uuid"

    def retrieve(self, request, *args, **kwargs):
        user_id = self.request.user.id       
        instance = MerchantProfile.objects.get(merchant__user=user_id)
        serializer = MerchantProfileSerializer(instance)
        return Response(serializer.data, status=status.HTTP_200_OK)

urls.py:

merchant_router = DefaultRouter()
merchant_router.register('/profile',  MerchantProfileViewSet, basename="merchantprofile")

urlpatterns = [
   path('merchant', include(merchant_router.urls)),
]

serializer.py

class MerchantProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = MerchantProfile
        fields = ["organization_name", 'since', 'mobile_number', 'email', 'website_url',
                  'facebook_url', 'instagram_url', 'tiktok_url', 'youtube_url', 'xhs_url']

No matter how I tweaked, I always get this

enter image description here

but this is how I want it to look like ( I managed to get this by using list method, but I was told that I should be able to achieve with retrieve and retrieve should be the way to go instead of using list which is a workaround in this particular case)

enter image description here

    def list(self, request):
        user_id = self.request.user.id

        try:
            qs = MerchantProfile.objects.get(merchant__user=user_id)
            serializer = self.serializer_class(qs)
            return Response(serializer.data, status=status.HTTP_200_OK)
        except:
            raise Http404("Merchant profile does not exist for the current user")

Would appreciate if someone can point out my mistakes and give me some guidance since I am very new to this, thank you!

0

There are 0 best solutions below