Reputation: 187
I'm trying to setup the lookup field between two entities, but I can't fix this error.
I've already tried these solutions but none of them worked for me(What am I doing wrong?):
Django Rest Framework, improperly configured lookup field
DRF Could not resolve URL for hyperlinked relationship using view name on PrimaryKeyRelatedField
here's my code Models:
class Category(models.Model):
title = models.CharField(max_length=50, unique=True)
slug = models.SlugField(max_length=80, default='')
def __str__(self):
return self.title
class Option(models.Model):
title = models.CharField(max_length=80)
slug = models.SlugField(max_length=80, unique=True)
description = models.CharField(max_length=250)
price = models.DecimalField(max_digits=7, decimal_places=2)
category = models.ForeignKey(Category, related_name='options', on_delete=models.CASCADE)
photo = models.ImageField(upload_to='options', null=True)
class Meta:
ordering = ['title']
def __str__(self):
return self.title
Serializers:
class CategorySerializer(serializers.HyperlinkedModelSerializer):
options = serializers.HyperlinkedRelatedField(many=True, view_name='option-detail', read_only=True)
class Meta:
model = Category
fields = ('url', 'slug', 'title', 'options')
lookup_field = 'slug'
extra_kwargs = {
'url': {'lookup_field': 'slug'}
}
class OptionSerializer(serializers.HyperlinkedModelSerializer):
category = serializers.ReadOnlyField(source='category.title')
class Meta:
model = Option
fields = ('url', 'slug', 'title', 'description', 'price', 'category')
lookup_field = 'slug'
extra_kwargs = {
'url': {'lookup_field': 'slug'},
'category': {'lookup_field': 'slug'}
}
Views:
class CategoryViewSet(viewsets.ReadOnlyModelViewSet):
"""
Returns the Category list or the requested one
"""
queryset = Category.objects.all()
serializer_class = CategorySerializer
lookup_field = 'slug'
class OptionViewSet(viewsets.ReadOnlyModelViewSet):
"""
Returns the Option list or the requested one
"""
queryset = Option.objects.all()
serializer_class = OptionSerializer
lookup_field = 'slug'
urls:
router = DefaultRouter()
router.register(r'options', views.OptionViewSet)
router.register(r'categories', views.CategoryViewSet)
urlpatterns = [
path('', include(router.urls)),
]
This works for the Option model. When I hit the '[localhost]/options/' url, it correctly lists the options and when hitting '[localhost]/options/some-option-slug' it returns the correct option.
But none of that works for the Category model. Calls to '[localhost]/categories/' retuns "Could not resolve URL for hyperlinked relationship using view name "option-detail". You may have failed to include the related model in your API, or incorrectly configured the lookup_field
attribute on this field.". While calls to '[localhost]/categories/category-slug/' returns 404 Not Found.
My django version is 4.0.1 and my Django Rest Framework version is 3.13.1
EDIT As suggestted by @code-apprendice, here's the output of print('router'): [<URLPattern '^options/$' [name='option-list']>, <URLPattern '^options.(?P[a-z0-9]+)/?$' [name='option-list']>, <URLPattern '^options/(?P[^/.]+)/$' [name='option-detail']>, <URLPattern '^options/(?P[^/.]+).(?P[a-z0-9]+)/?$' [name='option-detail']>, <URLPattern '^categories/$' [name='category-list']>, <URLPattern '^categories.(?P[a-z0-9]+)/?$' [name='category-list']>, <URLPattern '^categories/(?P[^/.]+)/$' [name='category-detail']>, <URLPattern '^categories/(?P[^/.]+).(?P[a-z0-9]+)/?$' [name='category-detail']>, <URLPattern '^$' [name='api-root']>, <URLPattern '^.(?P[a-z0-9]+)/?$' [name='api-root']>]
The DRF correctly generated the views option-list, option-detail, category-list and category-detail
Upvotes: 5
Views: 4471
Reputation: 187
Defining the lookup_field attribute for the options in the CategorySerializer solved the problem.
Here's the CategorySerializer class:
class CategorySerializer(serializers.HyperlinkedModelSerializer):
options = serializers.HyperlinkedRelatedField(
view_name='option-detail',
lookup_field = 'slug',
many=True,
read_only=True)
class Meta:
model = Category
fields = ('url', 'slug', 'title', 'options')
lookup_field = 'slug'
extra_kwargs = {
'url': {'lookup_field': 'slug'}
}
The problem was that the CategorySerializer set an explict options HyperlinkedRelatedField and it's lookup_field needs to be configured too.
Feel free to edit this answer to add a deeper explanation.
Upvotes: 7