首页 > 解决方案 > Django:当视图集中的不同序列化程序时,'int'对象不可迭代

问题描述

GET在此端点上发出请求时遇到问题: /api/vacancy/{hotel_id}/. 它应该返回特定酒店 ID 的空缺信息。

在我的架构中,空缺模型包含以下属性:

为了获得相关信息,我打算通过 调用HotelDetailsSerializerVacancy Viewset认为这可能比根据hotel_idURL 中提供的值过滤 Vacancy 表更容易,因为它会自动提供与该特定酒店相关的 Vacancy 集合ID。

提出GET请求http://localhost:8000/api/hotels/1(如下所示)提供了我需要的信息。但是,当我尝试通过Vacancy Viewset带有此端点的 获得此响应时,http://localhost:8000/api/vacancies/1我收到以下错误:

TypeError at /api/vacancies/1/
'int' object is not iterable

那么我首先要做的事情是可能的,还是有更好的方法或一些最佳实践可以在这里应用?

感谢您的回复!

这是我的Vacancy Serializer文件:

from rest_framework import serializers
from ..models.model_vacancy import Vacancy
from .serializers_room import *
from .serializers_hotel import *


class VacancyIndexSerializer(serializers.ModelSerializer):
    """
    Serializer listing all Vacancies models from DB
    """

    room_id = RoomIndexSerializer(allow_null=True)

    class Meta:
        model = Vacancy
        fields = [
            'room_id',
            'hotel_id',
            'vacancy',
            'rented'
        ]

class VacancyDetailsSerializer(serializers.ModelSerializer):
    """
    Serializer showing details of a Vacancy model from DB
    """

    room_id = RoomDetailsSerializer()

    class Meta:
        model = Vacancy
        fields = [
            'room_id',
            'vacancy',
            'rented'
        ]
  
  
class VacancyCreateSerializer(serializers.ModelSerializer):
    """
    Serializer to create a Vacancy model in DB
    """

    class Meta:
        model = Vacancy
        fields = [
            'room_id',
            'hotel_id',
            'vacancy',
            'rented'
        ]

    def create(self, validated_data):
        vacancy = Vacancy.objects.create(**validated_data)
        return stock

class VacancyUpdateSerializer(serializers.ModelSerializer):
    """
    Serializer declaring fields to be provided to update the Vacancy instance.
    """

    class Meta:
        model = Vacancy
        fields = [
            'room_id',
            'hotel_id',
            'vacancy',
            'rented'
        ]

我在其中Viewset使用另一个Serializerretrieve

from rest_framework import viewsets
from ..models.model_vacancy import Vacancy
from ..serializers.serializers_vacancy import *
from ..serializers.serializers_hotel import *


class VacancyViewSet(viewsets.ModelViewSet):
    """
    Vacancy ViewSet calling various serializers depending on request type (GET, PUT etc.)
    """
    queryset = Vacancy.objects.order_by('id')

    # mapping serializer into the action
    serializer_classes = {
        'list': VacancyIndexSerializer,
        'retrieve': HotelDetailsSerializer,
        'create': VacancyCreateSerializer,
        'update': VacancyUpdateSerializer,
        'partial_update': VacancyUpdateSerializer
  
    }

    # Your default serializer
    default_serializer_class = VacancyIndexSerializer

    def get_serializer_class(self):
        """
        Method to detect request type (GET, PUT etc.) and select corresponding serializer.
        """
        return self.serializer_classes.get(self.action, self.default_serializer_class)

这是我的另一个Serializer

from rest_framework import serializers
from ..models.model_hotel import Hotel
from .serializers_vacancy import *


class HotelIndexSerializer(serializers.ModelSerializer):
    """
    Serializer listing all Hotels models from DB
    """

    class Meta:
        model = Hotel
        fields = [
            'id',
            'name',
        ]

class HotelDetailsSerializer(serializers.ModelSerializer):
    """
    Serializer showing details of a Hotel model from DB
    """

    vacancy = VacancyDetailsSerializer(many=True)

    class Meta:
        model = Hotel
        fields = [
            'vacancy'
        ]
  
class HotelCreateSerializer(serializers.ModelSerializer):
    """
    Serializer to create a Hotel model in DB
    """

    class Meta:
        model = Hotel
        fields = [
            'name',
        ]

class HotelUpdateSerializer(serializers.ModelSerializer):
    """
    Serializer declaring fields to be provided to update the Hotel instance.
    """

    class Meta:
        model = Hotel
        fields = [
            'name',
        ]

在邮递员中,当我请求时GEThttp://localhost:8000/api/hotels/1我得到:

{
    "vacancy": [
        {
            "room_id": {
                "room": "first",
                "name": "first one",
                "description": "description"
            },
            "vacancy": 10,
            "rented": 0
        },
        {
            "room_id": {
                "room": "second",
                "name": "second one",
                "description": "description"
            },
            "vacancy": 10,
            "rented": 0
        }
    ]
}

标签: pythondjangoserializationnested

解决方案


当为空置模型配置酒店时,您不能强制ModelViewset退回酒店以进行操作。retreive

通过在此处指定HotelDetailsSerializer,当您获取/api/vacancies/1/它是一个 ID=1 的空缺实例时,您会产生一个错误原因,该实例被传递给显然不正确的序列化器,您应该只将酒店传递给HotelDetailsSerializer.

现在,一家酒店可以分配多个职位空缺(您自己展示了它作为/api/hotels/1回应)。因此,如果您想在那时获取股票,hotel_id则请求应返回该栏的多个空缺,而不是 1。

获取多个职位空缺的 API 是GET /api/vacancies/,您只需要传递一个查询参数来过滤它,如下所示:GET /api/vacancies/?hotel=1

你可以用django-filter

按照文档中的说明安装后,将其添加到您的VacancyViewSet

filterset_fields = ['hotel']

推荐阅读