我想获取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模板标记有关,完全是另外一回事。
我不知道提供任何开箱即用的解决方案,但是我知道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”,但也许可以为您提供帮助。
所以我还没有找到这个问题的直接答案。但是我想出了一个运行良好的设计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": ......