-1

我正在尝试实施这个方案:

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 很陌生。

4

1 回答 1

0

你当然可以!

模型视图集(我假设您正在使用)的 Django REST Framework (DRF) 实现了标准get_objectget_queryset方法。由于您向 url 正则表达式添加了其他参数,因此您可以通过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)
    

    我个人觉得这种方法更干净,即使它向序列化程序泄露了一些关于视图集的信息。

请注意,代码未经测试,因此您需要进行一些测试,但它应该可以帮助您入门。

于 2015-07-25T14:30:22.530 回答