POST新嵌套对象

时间:2015-07-25 08:09:45

标签: django django-rest-framework drf-nested-routers

我试图实施这个计划:

http://127.0.0.1:8000/api/get_work/

{
    "type": "dns",
    "source_alerts": [
        {
            "source": "alehop.com",
            "alerts": [
                {
                    "dns_server": "8.8.4.4",
                    "ip_addr": "134.211.190.5",
                },
                {
                    "dns_server": "7.7.2.2",
                    "ip_addr": "224.110.70.3",
                }
            ]
        }
    ]
}

然后能够获取嵌套到源中的所有警报:

**来源将是唯一的

http://127.0.0.1:8000/api/set_work/dns/alehop.com/

        "alerts": [
            {
                "dns_server": "8.8.4.4",
                "ip_addr": "134.211.190.5",
            },
            {
                "dns_server": "7.7.2.2",
                "ip_addr": "224.110.70.3",
            }

将单个警报发布到该来源:

        {
            "dns_server": "7.7.2.2",
            "ip_addr": "224.110.70.3",
        }

我的问题是:是否可以使用参数实现路径的列表/创建视图集?

router.register(r'set_work/(?P<type>.+)/(?P<source>.+)', views.SetWorkViewSet)

在这种情况下,如何在视图集中使用该参数以过滤查询集?

提前谢谢你。任何其他方法都会非常受欢迎,我对python / django来说很新。

1 个答案:

答案 0 :(得分:0)

当然可以!

Django REST Framework(DRF)用于模型视图集(我假设您正在使用)实现标准get_objectget_queryset方法。由于您向网址正则表达式添加了其他参数,因此可以通过视图集中的self.kwargs引用它们:

def get_queryset(self):
    qs = super(...).get_queryset()
    return qs.filter(type=self.kwargs['type'], source=self.kwargs['source'])

这将进行过滤,使list起作用。对于create,您可能需要调整序列化程序才能使用url kwargs中的值。有几种方法可以做到这一点:

  1. 将url kwargs添加到实例化时传递给序列化程序的数据

    class MyViewSet(ViewSet):
        def get_serializer(self, *args, **kwargs):
            # add the url kwargs to request data so that serializer will see it
            self.request.data.update(self.kwargs)
            return super(...).get_serializer(*args, **kwargs)
    

    这在技术上应该有用,但对我来说有些骚动所以我不推荐这种方法。

  2. 调整序列化程序中的验证逻辑以添加url参数

    class MySerializer(ModelSerializer):
        class Meta(object):
            model = MyModel
        def to_internal_value(self, data):
            if hasattr(self, 'internal_data') and 'view' in self.context:
                data.update(self.context['view'].kwargs)
            return super(...).to_internal_value(data)
    

    我个人认为这种方法更清晰,即使它将有关视图集的一些信息泄漏给序列化程序。

  3. 请注意,代码未经过测试,因此您需要进行一些测试,但它应该让您入门。