V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
firejoke
V2EX  ?  Django

关于如何根据 Accept 的 media_type 返回不同类型序列化数据的想法

  •  
  •   firejoke · 2021-11-19 18:04:57 +08:00 · 1573 次点击
    这是一个创建于 900 天前的主题,其中的信息可能已经有所发展或是发生改变。

    腾讯云最新优惠活动来了:云产品限时1折,云服务器低至88元/年 ,点击这里立即抢购:9i0i.cn/qcloud,更有2860元代金券免费领取,付款直接抵现金用,点击这里立即领取:9i0i.cn/qcloudquan

    (福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

    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 的风格吗?

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   6272 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 01:50 · PVG 09:50 · LAX 18:50 · JFK 21:50
    Developed with CodeLauncher
    ? Do have faith in what you're doing.


    http://www.vxiaotou.com