2017-09-12 15 views
1

のためのハイパーリンク関係を解決するために失敗し、私はこのテストを持っている:ジャンゴRESTフレームワーク - unittestのクライアントPOST

class AttributeTest(APITestCase): 
def setUp(self): 
    user1 = User.objects.create(pk=1, username='pepa', email='[email protected]', 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> 
+0

シリアライザとモデルに完全なトレースバックと関連コードを追加してください。 [mcve] –

+0

テストクライアントを使用せずにシリアライザを直接テストすることができます。これにより、より詳細なスタックトレースが得られるはずです。 'serializer = AttributeSerializer(data)'と 'serializer.save() 'です。たぶんそれはカスタム 'get_fields'と関係がありますか? –

+0

ねえ。ありがとう。コンテキストには 'view'が必要ないというエラーがあるようですが、結果は同じです。私はシリアライザを直接使うことについての質問を更新しました。 – kotrfa

答えて

0

はちょうどあなたにそれをフォーマットしていない、reversingあなたURL名とURLパラメータとしてc1.pkを渡してみてくださいURL:

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})) 
+0

ねえ、ありがとう。 reverse( 'api:campaign-detail'、kwargs = {'cid':self.c2.cid})) '(代わりに' cid'を使用します。 'pk'キャンペーン) – kotrfa

+0

@kotrfaそれはあなたのために働いてうれしいです。それがあなたを助けたら私の答えを受け入れるようにしてください。 – wencakisa

+0

誤解をおかけして申し訳ありません - それは問題を解決していない、それはちょうど前にハードコード化と同じものを返すだけです – kotrfa

0

なぜか分かりませんが、テストの結果は何とかキャッシュされなければなりませんでした。私はPCを再起動し、まったく同じコミットで動作しました。解決済み。

関連する問題