Django - извлекает вложенные поля на несколько уровней, используя внешние ключи - PullRequest
0 голосов
/ 27 мая 2018

Я изо всех сил пытаюсь написать Django GET, который возвращает следующий выглядящий ответ:

{
"lists": [
    {
        "id": "123",
        "list_order": [
            {
                "id": "123_1",
                "order": 1,
                "list_id": "123",
                "item_id": 9876,
                "item": {
                   "id": 9876,
                   "name": "item1",
                   "location": "California"
                }
            },
            {
                "id": "123_2",
                "order": 2,
                "list_id": "123",
                "item_id": 2484,
                "item": {
                   "id": 2484,
                   "name": "item2",
                   "location": "California"
                }
            }            
        ],
        "updated_date": "2018-03-15T00:00:00Z"
    }
  ]
}

С учетом list_id ответ возвращает основную информацию в списке ("id", "updated_date"), а также порядок пунктов в списке.Внутри каждого элемента в порядке списка он также захватывает связанные с ним детали элемента (вложенные в «элемент»).Я могу получить этот ответ без подробностей «item» («id», «name», «location») и без ошибок:

{
"lists": [
    {
        "id": "123",
        "list_order": [
            {
                "id": "123_1",
                "order": 1,
                "list_id": "123",
                "item_id": 9876
            },
            {
                "id": "123_2",
                "order": 2,
                "list_id": "123",
                "item_id": 2484
            }            
        ],
        "updated_date": "2018-03-15T00:00:00Z"
    }
  ]
}

Опять нет ошибок, и яможет получить первый вложенный уровень без каких-либо проблем.Проблема в том, что информация «item» отображается в каждом «list_order».Ниже приведены мои модели, сериализаторы и представления.

models.py

class Lists(models.Model):
    id = models.CharField(null=False, primary_key=True, max_length=900)
    updated_date = models.DateTimeField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'tbl_lists'

class Items(models.Model):
    id = models.BigIntegerField(primary_key=True)
    name = models.TextField(blank=True, null=True)
    location = models.TextField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'tbl_items'

class ListOrder(models.Model):
    id = models.CharField(null=False, primary_key=True, max_length=900)
    list_id = models.ForeignKey(Lists, db_column='list_id', related_name='list_order')
    item_id = models.ForeignKey(Items, db_column='item_id', related_name='items')
    order = models.BigIntegerField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'tbl_list_order'

serializers.py

class ItemsSerializer(serializers.ModelSerializer):

    class Meta:
        model = Items
        fields = '__all__'

class ListOrderSerializer(serializers.ModelSerializer):

    item = ItemsSerializer(many=False, read_only=True)

    class Meta:
        model = ListOrder
        fields = '__all__'

class ListsSerializer(serializers.ModelSerializer):

    list_order = ListOrderSerializer(many=True, read_only=True)

    class Meta:
        model = Lists
        fields = '__all__'

views.py

class ListsViewSet(generics.ListCreateAPIView):
    """
      API endpoint that returns a list with its meta-information
    """

    queryset = Lists.objects.all()
    serializer_class = ListsSerializer  

    def get_queryset(self):
        list_id = self.kwargs['list_id']

        filters = [Q(id=list_id)]

        return Lists.objects.filter(*filters)


    def list(self, request, list_id):

        queryset = self.get_queryset()

        list_serializer = ListsSerializer(queryset, many=True)

        return Response({ 'lists': list_serializer.data }) 

Я довольно новичок в Django и мне нравится то, что он предлагаетдо сих пор, хотя, возможно, я думаю об этом слишком «SQL».Я читал о select_related () и prefetch_related (), но не уверен, как бы применить его в этом случае.Буду признателен за любую помощь, и дайте мне знать, если есть какая-либо другая информация, которую я могу предоставить.

1 Ответ

0 голосов
/ 28 мая 2018

В вашем ListOrderSerializer вы пытаетесь сериализовать item.в то время как в модели ListOrder вы использовали имя поля item_id

Решение :

В ListOrderSerializer:

class ListOrderSerializer(serializers.ModelSerializer):
    item_id = ItemsSerializer(many=False, read_only=True)
    ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...