I am using django-rest-swagger for api doc generation. I would like to return different user the different part of models. So I used the get_serializer_class()
function to use different serializer for different users by checking the kwargs['pk']
on the url.
我正在使用django-rest-swagger来生成api doc。我想向不同的用户返回不同的模型部分。所以我使用get_serializer_class()函数通过检查url上的kwargs ['pk']为不同的用户使用不同的序列化器。
The urls.py
is:
urls.py是:
url(r'^api/users/$', views.UserEnum.as_view()),
url(r'^api/users/(?P<pk>[0-9]+)/$', views.UserDetail.as_view()),
The view that I am using is:
我使用的观点是:
#List all the users or create a new user
class UserEnum(generics.ListCreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = (IsAuthenticated, IsAdminUser,)
class UserDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = User.objects.all()
#serializer_class = UserSerializer #TODO: Problem with Swagger
permission_classes = (IsAuthenticated, IsOwnerAdminOrReadOnly,)
def get_serializer_class(self):
#swagger crash here.
user_id = int(self.kwargs['pk'])
if self.request.user.id == user_id or self.request.user.is_superuser:
serializer_class = UserSerializer
else:
serializer_class = UserProfileSerializer
return serializer_class
def get_object(self, *args, **kwargs):
user_id = int(self.kwargs['pk'])
if self.request.user.id == user_id or self.request.user.is_superuser:
return User.objects.get(id=user_id)
else:
return UserProfile.objects.get(user=user_id)
The serializer classes I am using are:
我使用的序列化程序类是:
class UserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = UserProfile
fields = ('photo', 'description', 'birthday', 'credit',)
class UserSerializer(serializers.ModelSerializer):
profile = UserProfileSerializer()
class Meta:
model = User
fields = ('id', 'last_login', 'username', 'email', 'date_joined', 'profile', )
...
The UserProfile
is:
UserProfile是:
class UserProfile(models.Model):
user = models.OneToOneField(User, primary_key=True, related_name="profile")
photo = models.ImageField(upload_to='user_photo', null=True, blank=True)
description = models.TextField(blank=True)
birthday = models.DateTimeField(blank=True)
credit = models.PositiveIntegerField()
def __unicode__(self):
return u'%s' % (self.user.username)
The above two urls work successfully without problems. (Or anyone can tell me The right way of returning different fields for different users based on the url parameters? ) But when I type the http://127.0.0.1:8000/api/
for generate api docs, it return the below error:
以上两个网址成功运行没有问题。 (或者任何人都可以告诉我基于url参数为不同用户返回不同字段的正确方法?)但是当我输入http://127.0.0.1:8000/api/生成api文档时,它会返回以下错误:
Unable to read api 'users' from path http://127.0.0.1:8000/api/api-docs/api/users (server returned Internal Server Error)
无法从路径http://127.0.0.1:8000/api/api-docs/api/users读取api'用户'(服务器返回内部服务器错误)
So I test the http://127.0.0.1:8000/api/api-docs/api/users
alone, and I get the error tips with more details:
所以我单独测试了http://127.0.0.1:8000/api/api-docs/api/users,我得到了更多细节的错误提示:
Environment:
Request Method: GET
Request URL: http://127.0.0.1:8000/api/api-docs/api/users
Django Version: 1.6.5
Python Version: 2.7.8
Installed Applications:
('django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'south',
'rest_framework',
'rest_framework_swagger',
'django_extensions',
'***')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware')
Traceback:
File "/Users/Scofield/anaconda/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
112. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/Scofield/anaconda/lib/python2.7/site-packages/django/views/decorators/csrf.py" in wrapped_view
57. return view_func(*args, **kwargs)
File "/Users/Scofield/anaconda/lib/python2.7/site-packages/django/views/generic/base.py" in view
69. return self.dispatch(request, *args, **kwargs)
File "/Users/Scofield/anaconda/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
407. response = self.handle_exception(exc)
File "/Users/Scofield/anaconda/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
404. response = handler(request, *args, **kwargs)
File "/Users/Scofield/anaconda/lib/python2.7/site-packages/rest_framework_swagger/views.py" in get
119. 'apis': generator.generate(apis),
File "/Users/Scofield/anaconda/lib/python2.7/site-packages/rest_framework_swagger/docgenerator.py" in generate
32. 'operations': self.get_operations(api, apis),
File "/Users/Scofield/anaconda/lib/python2.7/site-packages/rest_framework_swagger/docgenerator.py" in get_operations
68. serializer = self._get_method_serializer(method_introspector)
File "/Users/Scofield/anaconda/lib/python2.7/site-packages/rest_framework_swagger/docgenerator.py" in _get_method_serializer
165. serializer = method_inspector.get_response_serializer_class()
File "/Users/Scofield/anaconda/lib/python2.7/site-packages/rest_framework_swagger/introspectors.py" in get_response_serializer_class
203. serializer = self.get_serializer_class()
File "/Users/Scofield/anaconda/lib/python2.7/site-packages/rest_framework_swagger/introspectors.py" in get_serializer_class
196. serializer = self.ask_for_serializer_class()
File "/Users/Scofield/anaconda/lib/python2.7/site-packages/rest_framework_swagger/introspectors.py" in ask_for_serializer_class
179. return view.get_serializer_class()
File "/Users/Scofield/Dropbox/My Projects/Angels&Demons/src/doWishSites/doWishCore/views.py" in get_serializer_class
27. user_id = int(self.kwargs['pk'])
Exception Type: KeyError at /api/api-docs/api/users
Exception Value: 'pk'
1 个解决方案
#1
0
Try raping your code that accesses self.kwargs['pk']
with a try and except block
尝试强制使用try和except块访问self.kwargs ['pk']的代码
def get_serializer_class(self):
# swagger crash here.
try:
user_id = int(self.kwargs['pk'])
except Exception as e:
print(e)
if self.request.user.id == user_id or self.request.user.is_superuser:
serializer_class = UserSerializer
else:
serializer_class = UserProfileSerializer
return serializer_class
Source https://github.com/marcgibbons/django-rest-swagger/issues/194
来源https://github.com/marcgibbons/django-rest-swagger/issues/194
#1
0
Try raping your code that accesses self.kwargs['pk']
with a try and except block
尝试强制使用try和except块访问self.kwargs ['pk']的代码
def get_serializer_class(self):
# swagger crash here.
try:
user_id = int(self.kwargs['pk'])
except Exception as e:
print(e)
if self.request.user.id == user_id or self.request.user.is_superuser:
serializer_class = UserSerializer
else:
serializer_class = UserProfileSerializer
return serializer_class
Source https://github.com/marcgibbons/django-rest-swagger/issues/194
来源https://github.com/marcgibbons/django-rest-swagger/issues/194