带有多个查找参数的django-rest-framework HyperlinkedIdentityField

发布于 2021-01-29 17:34:22

我的urlpatterns中有以下URL:

url(r'^user/(?P<user_pk>[0-9]+)/device/(?P<uid>[0-9a-fA-F\-]+)$', views.UserDeviceDetailView.as_view(), name='user-device-detail'),

请注意,它具有两个字段:user_pkuid。该网址看起来像:https://example.com/user/410/device/c7bda191-f485-4531-a2a7-37e18c2a252c

在此模型的详细视图中,我试图填充一个url字段,其中将包含指向模型的链接。

在序列化器中,我有:

url = serializers.HyperlinkedIdentityField(view_name="user-device-detail", lookup_field='uid', read_only=True)

但是,我认为这是失败的,因为URL有两个字段:

django.core.exceptions.ImproperlyConfigured:无法使用视图名称“用户设备详细信息”解析超链接关系的URL。您可能无法在API中包含相关模型,或者lookup_field在此字段上配置了错误的属性。

当URL有两个或多个URL模板项时,如何使用HyperlinkedIdentityField(或中的任何一个Hyperlink*Field)?(查找字段)?

关注者
0
被浏览
49
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    我不确定您是否已解决此问题,但这对其他遇到此问题的人可能有用。除了重写HyperlinkedIdentityField和自己创建自定义序列化字段之外,您无能为力。这个问题的一个示例在下面的github链接中(以及一些源代码来解决):

    https://github.com/tomchristie/django-rest-
    framework/issues/1024

    在此指定的代码是这样的:

    from rest_framework.relations import HyperlinkedIdentityField
    from rest_framework.reverse import reverse
    
    class ParameterisedHyperlinkedIdentityField(HyperlinkedIdentityField):
        """
        Represents the instance, or a property on the instance, using hyperlinking.
    
        lookup_fields is a tuple of tuples of the form:
            ('model_field', 'url_parameter')
        """
        lookup_fields = (('pk', 'pk'),)
    
        def __init__(self, *args, **kwargs):
            self.lookup_fields = kwargs.pop('lookup_fields', self.lookup_fields)
            super(ParameterisedHyperlinkedIdentityField, self).__init__(*args, **kwargs)
    
        def get_url(self, obj, view_name, request, format):
            """
            Given an object, return the URL that hyperlinks to the object.
    
            May raise a `NoReverseMatch` if the `view_name` and `lookup_field`
            attributes are not configured to correctly match the URL conf.
            """
            kwargs = {}
            for model_field, url_param in self.lookup_fields:
                attr = obj
                for field in model_field.split('.'):
                    attr = getattr(attr,field)
                kwargs[url_param] = attr
    
            return reverse(view_name, kwargs=kwargs, request=request, format=format)
    

    这应该可行,在您的情况下,您可以这样称呼它:

    url = ParameterisedHyperlinkedIdentityField(view_name="user-device-detail", lookup_fields=(('<model_field_1>', 'user_pk'), ('<model_field_2>', 'uid')), read_only=True)
    

    模型字段在哪里<model_field_1><model_field_2>在您的情况下可能是“ id”和“ uid”。

    请注意,上述问题是2年前报告的,我不知道它们是否在较新版本的DRF中包含了类似内容(我还没有找到),但是上面的代码对我有用。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看