我正在使用django-rest-swagger来生成api doc。我想向不同的用户返回不同的模型部分。因此,我使用get_serializer_class()
函数通过检查网址上的kwargs['pk']
为不同用户使用不同的序列化程序。
urls.py
是:
url(r'^api/users/$', views.UserEnum.as_view()),
url(r'^api/users/(?P<pk>[0-9]+)/$', views.UserDetail.as_view()),
我使用的观点是:
#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)
我使用的序列化程序类是:
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', )
...
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)
以上两个网址成功运行没有问题。 (或者任何人都可以告诉我基于url参数为不同用户返回不同字段的正确方法?)但是当我为生成api文档键入http://127.0.0.1:8000/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
,我会得到更多详细信息的错误提示:
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'
答案 0 :(得分:0)
尝试强奸访问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
来源https://github.com/marcgibbons/django-rest-swagger/issues/194