DRF中HyperlinkedModelSerializer指定外键返回URL/ID及报错解决
Got it, let's tackle this issue! The problem here is that HyperlinkedModelSerializer automatically tries to create hyperlinked fields for all foreign keys, but since you don't have a ViewSet (or corresponding URL route) for the Unit model, it can't resolve the unit-detail view name—hence the error.
Here's how to make location and category return URLs while unit only returns its ID:
Step 1: Explicitly Define Field Types in Your Serializer
Override the default field behavior by explicitly declaring each foreign key field with the type you want. This gives you full control over how each field is serialized.
Update your serializers.py like this:
from rest_framework import serializers from .models import Material, Location, Category, Unit class MaterialSerializer(serializers.HyperlinkedModelSerializer): # For fields that need URLs: use HyperlinkedRelatedField location = serializers.HyperlinkedRelatedField( view_name='location-detail', # Matches the router's basename + "-detail" queryset=Location.objects.all(), allow_null=True # Match your model's null=True setting ) category = serializers.HyperlinkedRelatedField( view_name='category-detail', queryset=Category.objects.all(), allow_null=True ) # For unit: use PrimaryKeyRelatedField to return only the ID unit = serializers.PrimaryKeyRelatedField( queryset=Unit.objects.all(), allow_null=True ) class Meta: model = Material fields = ('id', 'url', 'name', 'location', 'category', 'unit', 'type', 'price',)
Step 2: Verify Your URL Router Configuration
Double-check your urls.py to ensure the category route has a proper basename (this ensures the category-detail view name exists):
# Update this line to include the basename explicitly router.register('category', CategoryViewSet, 'category')
When you register a ViewSet with the router, the third parameter sets the basename, which Django uses to generate view names like {basename}-detail. For your location route, you already have 'location' as the basename, so location-detail works correctly.
Why This Works
HyperlinkedRelatedFieldtells DRF to serialize the foreign key as a URL pointing to the related object's detail view (which exists forLocationandCategory).PrimaryKeyRelatedFieldskips the URL lookup and just returns the foreign key's ID, which is exactly what you want forUnitsince there's no detail view for it.
This setup will resolve the unit-detail error and give you the exact output you need: URLs for location/category, and ID for unit.
内容的提问来源于stack exchange,提问作者Azamat Sultanov

