'Django REST Framework; ImproperlyConfigured; Could not resolve URL for hyperlinked relationship
Am trying to use DRF to make an election tracker; getting on what was supposed to be fairly simple ViewSet list and retrieve endpoints;
django.core.exceptions.ImproperlyConfigured: Could not resolve URL for hyperlinked relationship using view name "election-detail". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field.
Model Snippet...
class Election(models.Model):
_id = models.CharField(
name="id", primary_key=True, validators=[election_ids.validate], max_length=32
)
date = ComputedDateField(compute_from="_date") # not relevant
parent = models.ForeignKey(
to="self", on_delete=models.CASCADE, default=None, null=True
)
Serializers
class ElectionSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Election
# Removing the 'url' from below stops the ImproperlyConfigured error on retrieve calls
fields = ["url", "org", "date", "constituency", "parent"]
read_only_fields = ["url"]
depth=1
ViewSet
class ElectionViewSet(viewsets.ReadOnlyModelViewSet):
"""
API endpoint that allows elections to be viewed or edited.
"""
lookup_field = 'id'
lookup_value_regex = '[a-z0-9.\-_]+' # this might be the culprit, see below
queryset = Election.objects.all().order_by("-date")
serializer_class = ElectionSerializer
permission_classes = [permissions.AllowAny]
and relevant urls.py
app_name = "counts"
api_router = routers.DefaultRouter()
api_router.register(r"users", UserViewSet, "users")
api_router.register(r"groups", GroupViewSet, "groups")
api_router.register(r"elections", ElectionViewSet, "elections")
api_router.register(r"candidates", CandidateViewSet, "candidates")
api_router.register(r"stages", StageViewSet, "stages")
# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
path("", TemplateView.as_view(template_name="home.html"), name='home'),
path("about/", TemplateView.as_view(template_name="about.html"), name='about'),
path("api/v1/", include(api_router.urls)),
path("api-auth/", include("rest_framework.urls", namespace="rest_framework")),
]
I think the issue is that the ID's are in a standard format that contains periods, which aren't a standard part of the SlugField type, and my working hunch is that something in the bowels of HyperlinkedModelSerializer is having trouble building the reverse / parent entity urls.
If I remove the "url" from ElectionSerializer.Meta.fields, then the individual 'election-detail' view appears to work fine (i.e. I can get a successful, correct, response on /api/v1/elections/nia.2016-05-05/) but I still can't get a listing going on .../elections/.
My understanding was that ReadOnlyModelViewSet would look after the default routing and view generation for list and retrieve operations which at this point are the only ones I'm interested in.
Things I have tried:
- Adding Namespaces and Names to the urls in both / and the base urls or the app-level urls
- Changing the model to use a custom 'slug' field as the lookup with
s/\./_/g - Hopefully not whatever you're about to suggest.
Any ideas? (Full codebase here for anyone feeling masochistic.)
Solution 1:[1]
I haven't done Django in while, but I didn't see any URL field in your model. We use to have to define a get_absolute_url to get that. The other fields in the viewset are defined, but not the URL. If it's not provided automatically, that could be your issue. Django will infer the template name and other stuff.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Avezou |
