如何在Django REST的OPTIONS元数据中获取外键关联模型URL
在Django REST框架的OPTIONS元数据中添加ForeignKey关联模型的URL
默认情况下,Django REST框架(DRF)的OPTIONS请求返回的元数据里不会包含关联模型的列表URL,不过我们可以通过自定义元数据类来实现这个需求,具体步骤如下:
1. 自定义元数据类
我们需要继承DRF自带的DefaultMetadata类,重写它的get_field_metadata方法,针对关联字段(比如ForeignKey对应的PrimaryKeyRelatedField)添加choices_url字段:
from rest_framework.metadata import DefaultMetadata from rest_framework.reverse import reverse from rest_framework.relations import PrimaryKeyRelatedField class CustomMetadata(DefaultMetadata): def get_field_metadata(self, field): metadata = super().get_field_metadata(field) # 针对PrimaryKeyRelatedField(对应模型的ForeignKey)处理 if isinstance(field, PrimaryKeyRelatedField): # 获取关联模型的queryset对应的视图名称,默认格式为 "<app_label>-<model_name>-list" view_name = f"{field.queryset.model._meta.app_label}-{field.queryset.model._meta.model_name}-list" try: # 生成完整的URL,request参数用来获取当前的域名和协议 choices_url = reverse(view_name, request=self.request) metadata['choices_url'] = choices_url except: # 如果无法反转URL(比如未配置对应视图),可留空或添加提示 metadata['choices_url'] = None return metadata
2. 在视图中配置自定义元数据类
不管你用的是APIView、GenericAPIView还是ModelViewSet,只需在视图类中指定metadata_class为我们刚才定义的CustomMetadata即可:
from rest_framework.viewsets import ModelViewSet from .models import City, Country from .serializers import CitySerializer, CountrySerializer class CountryViewSet(ModelViewSet): queryset = Country.objects.all() serializer_class = CountrySerializer class CityViewSet(ModelViewSet): queryset = City.objects.all() serializer_class = CitySerializer # 指定自定义元数据类 metadata_class = CustomMetadata
3. 验证效果
启动服务后,向City接口发送OPTIONS请求,你就能看到POST动作的country字段里多出了choices_url字段,格式和你期望的一致:
"actions": { "POST": { "country": { "type": "related", "required": true, "read_only": false, "label": "Country", "choices_url": "http://example.com/api/country/" } } }
注意事项
- 确保关联模型(这里是Country)已经配置了对应的列表视图,并且
reverse能正确匹配到该视图的名称 - 如果你的视图名称不是默认的
<app_label>-<model_name>-list格式,需要调整view_name的生成逻辑,匹配你实际的URL配置
内容的提问来源于stack exchange,提问作者Qho
相关产品推荐
相关产品推荐

