How to show foreign key strings related value in Django Rest Framework

Viewed 195

I get responses in foreign key values as shown below image

Image is here

but I want the response of values in string which Is returned from str method in models file.

my models is given below

from django.db import models
from django.contrib.auth.models import AbstractUser,AbstractBaseUser
from .Manager import Custom_Manager
# Create your models here.

class user_profile(AbstractUser):
    username = None
    first_name = models.CharField(max_length=250,blank=True,default='')
    last_name = models.CharField(max_length=250,blank=True,null=True,default='')
    email = models.EmailField(verbose_name='email_address', max_length=255, unique=True)
    address=models.CharField(max_length=250)
    profile_picture=models.ImageField(upload_to='Profile Pictures', blank=True)
    objects = Custom_Manager()
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []
    def __str__(self):
        return self.email;


class Category(models.Model):
    name=models.CharField(max_length=250,null=True,blank=True)


    def __str__(self):
        return self.name;

class Services(models.Model):
    s_name=models.CharField(max_length=255)
    provider_user=models.ForeignKey('digi_khidmat.user_profile',on_delete=models.CASCADE)
    category=models.ForeignKey(to='digi_khidmat.Category',on_delete=models.CASCADE ,blank=True,null=True)
    Services_image=models.ImageField(upload_to='Services', blank=True,null=True)
    description=models.CharField(max_length=1000,blank=True)
    services_rate_per_hour=models.IntegerField()

    def __str__(self):
        return self.s_name

class request_services(models.Model):
    services = models.ForeignKey(to='digi_khidmat.Services',
                                  on_delete=models.CASCADE,related_name="Services")
    provider_user = models.ForeignKey(to='digi_khidmat.user_profile',
                                      on_delete=models.CASCADE,related_name="service_provider")
    category = models.ForeignKey(to='digi_khidmat.Category',
                                 on_delete=models.CASCADE, blank=True, null=True )

    request_user = models.ForeignKey(to='digi_khidmat.user_profile',
                                      on_delete=models.CASCADE,related_name="request_user")
    status=models.ForeignKey(to='digi_khidmat.services_status',
                                      on_delete=models.CASCADE,related_name="request_user")

class services_status(models.Model):
    status=models.CharField(max_length=10,default='Pending')

    def __str__(self):
        return self.status;

my Serializer class is below


class user_profile_serializer(serializers.ModelSerializer):
    class Meta:
        model=user_profile
        fields='__all__'


class Category_serializer(serializers.ModelSerializer):
    class Meta:
        model=Category
        fields='__all__'

class Services_serializer(serializers.ModelSerializer):
    class Meta:
        model=Services
        fields='__all__'

class Services_status(serializers.ModelSerializer):
    class Meta:
        model=services_status
        fields='__all__'


class request_services_serializer(serializers.ModelSerializer):
    serviese_name=serializers.StringRelatedField(read_only=True)
    class Meta:
        model=request_services
        fields='__all__'

when i convert

 serviese_name=serializers.StringRelatedField(read_only=True)

to

 serviese_name=serializers.StringRelatedField(read_only=True, many=True)

it throws the following error

ceback (most recent call last):
  File "C:\Users\Muhammad Arshad\anaconda3\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
    response = get_response(request)
  File "C:\Users\Muhammad Arshad\anaconda3\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\Muhammad Arshad\anaconda3\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "C:\Users\Muhammad Arshad\anaconda3\lib\site-packages\django\views\generic\base.py", line 70, in view
    return self.dispatch(request, *args, **kwargs)
  File "C:\Users\Muhammad Arshad\anaconda3\lib\site-packages\rest_framework\views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "C:\Users\Muhammad Arshad\anaconda3\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "C:\Users\Muhammad Arshad\anaconda3\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
    raise exc
  File "C:\Users\Muhammad Arshad\anaconda3\lib\site-packages\rest_framework\views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "D:\Project\Django\djangoProject\digi_khidmat\ServicesRequest.py", line 14, in get
    return Response(services_serializer.data)
  File "C:\Users\Muhammad Arshad\anaconda3\lib\site-packages\rest_framework\serializers.py", line 745, in data
    ret = super().data
  File "C:\Users\Muhammad Arshad\anaconda3\lib\site-packages\rest_framework\serializers.py", line 246, in data
    self._data = self.to_representation(self.instance)
  File "C:\Users\Muhammad Arshad\anaconda3\lib\site-packages\rest_framework\serializers.py", line 663, in to_representation
    return [
  File "C:\Users\Muhammad Arshad\anaconda3\lib\site-packages\rest_framework\serializers.py", line 664, in <listcomp>
    self.child.to_representation(item) for item in iterable
  File "C:\Users\Muhammad Arshad\anaconda3\lib\site-packages\rest_framework\serializers.py", line 502, in to_representation
    attribute = field.get_attribute(instance)
  File "C:\Users\Muhammad Arshad\anaconda3\lib\site-packages\rest_framework\relations.py", line 538, in get_attribute
    relationship = get_attribute(instance, self.source_attrs)
  File "C:\Users\Muhammad Arshad\anaconda3\lib\site-packages\rest_framework\fields.py", line 97, in get_attribute
    instance = getattr(instance, attr)
AttributeError: 'request_services' object has no attribute 'serviese_name'
[01/Mar/2022 14:29:00] "GET /api/sr1 HTTP/1.1" 500 125633

example expected response

 {
        "id": 1,
        "services": Learn Piano,
        "provider_user": User1 email,
        "category": Music,
        "request_user": user2 email,
        "status": pending/cancel/approved
    },

but the response I get from the server

   {
        "id": 1,
        "services": 2,
        "provider_user": 1,
        "category": 2,
        "request_user": 2,
        "status": 1
    },
1 Answers

It does not make sense to set many=True: you want to work with a ForeignKey, so that means you serialize a single object.

What you need to do is use the name of the ForeignKeys, so:

class request_services_serializer(serializers.ModelSerializer):
    services = serializers.StringRelatedField(read_only=True)
    provider_user = serializers.StringRelatedField(read_only=True)
    category = serializers.StringRelatedField(read_only=True)
    request_user = serializers.StringRelatedField(read_only=True)
    status= serializers.StringRelatedField(read_only=True)
    
    class Meta:
        model=request_services
        fields='__all__'

Note: Models in Django are written in PascalCase, not snake_case, so you might want to rename the model from services_status to serviceStatus.


Note: normally a Django model is given a singular name, so Service instead of Services.

Related