Issue #2414
Updated by amacdona@redhat.com about 8 years ago
`HyperlinkedRelatedField` for detail list views are passed incorrect `view_names`. As an example, this should be the most simple working detail importer serializer possible: <pre><code class="python"> class TestImporterSerializer(ImporterSerializer): # _href is provided by the base class, which is a subclass of `MasterModelSerializer` class Meta: model = TestImporter fields = ImporterSerializer.Meta.fields </code></pre> This creates the following error from Django (viewed from the browsable web API): <pre> ImproperlyConfigured at /api/v3/importers/test/ Could not resolve URL for hyperlinked relationship using view name "testimporter-detail". "importers-detail". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field. Request Method: GET Request URL: http://192.168.121.160:8000/api/v3/importers/test/ Django Version: 1.8.16 Exception Type: ImproperlyConfigured Exception Value: Could not resolve URL for hyperlinked relationship using view name "testimporter-detail". "importers-detail". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field. Exception Location: /usr/lib/python3.5/site-packages/djangorestframework-3.5.3-py3.5.egg/rest_framework/relations.py in to_representation, line 386 Python Executable: /home/vagrant/.virtualenvs/pulp/bin/python Python Version: 3.5.2 Python Path: ['/home/vagrant/devel/pulp/app/pulp/app', '/home/vagrant/.virtualenvs/pulp/lib64/python35.zip', '/home/vagrant/.virtualenvs/pulp/lib64/python3.5', '/home/vagrant/.virtualenvs/pulp/lib64/python3.5/plat-linux', '/home/vagrant/.virtualenvs/pulp/lib64/python3.5/lib-dynload', '/usr/lib64/python3.5', '/usr/lib/python3.5', '/home/vagrant/.virtualenvs/pulp/lib/python3.5/site-packages', '/home/vagrant/devel/devel/pulp-dev', '/home/vagrant/devel/pulp/app', '/usr/lib/python3.5/site-packages/psycopg2-2.6.2-py3.5-linux-x86_64.egg', '/usr/lib/python3.5/site-packages/djangorestframework-3.5.3-py3.5.egg', '/usr/lib/python3.5/site-packages/django_filter-0.15.3-py3.5.egg', '/usr/lib/python3.5/site-packages/django_extensions-1.7.4-py3.5.egg', '/usr/lib/python3.5/site-packages/django_crispy_forms-1.6.1-py3.5.egg', '/usr/lib/python3.5/site-packages/Django-1.8.16-py3.5.egg', '/usr/lib/python3.5/site-packages/coreapi-2.0.9-py3.5.egg', '/usr/lib/python3.5/site-packages/celery-4.0.0-py3.5.egg', '/usr/lib/python3.5/site-packages/uritemplate-3.0.0-py3.5.egg', '/usr/lib/python3.5/site-packages/itypes-1.1.0-py3.5.egg', '/usr/lib/python3.5/site-packages/kombu-4.0.0-py3.5.egg', '/usr/lib/python3.5/site-packages/billiard-3.5.0.2-py3.5.egg', '/usr/lib/python3.5/site-packages/pytz-2016.7-py3.5.egg', '/usr/lib/python3.5/site-packages/amqp-2.1.1-py3.5.egg', '/usr/lib/python3.5/site-packages/vine-1.1.3-py3.5.egg', '/home/vagrant/devel/pulp/plugin', '/home/vagrant/devel/pulp/exceptions', '/home/vagrant/devel/pulp/client_lib', '/home/vagrant/devel/pulp/common', '/home/vagrant/devel/pulp/client_consumer', '/home/vagrant/devel/pulp/devel', '/home/vagrant/devel/pulp/server', '/home/vagrant/devel/pulp/bindings', '/home/vagrant/devel/pulp/client_admin', '/home/vagrant/devel/pulp/streamer', '/usr/lib/python3.5/site-packages/Twisted-16.5.0-py3.5-linux-x86_64.egg', '/home/vagrant/devel/pulp/repoauth', '/home/vagrant/devel/pulp/oid_validation', '/home/vagrant/devel/pulp/tasking', '/usr/lib64/python3.5/site-packages', '/usr/lib/python3.5/site-packages', '/usr/lib/python3.5/site-packages', '/home/vagrant/devel/pulp'] Server time: Thu, 10 Nov 2016 19:16:43 18:59:28 +0000 </pre> This is the traceback from the server: <pre> Traceback (most recent call last): File "/usr/lib/python3.5/site-packages/Django-1.8.16-py3.5.egg/django/core/handlers/base.py", line 132, in get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/usr/lib/python3.5/site-packages/Django-1.8.16-py3.5.egg/django/views/decorators/csrf.py", line 58, in wrapped_view return view_func(*args, **kwargs) File "/usr/lib/python3.5/site-packages/djangorestframework-3.5.3-py3.5.egg/rest_framework/viewsets.py", line 83, in view return self.dispatch(request, *args, **kwargs) File "/usr/lib/python3.5/site-packages/djangorestframework-3.5.3-py3.5.egg/rest_framework/views.py", line 477, in dispatch response = self.handle_exception(exc) File "/usr/lib/python3.5/site-packages/djangorestframework-3.5.3-py3.5.egg/rest_framework/views.py", line 437, in handle_exception self.raise_uncaught_exception(exc) File "/usr/lib/python3.5/site-packages/djangorestframework-3.5.3-py3.5.egg/rest_framework/views.py", line 474, in dispatch response = handler(request, *args, **kwargs) File "/usr/lib/python3.5/site-packages/djangorestframework-3.5.3-py3.5.egg/rest_framework/mixins.py", line 45, in list return self.get_paginated_response(serializer.data) File "/usr/lib/python3.5/site-packages/djangorestframework-3.5.3-py3.5.egg/rest_framework/serializers.py", line 725, in data ret = super(ListSerializer, self).data File "/usr/lib/python3.5/site-packages/djangorestframework-3.5.3-py3.5.egg/rest_framework/serializers.py", line 262, in data self._data = self.to_representation(self.instance) File "/usr/lib/python3.5/site-packages/djangorestframework-3.5.3-py3.5.egg/rest_framework/serializers.py", line 643, in to_representation self.child.to_representation(item) for item in iterable File "/usr/lib/python3.5/site-packages/djangorestframework-3.5.3-py3.5.egg/rest_framework/serializers.py", line 643, in <listcomp> self.child.to_representation(item) for item in iterable File "/home/vagrant/devel/pulp/app/pulp/app/serializers/base.py", line 187, in to_representation ret[field.field_name] = field.to_representation(attribute) File "/usr/lib/python3.5/site-packages/djangorestframework-3.5.3-py3.5.egg/rest_framework/relations.py", line 386, in to_representation raise ImproperlyConfigured(msg % self.view_name) django.core.exceptions.ImproperlyConfigured: Could not resolve URL for hyperlinked relationship using view name "importers-detail". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field. </pre> The problem is that the view_name being passed to the HyperlinedRelatedField is `testimporter-detail`, which does not exist. What should be created is `<master_names>-<detail_name>-detail`, which in this example would be importers-test-detail. There is a workaround, the plugin writer just needs to override `_href` with the correct view_name, but this isn't ideal and should be handled by the base class. <pre><code class="python"> class TestImporterSerializer(ImporterSerializer): _href = serializers.HyperlinkedIdentityField(view_name='importers-test-detail') class Meta: model = TestImporter fields = ImporterSerializer.Meta.fields </code></pre>