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

Sup*_*ngo 8 python django django-rest-framework

我的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'),
Run Code Online (Sandbox Code Playgroud)

注意它有两个字段:user_pkuid.URL看起来像: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)
Run Code Online (Sandbox Code Playgroud)

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

django.core.exceptions.ImproperlyConfigured:无法使用视图名称"user-device-detail"解析超链接关系的URL.您可能未能在API中包含相关模型,或者未lookup_field在此字段上错误地配置属性.

当URL包含两个或更多URL模板项时,如何使用HyperlinkedIdentityField(或任何Hyperlink*Field)?(查询字段)?

Cli*_*Sun 7

我不确定你是否已经解决了这个问题,但这可能对有这个问题的其他人有用.除了重写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)
Run Code Online (Sandbox Code Playgroud)

这应该工作,在你的情况下你会这样称呼它:

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

<model_field_1><model_field_2>是示范田,大概"身份证"和你的情况为"uid".

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