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. Addcontext={'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!
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.
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() .
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With