Написать сериализатор для модели с несколькими внешними ключами в django остальной среде - PullRequest
0 голосов
/ 21 апреля 2020

Я строю API для операций CRUD на пользовательской таблице, которая связана с таблицами стран и состояний в соответствии с определениями модели:

class Country(models.Model):
""" Model for Country"""
country_abbreviation = models.CharField(max_length=80)
country_name = models.CharField(max_length=80)
is_active = models.SmallIntegerField()

def __str__(self):
    return self.country_name


class State(models.Model):
""" model for saving state"""
state_name = models.CharField(max_length=32)
state_abbreviation = models.CharField(max_length=8)
country = models.ForeignKey(Country, related_name='states', on_delete=models.CASCADE)
is_active = models.SmallIntegerField(default=1, blank=True)

def __str__(self):
    return self.state_name

class Meta:
    """ meta class"""
    ordering = ('state_name', )

class User(models.Model):
""" model for saving user information """
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
country = models.ForeignKey(Country, related_name='user_country', on_delete=models.CASCADE)
state = models.ForeignKey(State, related_name='user_state', on_delete=models.CASCADE)
address = models.CharField(max_length=150)

def __str__(self):
    return '%d: %s %s' % (self.id, self.first_name, self.last_name)

class Meta:
    """ meta class """
    ordering = ('first_name', )

Я пишу сериализаторы таким образом, что пока я получаю записи из пользовательской таблицы для каждой строки в таблице должна быть доступна вся информация о стране и штате, связанная с этой конкретной строкой, а не только их идентификаторы соответственно:

class UserSerializer(serializers.ModelSerializer):

class Meta:
    model = User
    fields = ['id', 'first_name', 'last_name', 'country', 'state', 'address']

Ожидаемый ответ:

{ 
"count": 1,
"next": null,
"previous": null,
"results": [ 
    { 
        "id": 1,
        "first_name": "Satish",
        "last_name": "Kumar",
        "country": { 
            "id": 23,
            "country_name": "India" 
        }, 
        "state": { 
            "id": 22,
            "state_name": "Delhi"
        },
        "address": "New Delhi" 
    } 
],
"page_size": 10, 
"model_type": "User" 

}

Я получаю:

{
"count": 1,
"next": null,
"previous": null,
"results": [
    {
        "id": 1,
        "first_name": "Satish",
        "last_name": "Kumar",
        "country": 23,
        "state": 22,
        "address": "New Delhi"
    }
],
"page_size": 10,
"model_type": "User"

}

В views.py коды выглядят так:

class UserList(generics.ListCreateAPIView):
filter_backends = [filters.SearchFilter, filters.OrderingFilter]
search_fields = ['first_name', 'last_name']
ordering_fields = ['id', 'first_name', 'last_name']
ordering = ['first_name']
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = [permissions.IsAuthenticated]

def list(self, request, *args, **kwargs):
    page_size_req = self.request.query_params.get('page_size', None)
    if page_size_req is not None:
        records_per_page = page_size_req
        pagination.PageNumberPagination.page_size = int(page_size_req)
    else:
        records_per_page = 10
    response = super().list(request, args, kwargs)
    # Add additional info required:
    response.data['page_size'] = records_per_page
    response.data['model_type'] = 'User'
    return response

Может кто-то, пожалуйста, помогите мне разобраться, как мне добиться желаемых результатов в этом случае? Спасибо за ваше время заранее.

1 Ответ

1 голос
/ 21 апреля 2020

В этом случае добавьте depth в ваш сериализатор:

class UserSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = ['id', 'first_name', 'last_name', 'country', 'state', 'address']
        depth = 1
...