Django REST框架 - 单元测试客户端无法解析POST的超链接关系

时间:2017-09-12 21:07:34

标签: django django-rest-framework

我有这个测试:

class AttributeTest(APITestCase):
def setUp(self):
    user1 = User.objects.create(pk=1, username='pepa', email='ads@asasd.cz', is_active=True, is_staff=True)
    user1.set_password('mypass')
    user1.save()
    self.c1 = Campaign.objects.create(pk=1, owner=user1, project_name='c1')

def test(self):
    campaign_url = 'http://testserver/api/campaigns/{}/'.format(self.c1.pk)
    self.client.login(username='pepa', password='mypass')
    data = {
        "label": "something_here",
        "parent_campaign": campaign_url,
    }
    # campaign clearly exists (created in setUp) and GET retrieve it:
    assert self.client.get(campaign_url).json()['project_name'] == 'c1'
    # I can even try it myself using pdb

    # but this doesn't work - response return 400 Bad Request
    # complaining about the very same hyperlink I can GET above
    response = self.client.post('/api/keys', data, format="json")
    self.assertEqual(response.status_code, status.HTTP_201_CREATED)

但运行时,{'parent_campaign': ['Invalid hyperlink - No URL match.']}失败。

当我尝试使用curl或可浏览的API(在测试环境之外)时,一切都按预期工作。

我的序列化程序对应/api/keys

class AttributeSerializer(serializers.HyperlinkedModelSerializer):
    url = serializers.HyperlinkedIdentityField(
        view_name='api:key-detail')
    parent_campaign = serializers.HyperlinkedRelatedField(
        view_name='api:campaign-detail',
        lookup_field='cid',
        queryset=Campaign.objects.all())

    def _get_user_campaigns(self):
        user = self.context['view'].request.user
        return Campaign.objects.filter(owner=user)

    def get_fields(self, *args, **kwargs):
        fields = super(AttributeSerializer, self).get_fields(*args, **kwargs)
        fields['parent_campaign'].queryset = self._get_user_campaigns()
        return fields

    class Meta:
        model = Key
        fields = ("id", 'url', "label", 'parent_campaign')

直接使用序列化程序:

(Pdb) from api.attribute.serializers import AttributeSerializer
(Pdb) ser = AttributeSerializer(data=data)
(Pdb) ser.is_valid()
True
(Pdb) ser.save()
<Key: Something1 | MAROO | CID: lrvyw93>

2 个答案:

答案 0 :(得分:0)

尝试reversing您的网址名称并将c1.pk作为网址参数传递,而不只是将其格式化为您的网址:

from rest_framework.reverse import reverse

campaign_url_name = 'api:campaign-detail'  # Use URL name instead of raw URL path
response = self.client.get(reverse(campaign_url_name, kwargs={'pk': self.c1.pk}))

答案 1 :(得分:0)

我不知道为什么,但测试结果必须以某种方式缓存。我重新启动了PC,它使用完全相同的提交。解决。