Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django REST Framework: how to properly use the HyperlinkedModelSerializer url field in unit tests

So I have models Actor and Role and a default REST API using Viewsets and the HyperlinkedModelSerializer.

My goal: a unit test that creates a Role with an associated Actor.

My test code is currently:

def test_post_create_role_for_actor(self):

    # default actor
    actor = ActorFactory() 

    # inherits HyperlinkedModelSerializer
    actor_serialized = ActorSerializer(actor) 

    postdata = {
        'role': 'mydummyrole',
        'actor': actor_serialized.data['url']
    }

    ret = self.client.post(self.url, json.dumps(postdata), content_type='application/json')

    self.assertEqual(ret.status_code, 201)
    self.assertTrue(Role.objects.filter(role='mydummyrole', actor_id=actor.id).exists())

Now this looks very ugly to me, especially the serialization to retrieve the generated url field. In fact, I get a deprecation warning:

DeprecationWarning: Using HyperlinkedIdentityField without including the request in the serializer context is deprecated. Add context={'request': request} when instantiating the serializer.

But the "url" field as generated by the serializer seems unrelated to any request. What is the proper way to fetch this field? I feel that I'm missing a concept here. Or two.

TIA!

like image 432
Willem Avatar asked Dec 16 '13 15:12

Willem


People also ask

What is the difference between ModelSerializer and HyperlinkedModelSerializer?

The HyperlinkedModelSerializer class is similar to the ModelSerializer class except that it uses hyperlinks to represent relationships, rather than primary keys. By default the serializer will include a url field instead of a primary key field.

What is ViewSet in Django REST framework?

A ViewSet class is simply a type of class-based View, that does not provide any method handlers such as . get() or . post() , and instead provides actions such as . list() and . create() .

Do we need Serializers in Django REST framework?

Serializers in Django REST Framework are responsible for converting objects into data types understandable by javascript and front-end frameworks. Serializers also provide deserialization, allowing parsed data to be converted back into complex types, after first validating the incoming data.


1 Answers

In preperation of the unit test, I would first insert the actor:

actor = ActorFactory() 
actor.save()

Then use Django's reverse method to get the url by using the actor's id, or whatever field you use as identifier in the url:

url = reverse('my_api.actor_resource', args={'id': actor.id})

How to reverse the url depends on how you've set up your resource, but it should be possible.

like image 72
gitaarik Avatar answered Oct 26 '22 19:10

gitaarik