
DRF 的 HyperLinkedRelatedField 非常好用,但请求 Json 格式的数据的时候,还要在根据返回的 url 字段再请求一遍,所以有了个想根据请求头确定返回数据类型的想法
class BaseSerializer(serializers.HyperlinkedModelSerializer): def __new__(cls, *args, **kwargs): media_field = kwargs["context"]["request"].accepted_media_type if hasattr(cls, "related_fields"): for name, fields in cls.related_fields.items(): if "text" in media_field: field = fields.get("text", None) elif "json" in media_field: field = fields.get("json", None) elif "yaml" in media_field: field = fields.get("yaml", None) else: log.error(f"{name} not found any type field") continue cls._declared_fields[name] = field cls.Meta.fields += (name,) return super().__new__(cls, *args, **kwargs) 根据请求头里包含的 accepted_media_type 来判断
使用方法
class PermissionSerializer(BaseSerializer): url = serializers.HyperlinkedIdentityField( view_name='permission-detail', lookup_field="codename", # lookup_url_kwarg="codename", ) name = serializers.CharField(max_length=255) codename = serializers.CharField(max_length=100) content_type = serializers.SlugRelatedField( read_Only=True, slug_field="app_label" ) related_fields = dict( user_set=dict( text=serializers.HyperlinkedRelatedField( view_name='user-detail', many=True, queryset=User.objects.get_queryset(), lookup_field="username", required=False, ), json=serializers.StringRelatedField(many=True), yaml=serializers.StringRelatedField(many=True), ), group_set=dict( text=serializers.HyperlinkedRelatedField( view_name='group-detail', many=True, queryset=Group.objects.get_queryset(), lookup_field="name", required=False, ), json=serializers.StringRelatedField(many=True), yaml=serializers.StringRelatedField(many=True), ), ) class Meta: model = Permission fields = ( 'name', 'codename', 'content_type', 'url' ) 测试可行,还有其他好用的方法吗?
或者说我这个方法符合 REST 的风格吗?