Skip to main content
 首页 » 编程设计

python之Django REST 框架;使用 'groups' 字段序列化用户模型时出现问题

2025年01月19日28rubylouvre

我正在尝试将 REST 框架添加到我现有的项目中。但是,每当我将 'groups' 添加到我的 UserSerializer 类中的 fields 时,我都会得到此回溯:

Environment: 
 
 
Request Method: GET 
Request URL: http://127.0.0.1:8000/api/users/ 
 
Django Version: 1.10.7 
Python Version: 3.6.3 
Installed Applications: 
['django.contrib.auth', 
 'django.contrib.contenttypes', 
 'django.contrib.sessions', 
 'django.contrib.sites', 
 'django.contrib.messages', 
 'django.contrib.staticfiles', 
 'django.contrib.admin', 
 'crispy_forms', 
 'allauth', 
 'allauth.account', 
 'allauth.socialaccount', 
 'blended_learning_portal.users.apps.UsersConfig', 
 'blended_learning_portal.taskapp.celery.CeleryConfig', 
 'blended_learning_portal.unit.apps.UnitConfig', 
 'blended_learning_portal.data.apps.DataConfig', 
 'debug_toolbar', 
 'django_extensions', 
 'graphos', 
 'ckeditor', 
 'ckeditor_uploader', 
 'webpack_loader', 
 'rest_framework'] 
Installed Middleware: 
['django.middleware.security.SecurityMiddleware', 
 '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', 
 'django.middleware.locale.LocaleMiddleware', 
 'debug_toolbar.middleware.DebugToolbarMiddleware'] 
 
 
 
Traceback: 
 
File "/home/michael/blportal/lib/python3.6/site-packages/rest_framework/relations.py" in to_representation 
  378.             url = self.get_url(value, self.view_name, request, format) 
 
File "/home/michael/blportal/lib/python3.6/site-packages/rest_framework/relations.py" in get_url 
  316.         return self.reverse(view_name, kwargs=kwargs, request=request, format=format) 
 
File "/home/michael/blportal/lib/python3.6/site-packages/rest_framework/reverse.py" in reverse 
  50.         url = _reverse(viewname, args, kwargs, request, format, **extra) 
 
File "/home/michael/blportal/lib/python3.6/site-packages/rest_framework/reverse.py" in _reverse 
  63.     url = django_reverse(viewname, args=args, kwargs=kwargs, **extra) 
 
File "/home/michael/blportal/lib/python3.6/site-packages/django/urls/base.py" in reverse 
  91.     return force_text(iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))) 
 
File "/home/michael/blportal/lib/python3.6/site-packages/django/urls/resolvers.py" in _reverse_with_prefix 
  392.             (lookup_view_s, args, kwargs, len(patterns), patterns) 
 
During handling of the above exception (Reverse for 'group-detail' with arguments '()' and keyword arguments '{'pk': 2}' not found. 0 pattern(s) tried: []), another exception occurred: 
 
File "/home/michael/blportal/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner 
  42.             response = get_response(request) 
 
File "/home/michael/blportal/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response 
  187.                 response = self.process_exception_by_middleware(e, request) 
 
File "/home/michael/blportal/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response 
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs) 
 
File "/home/michael/blportal/lib/python3.6/site-packages/django/views/decorators/csrf.py" in wrapped_view 
  58.         return view_func(*args, **kwargs) 
 
File "/home/michael/blportal/lib/python3.6/site-packages/rest_framework/viewsets.py" in view 
  90.             return self.dispatch(request, *args, **kwargs) 
 
File "/home/michael/blportal/lib/python3.6/site-packages/rest_framework/views.py" in dispatch 
  489.             response = self.handle_exception(exc) 
 
File "/home/michael/blportal/lib/python3.6/site-packages/rest_framework/views.py" in handle_exception 
  449.             self.raise_uncaught_exception(exc) 
 
File "/home/michael/blportal/lib/python3.6/site-packages/rest_framework/views.py" in dispatch 
  486.             response = handler(request, *args, **kwargs) 
 
File "/home/michael/blportal/lib/python3.6/site-packages/rest_framework/mixins.py" in list 
  48.         return Response(serializer.data) 
 
File "/home/michael/blportal/lib/python3.6/site-packages/rest_framework/serializers.py" in data 
  738.         ret = super(ListSerializer, self).data 
 
File "/home/michael/blportal/lib/python3.6/site-packages/rest_framework/serializers.py" in data 
  262.                 self._data = self.to_representation(self.instance) 
 
File "/home/michael/blportal/lib/python3.6/site-packages/rest_framework/serializers.py" in to_representation 
  656.             self.child.to_representation(item) for item in iterable 
 
File "/home/michael/blportal/lib/python3.6/site-packages/rest_framework/serializers.py" in <listcomp> 
  656.             self.child.to_representation(item) for item in iterable 
 
File "/home/michael/blportal/lib/python3.6/site-packages/rest_framework/serializers.py" in to_representation 
  500.                 ret[field.field_name] = field.to_representation(attribute) 
 
File "/home/michael/blportal/lib/python3.6/site-packages/rest_framework/relations.py" in to_representation 
  520.             for value in iterable 
 
File "/home/michael/blportal/lib/python3.6/site-packages/rest_framework/relations.py" in <listcomp> 
  520.             for value in iterable 
 
File "/home/michael/blportal/lib/python3.6/site-packages/rest_framework/relations.py" in to_representation 
  393.             raise ImproperlyConfigured(msg % self.view_name) 
 
Exception Type: ImproperlyConfigured at /api/users/ 
Exception Value: Could not resolve URL for hyperlinked relationship using view name "group-detail". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field. 

错误似乎来自 UserSerializer,而不是 GroupSerializer。它显然不知道在哪里寻找 group-detail(因为我在命名空间 api_v1 中有它。但是我不确定如何指定它。

api/views.py:

from django.contrib.auth.models import Group 
from rest_framework import viewsets 
from .serializers import UserSerializer, GroupSerializer 
 
# We're using a modified User model 
try: 
    from django.contrib.auth import get_user_model 
except ImportError:  # Django < 1.5 
    from django.contrib.auth.models import User 
else: 
    User = get_user_model() 
 
 
class UserViewSet(viewsets.ModelViewSet): 
    """ 
    API endpoint that allows users to be viewed or edited. 
    """ 
    queryset = User.objects.all() 
    serializer_class = UserSerializer 
 
 
class GroupViewSet(viewsets.ModelViewSet): 
    """ 
    API endpoint that allows users to be viewed or edited. 
    """ 
    queryset = Group.objects.all() 
    serializer_class = GroupSerializer 

api/serializers.py:

from django.contrib.auth.models import Group 
from rest_framework import serializers 
 
 
try: 
    from django.contrib.auth import get_user_model 
except ImportError:  # Django < 1.5 
    from django.contrib.auth.models import User 
else: 
    User = get_user_model() 
 
 
class UserSerializer(serializers.HyperlinkedModelSerializer): 
    class Meta: 
        extra_kwargs = {'url': {'view_name': 'api_v1:user-detail'}} 
        model = User 
        fields = ('url', 'username', 'email', 'groups') 
 
 
class GroupSerializer(serializers.HyperlinkedModelSerializer): 
    class Meta: 
        extra_kwargs = {'url': {'view_name': 'api_v1:group-detail'}} 
        model = Group 
        lookup_field = 'id' 
        fields = ('url', 'id', 'name') 

api/urls.py:

from django.conf.urls import url, include 
from rest_framework import routers 
from . import views 
 
router = routers.DefaultRouter() 
router.register(r'users', views.UserViewSet) 
router.register(r'groups', views.GroupViewSet) 
 
urlpatterns = [ 
    url(r'^', include(router.urls)), 
] 

我希望这只是告诉 Django 在哪里寻找 group-detail 的问题。任何帮助将不胜感激,这让我发疯。

请您参考如下方法:

我想我忽略了您可以为每个字段添加一个 kwarg samespace。我有点傻。无论如何,在我的 serializers.py 中更改它是解决方案:

    extra_kwargs = { 
        'url': {'view_name': 'api_v1:user-detail'}, 
 
        # Added this line: 
        'groups': {'view_name': 'api_v1:group-detail'}, 
    } 

顺便说一下,这是必要的,因为 rest_framework.routers.DefaultRouter 根本不处理命名空间。参见 this issue在 Git 上。