Django Rest Framework从视图中获取视图详细信息的URI模板

问题描述 投票:0回答:2

我想获取Django视图的URI模板。与Internet Standards URI template中一样,而不是Django url模板标签。例如,以urls.py为例:

from rest_framework.routers import SimpleRouter
router = SimpleRouter()
router.register(r'collections', views.CollectionViewSet)

和view.py与

from restframework import viewsets

class CollectionViewSet(viewsets.ModelViewSet):
    queryset = Collection.objects.all()
    serializer_class = serializers.CollectionSerializer
    lookup_field='name'

def list(self, *args, **kwargs):
    <...code overriding list...>

我想做的是能够从列表函数中像这样获得uri模板:

'http://localhost:8000/api/collections/{name}/'

我已经尝试使用rest框架的'reverse',它是Django'reverse'函数的扩展;像这样:

from rest_framework.reverse import reverse
field=self.lookup_field
url = reverse('collection-detail', args=['temp'], request=request)
url = url.replace('temp', '{' + field + '}')

虽然这真笨拙!有没有更好的办法??谢谢:)

我尝试用谷歌搜索,但所有结果都与url模板标记有关,完全是另外一回事。

python django django-rest-framework uri
2个回答
1
投票

我不知道提供任何开箱即用的解决方案,但是我知道django-extensions中有一个命令,该命令提供了一种打印所有url模式及其参数的方法,您可以从他们的工作方式中寻找解决方案:Code extract for show_urls command

# Basicly they load urls configurations
# ...
urlconf = __import__(getattr(settings, 'ROOT_URLCONF'), {}, {}, [''])
# ...
# then you can have a look on the patterns
print(urlconf.urlpatterns)

很抱歉,如果这看起来太“ hacky”,但也许可以为您提供帮助。


0
投票

所以我还没有找到这个问题的直接答案。但是我想出了一个运行良好的设计pattern。因此,如果其他人有兴趣构建使客户端知道用于查找资源的URL模式的API,则可以尝试这样做。

在您的models.py中,定义一个名为'key_template'的类变量,它只是uri模板的尾部。例如“ {name}”。定义一个名为“ key”的属性,该属性使用当前实例的键值解析此模板。然后在您的视图集“键”上创建查找字段。这需要一些额外的工作,但是很大的收获是,通过这种方式,您还可以轻松处理多属性键。请参阅下面的示例。

型号:

class Process(models.Model):
    major = models.IntegerField()
    minor = models.IntegerField()
    patch = models.IntegerField()
    service = models.ForeignKey(Service, on_delete=models.CASCADE)

    key_template = "{service}-{major}-{minor}-{patch}"

    @property
    def key(self):
        return self.key_template.format(
            service=self.service.value,
            major=self.major,
            minor=self.minor,
            patch=self.patch
            )

观看次数:

class ProcessViewSet(viewsets.ModelViewSet):
    serializer_class = serializers.ProcessSerializer 
    queryset = Process.objects.all()
    lookup_field = 'key'

现在我可以制作一个这样的功能:

from rest_framework.reverse import reverse

def create_template(model, view_name, request):
    reverse_url = reverse(view_name, args=['temp_key'], request=request)
    reverse_url = reverse_url.replace('temp_key', model.key_template)

    return reverse_url

当然,当您从视图调用此视图时,您将能够提供视图名称和模型。

只要您始终使用“键”查找字段,它将始终有效,因为您知道您需要一个参数并且该参数可以是字符串。因此args = ['temp_key']不会有问题(除非出于某种商业原因,'temp_key'在URL根目录中的其他位置)。

这是我使用此功能的示例输出:

{"_links":
    {"self":
        {"href":"http://localhost:8000/api/processes/"},
         "children":{
             "href":"http://localhost:8000/api/processes/{service}-{major}-{minor}-{patch}/",
             "templated":true
             }
         },
       "_embedded": ......
© www.soinside.com 2019 - 2024. All rights reserved.