【发布时间】:2016-05-12 17:58:47
【问题描述】:
我正在为项目编写一个 REST API,并且菜单端点正在返回一个 JSON,其中包含项目组、项目中的项目以及用户可以添加到项目中的任何额外内容。
serializers.py
====================
class ItemExtraSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = ItemExtra
fields = ('id', 'name', 'price')
class ItemSerializer(serializers.HyperlinkedModelSerializer):
extras = ItemExtraSerializer(many=True, read_only=True)
class Meta:
model = Item
fields = ('id', 'url', 'name', 'description', 'image', 'code', 'price', 'extras')
class ItemGroupSerializer(serializers.HyperlinkedModelSerializer):
items = ItemSerializer(many=True, read_only=True)
class Meta:
model = ItemGroup
fields = ('id', 'url', 'name', 'items')
views.py
=========================
class MenuView(ListAPIView):
serializer_class = ItemGroupSerializer
def get_queryset(self):
"""
Return the items inside their groups for search query
Filtering is one Group name and Item name
:return:
"""
queryset = ItemGroup.objects.all()
search_terms = self.request.query_params.get('q', None)
if search_terms:
queryset = Item.objects.search(search_terms)
return queryset
tests.py
========================
class ItemTestCases(APITestCase):
def setUp(self):
self.sandwich_group, created = ItemGroup.objects.get_or_create(name='Sandwiches')
self.meal_group, created = ItemGroup.objects.get_or_create(name='Meals')
self.shawarma_sandwich, created = Item.objects.get_or_create(name='Shawarma Sandwich',
description='Meat Shawarma Sandwich',
price=1.250,
code='SW-01',
group=self.sandwich_group)
self.burger_sandwich, created = Item.objects.get_or_create(name='Cheese Burger',
description='Single cheese burger Sandwich',
price=1.000,
code='SW-02',
group=self.sandwich_group)
self.burger_sandwich_extra, created = ItemExtra.objects.get_or_create(name='Extra cheese',
price=0.100,
item=self.burger_sandwich)
self.sharawma_meal, created = Item.objects.get_or_create(name='Shawarma Meal',
description='Shawarma Sandwich with fries and drink',
price=2.000,
code='ME-01',
group=self.meal_group)
self.burger_meal, created = Item.objects.get_or_create(name='Burger Meal',
description='Single cheese burger Sandwich',
price=2.250,
code='ME-02',
group=self.meal_group)
self.cheese_meal_extra, created = ItemExtra.objects.get_or_create(name='Extra cheese',
price=0.100,
item=self.burger_meal)
self.factory = APIRequestFactory()
def test_menu_GET_request(self):
item_list = reverse('menu')
response = self.client.get(item_list)
self.assertEqual(response.status_code, status.HTTP_200_OK)
groups = ItemGroup.objects.all()
expected = ItemGroupSerializer(groups)
self.assertContains(response, expected.data)
测试的输出是:
AssertionError:HyperlinkedIdentityField 需要序列化程序上下文中的请求。实例化序列化器时添加context={'request': request}。
如何将 serlizer 呈现为 JSON,以便与 API 端点 JSON 进行比较?
更新 1: 我想通了,但我认为有一个更清洁的解决方案
我已经创建了辅助函数
def render_many_serializer_as_json(serializer, request, instance):
serializer_data = serializer(instance=instance, many=True, context={'request': request}).data
return JSONRenderer().render(serializer_data)
然后重写我的测试
def test_menu_GET_request(self):
item_list = reverse('menu')
request = self.factory.get(item_list, format='json')
response = self.client.get(item_list)
groups = ItemGroup.objects.all()
expected = render_many_serializer_as_json(ItemGroupSerializer, request, groups)
self.assertEqual(response.content, expected)
【问题讨论】:
标签: django django-rest-framework