You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DRF中HyperlinkedModelSerializer指定外键返回URL/ID及报错解决

Fix: Mix Hyperlinked and Primary Key Fields in Django REST Framework Serializer

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

  • HyperlinkedRelatedField tells DRF to serialize the foreign key as a URL pointing to the related object's detail view (which exists for Location and Category).
  • PrimaryKeyRelatedField skips the URL lookup and just returns the foreign key's ID, which is exactly what you want for Unit since 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:54:19