[使用DRF ViewSet和APIView时,对于DurationField的序列化,我得到两个不同的结果。
在第一个端点host / app / item,它对应于视图集Items
并列出了所有创建的项,我得到此响应:
[
{
"id": 2,
"duration": "604800.0",
...
}
...
]
来自host / app / user_data的响应包括与与概要文件相关的项目实例所对应的项目:
{
...
"items": [
{
"item": {
"id": 2,
"duration": "P7DT00H00M00S",
...
}
...
}
]
}
但是持续时间在ISO 8601 duration format中。这非常令人困惑,因为端点使用相同的序列化器。我通过在ItemSerializer中强制使用duration = serializers.DurationField()
进行序列化来确认这一点。我想要相同的格式,以秒为单位。我该怎么办?
这些是我在研究此问题时发现的问题:https://github.com/encode/django-rest-framework/issues/4430https://github.com/encode/django-rest-framework/issues/4665
网址:
router = routers.DefaultRouter()
router.register(r'items', views.Items)
urlpatterns = [
path('', include(router.urls)),
path('user_data', views.UserData.as_view(), name='user_data'),
...
]
观看次数:
class Items(viewsets.ModelViewSet):
queryset = Item.objects.all()
serializer_class = ItemSerializer
def get_permissions(self):
if self.action in ('list', 'retrieve'):
permission_classes = [AllowAny]
else:
permission_classes = [IsAdminUser]
return [permission() for permission in permission_classes]
class UserData(APIView):
"""Get authenticated user's information: data related to models User and Profile"""
permission_classes = [IsAuthenticated]
def get(self, request):
user = request.user
user_serialized = UserSerializer(user)
profile_serialized = ProfileSerializer(user.profile)
user_info = {}
user_info.update(user_serialized.data)
user_info.update(profile_serialized.data)
return JsonResponse(user_info)
序列化器:
class ItemSerializer(serializers.ModelSerializer):
class Meta:
model = Item
fields = '__all__'
depth = 1
class ItemInstanceSerializer(serializers.ModelSerializer):
item = ItemSerializer()
class Meta:
model = ItemInstance
fields = ['item']
depth = 2
class ProfileSerializer(serializers.ModelSerializer):
items = ItemInstanceSerializer(source='iteminstance_set', many=True)
class Meta:
model = Profile
fields = ['address', 'birth_date', 'items']
型号:
class Item(models.Model):
...
SINGLE_DAY = timedelta(days=1)
WEEK = timedelta(weeks=1)
MONTH = timedelta(weeks=4)
YEAR = timedelta(weeks=52)
DURATION_CHOICES = [
(SINGLE_DAY, 'Single-day'),
(WEEK, 'Week'),
(MONTH, 'Month'),
(YEAR, 'Year'),
]
duration = models.DurationField(
choices=DURATION_CHOICES,
)
...
class ItemInstance(models.Model):
...
item = models.ForeignKey(
Item,
on_delete=models.CASCADE,
)
...
问题出在JSONResponse
中使用的UserData
。它将使用Django的序列化而不是DRF的序列化。请改用rest_framework.response.Response
。您可以从字面上进行更改,它应该可以工作。您也可以从item = ItemSerializer()
中删除ItemInstanceSerializer
行,因为ItemSerializer
并没有做任何特别的事情。 DRF的默认序列化器字段很好。它们在此处由ModelSerializer
隐式创建。
序列化不同的原因是serializer.data并不总是返回摘要值(完全呈现)。当您将该结构提供给JSONResponse时,它将使用非JSON友好基元的值来做自己的事情,而Response则以不同的方式来做。根据文档serializer.data
should only return primitive types,但对于timedelta
似乎并非如此。奇特的。