Django_rest_framwork "TypeError: Link object does not support element assignment"
Project using Django, DRF, swagger.
URL below:
schema_view = get_swagger_view(title='Pastebin API')
urlpatterns = [
url(r'^$', schema_view),
url(r'store', include('store.urls')),
... # other urls using routers.SimplerRouter
]
and store / urls.py:
router = routers.SimpleRouter()
router.register(r'', views.StoreViewSet)
urlpatterns = router.urls
and views.StoreViewSet:
class StoreViewSet(BaseObject, GenericViewSet):
permition_class = ()
@list_route()
def detail(self, request):
return {}
@list_route(url_path='detail/export')
def detail_export(self, request):
return {}
after python manage.py runserver
, visit http://127.0.0.1:8000/#
and typeError occurred:
File "/usr/local/share/.virtualenvs/dev-finance/lib/python2.7/site-packages/rest_framework_swagger/views.py", line 32, in get
schema = generator.get_schema(request=request)
File "/usr/local/share/.virtualenvs/dev-finance/lib/python2.7/site-packages/rest_framework/schemas.py", line 242, in get_schema
links = self.get_links(request)
File "/usr/local/share/.virtualenvs/dev-finance/lib/python2.7/site-packages/rest_framework/schemas.py", line 276, in get_links
insert_into(links, keys, link)
File "/usr/local/share/.virtualenvs/dev-finance/lib/python2.7/site-packages/rest_framework/schemas.py", line 79, in insert_into
target[keys[-1]] = value
TypeError: 'Link' object does not support item assignment
[ERROR] 2017-05-04 15:25:06,936 log_message(basehttp.py:131) "GET / HTTP/1.1" 500 20384
The error message indicates that the object Link
cannot assign a value such as dict.
If I rename the method name from detail_export
to details_export
, everything is fine.
A guessing error occurred when the decor_framework @list_route
decorater passed the url method for the Link object.
why are other methods just fine? how can i solve this?
source to share
This is a bug in DRF . This will probably be fixed in 3.6.4. Now you can:
-
Remove
url_path
fromlist_route
:class StoreViewSet(BaseObject, GenericViewSet): permition_class = () @list_route() def detail(self, request): return {} @list_route() def detail_export(self, request): return {}
-
Or use custom
SchemaView
with customSchemaGenerator
:# api/schema.py for example from rest_framework.permissions import AllowAny from rest_framework.renderers import CoreJSONRenderer from rest_framework.response import Response from rest_framework.schemas import SchemaGenerator from rest_framework.views import APIView from rest_framework_swagger import renderers class CustomSchemaGenerator(SchemaGenerator): def get_keys(self, subpath, method, view): result = super().get_keys(subpath, method, view) # here you can fix your path if result == ['store', 'detail', 'detail_export']: return ['store', 'detail_export'] return result class SwaggerSchemaView(APIView): _ignore_model_permissions = True exclude_from_schema = True permission_classes = [AllowAny] renderer_classes = [ CoreJSONRenderer, renderers.OpenAPIRenderer, renderers.SwaggerUIRenderer ] def get(self, request): generator = CustomSchemaGenerator(title='API') return Response(generator.get_schema(request=request)) # urls.py from django.contrib.auth.decorators import login_required from api.schema import SwaggerSchemaView urlpatterns = [ # ... url(r'^swagger-url/', login_required(SwaggerSchemaView.as_view())) # ... ]
source to share