在未开启版本控制前我做了如下的配置
# url.py
path('media/<path:path>', serve, {'document_root': MEDIA_ROOT}, name='media'),
# serializers
class BannerSerializers(serializers.ModelSerializer): # 序列化banner图
picture = serializers.HyperlinkedRelatedField(view_name='media',
read_only=True,
lookup_field="name", # 获取字段存储的相对地址
lookup_url_kwarg="path" # 对应待生成url上的参数,
)
访问http://127.0.0.1:8000/api/v1/index/banner/
可以完成对相应的url的生成
然后我打开了版本控制 便报了错
# 版本控制类
'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
'DEFAULT_VERSION': "v1",
'ALLOWED_VERSIONS': ['v1', ],
'VERSION_PARAM': 'version',
报错代码
Traceback (most recent call last):
File "G:\python3.7.0\lib\site-packages\rest_framework\reverse.py", line 42, in reverse
url = scheme.reverse(viewname, args, kwargs, request, format, **extra)
File "G:\python3.7.0\lib\site-packages\rest_framework\versioning.py", line 89, in reverse
viewname, args, kwargs, request, format, **extra
File "G:\python3.7.0\lib\site-packages\rest_framework\versioning.py", line 25, in reverse
return _reverse(viewname, args, kwargs, request, format, **extra)
File "G:\python3.7.0\lib\site-packages\rest_framework\reverse.py", line 63, in _reverse
url = django_reverse(viewname, args=args, kwargs=kwargs, **extra)
File "G:\python3.7.0\lib\site-packages\django\urls\base.py", line 90, in reverse
return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
File "G:\python3.7.0\lib\site-packages\django\urls\resolvers.py", line 660, in _reverse_with_prefix
raise NoReverseMatch(msg)
django.urls.exceptions.NoReverseMatch: Reverse for 'media' with keyword arguments '{'path': 'pic_move/Cache_-6cc421832464fb12._BKSQTY2.jpg', 'version': 'v1'}' not found. 1 pattern(s) tried: ['media/(?P<path>.+)$']
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "G:\python3.7.0\lib\site-packages\rest_framework\relations.py", line 394, in to_representation
url = self.get_url(value, self.view_name, request, format)
File "G:\python3.7.0\lib\site-packages\rest_framework\relations.py", line 332, in get_url
return self.reverse(view_name, kwargs=kwargs, request=request, format=format)
File "G:\python3.7.0\lib\site-packages\rest_framework\reverse.py", line 47, in reverse
url = _reverse(viewname, args, kwargs, request, format, **extra)
File "G:\python3.7.0\lib\site-packages\rest_framework\reverse.py", line 63, in _reverse
url = django_reverse(viewname, args=args, kwargs=kwargs, **extra)
File "G:\python3.7.0\lib\site-packages\django\urls\base.py", line 90, in reverse
return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
File "G:\python3.7.0\lib\site-packages\django\urls\resolvers.py", line 660, in _reverse_with_prefix
raise NoReverseMatch(msg)
django.urls.exceptions.NoReverseMatch: Reverse for 'media' with keyword arguments '{'path': 'pic_move/Cache_-6cc421832464fb12._BKSQTY2.jpg', 'version': 'v1'}' not found. 1 pattern(s) tried: ['media/(?P<path>.+)$']
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "G:\python3.7.0\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "G:\python3.7.0\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "G:\python3.7.0\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "G:\python3.7.0\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "G:\python3.7.0\lib\site-packages\django\views\generic\base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "G:\python3.7.0\lib\site-packages\rest_framework\views.py", line 504, in dispatch
response = self.handle_exception(exc)
File "G:\python3.7.0\lib\site-packages\rest_framework\views.py", line 465, in handle_exception
self.raise_uncaught_exception(exc)
File "G:\python3.7.0\lib\site-packages\rest_framework\views.py", line 476, in raise_uncaught_exception
raise exc
File "G:\python3.7.0\lib\site-packages\rest_framework\views.py", line 501, in dispatch
response = handler(request, *args, **kwargs)
File "E:\python\rewrite_first\index\views.py", line 26, in get
return Response(ser_banner.data)
File "G:\python3.7.0\lib\site-packages\rest_framework\serializers.py", line 760, in data
ret = super().data
File "G:\python3.7.0\lib\site-packages\rest_framework\serializers.py", line 260, in data
self._data = self.to_representation(self.instance)
File "G:\python3.7.0\lib\site-packages\rest_framework\serializers.py", line 678, in to_representation
self.child.to_representation(item) for item in iterable
File "G:\python3.7.0\lib\site-packages\rest_framework\serializers.py", line 678, in <listcomp>
self.child.to_representation(item) for item in iterable
File "G:\python3.7.0\lib\site-packages\rest_framework\serializers.py", line 529, in to_representation
ret[field.field_name] = field.to_representation(attribute)
File "G:\python3.7.0\lib\site-packages\rest_framework\relations.py", line 409, in to_representation
raise ImproperlyConfigured(msg % self.view_name)
django.core.exceptions.ImproperlyConfigured: Could not resolve URL for hyperlinked relationship using view name "media". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field.
[26/Feb/2020 23:53:22] "GET /api/v1/index/banner/ HTTP/1.1" 500 192466
通过报错的代码我大致的清楚了是怎么回事 media只能接收一个参数
而我再访问http://127.0.0.1:8000/api/v1/index/banner/链接时有多出一个{‘version’: ‘v1’}参数 而对应的media上面只能接收path一个参数因此报错。
对于上述问题我第一开始的想法是在加个参数构成如下的链接api/str:version/media/path:path
这是一种解决的方法,但是我想应该还有别的方法解决它
通过debug我找到了问题具体出在哪了
reverse.py
在图中1处先使用版本控制类内的reverse去生成ur.,但是报了错,少了一个参数槽,所以走到了except内,去使用django自带的reverse去生成url,但是也是也多了一个参数,所以在2处一行加一个del 将传入的version删除即可。
修改后执行结果如下