该字段已在序列化程序上声明,但在 django rest 中未包含错误

Posted

技术标签:

【中文标题】该字段已在序列化程序上声明,但在 django rest 中未包含错误【英文标题】:The field was declared on serializer , but has not been included error in django rest 【发布时间】:2017-02-17 03:21:31 【问题描述】:

我在我的 django REST API 中创建了几个序列化程序并遇到了奇怪的问题。当我转到 http://127.0.0.1:8000/api/register/ 网址时,我得到了错误:

环境:

请求方法:GET 请求地址:http://localhost:8000/api/users/

Django 版本:1.10.2 Python 版本:3.5.2 已安装的应用程序: ['django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'api'] 已安装的中间件: ['django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware']

追溯:

文件 "D:\code\active\Python\Django\photo-hub\photo-hub\env\lib\site-packages\django\core\handlers\exception.py" 在内部 39. response = get_response(request)

文件 "D:\code\active\Python\Django\photo-hub\photo-hub\env\lib\site-packages\django\core\handlers\base.py" 在 _legacy_get_response 249. response = self._get_response(request)

文件 "D:\code\active\Python\Django\photo-hub\photo-hub\env\lib\site-packages\django\core\handlers\base.py" 在 _get_response 217. response = self.process_exception_by_middleware(e, request)

文件 "D:\code\active\Python\Django\photo-hub\photo-hub\env\lib\site-packages\django\core\handlers\base.py" 在 _get_response 215. response = response.render()

文件 "D:\code\active\Python\Django\photo-hub\photo-hub\env\lib\site-packages\django\template\response.py" 在渲染中 109. self.content = self.rendered_content

文件 "D:\code\active\Python\Django\photo-hub\photo-hub\env\lib\site-packages\rest_framework\response.py" 在渲染内容中 72. ret = renderer.render(self.data, accepted_media_type, context)

文件 "D:\code\active\Python\Django\photo-hub\photo-hub\env\lib\site-packages\rest_framework\renderers.py" 在渲染中 697. context = self.get_context(数据,accepted_media_type,renderer_context)

文件 "D:\code\active\Python\Django\photo-hub\photo-hub\env\lib\site-packages\rest_framework\renderers.py" 在 get_context 630. raw_data_post_form = self.get_raw_data_form(数据,视图,'POST',请求)

文件 "D:\code\active\Python\Django\photo-hub\photo-hub\env\lib\site-packages\rest_framework\renderers.py" 在 get_raw_data_form 553. content = renderer.render(serializer.data, 接受, 上下文)

文件 "D:\code\active\Python\Django\photo-hub\photo-hub\env\lib\site-packages\rest_framework\serializers.py" 在数据中 508. ret = super(Serializer, self).data

文件 "D:\code\active\Python\Django\photo-hub\photo-hub\env\lib\site-packages\rest_framework\serializers.py" 在数据中 244. self._data = self.get_initial()

文件 "D:\code\active\Python\Django\photo-hub\photo-hub\env\lib\site-packages\rest_framework\serializers.py" 在 get_initial 387. 对于self.fields.values()中的字段

文件 "D:\code\active\Python\Django\photo-hub\photo-hub\env\lib\site-packages\rest_framework\serializers.py" 在领域 340.对于key,self.get_fields().items()中的值:

文件 "D:\code\active\Python\Django\photo-hub\photo-hub\env\lib\site-packages\rest_framework\serializers.py" 在 get_fields 947. field_names = self.get_field_names(declared_fields,信息)

文件 "D:\code\active\Python\Django\photo-hub\photo-hub\env\lib\site-packages\rest_framework\serializers.py" 在 get_field_names 1046. serializer_class=self.class.name

异常类型:/api/users/ 处的 AssertionError 异常值: 在序列化程序 UserSerializer 上声明了字段“照片”,但尚未 已包含在“字段”选项中。

但我的 UserSerializer 甚至没有“照片”字段。我是 django 新手,请帮助我了解这个问题的根源。

序列化器.py

from django.utils import timezone
from django.contrib.auth.models import User

from rest_framework import serializers

from api.models import Album, Photo

class PhotoSerializer(serializers.HyperlinkedModelSerializer):
    #url = serializers.HyperlinkedIdentityField(view_name="photo-detail")
    album = serializers.HyperlinkedRelatedField(view_name='album-detail', queryset=Album.objects)
    owner = serializers.HyperlinkedRelatedField(view_name='user-detail', queryset=User.objects)

    class Meta:
        model = Photo
        fields = ('url', 'name', 'image', 'creation_date', 'owner', 'album')
        read_only_fields=('creation_date')

class AlbumSerializer(serializers.HyperlinkedModelSerializer):
    #url = serializers.HyperlinkedIdentityField(view_name="album-detail")
    owner = serializers.HyperlinkedRelatedField(view_name='user-detail', queryset=User.objects)
    photos = serializers.HyperlinkedRelatedField(view_name='photo-list',  queryset=Photo.objects, many=True)

    def get_validation_exclusions(self):
        # Need to exclude `author` since we'll add that later based off the request
        exclusions = super(AlbumSerializer, self).get_validation_exclusions()
        return exclusions + ['user']

    class Meta:
        model = Album
        fields = ('pk', 'name', 'creation_date', 'owner', 'photos')
        read_only_fields=('creation_date')

class UserSerializer(serializers.HyperlinkedModelSerializer):
    #url = serializers.HyperlinkedIdentityField(view_name="user-detail", read_only=True)
    albums = serializers.HyperlinkedRelatedField(many=True, view_name='album-list', queryset=Album.objects)

    password = serializers.CharField(write_only=True, required=True)
    confirm_password = serializers.CharField(write_only=True, required=True)

    class Meta:
        model = User
        fields = ('url', 'pk', 'username', 'email', 'password', 'is_staff', 'albums')
        write_only_fields = ('password')
        read_only_fiels = ('pk')

    def create(self, validated_data):
        user = User.objects.create(
            username=validated_data['username'],
            email=validated_data['email'],
        )
        user.set_password(validated_data['password'])
        user.save()
        return user

    def update(self, instance, validated_data):
        user = super(UserSerializer, self).update(instance, validated_data)
        user.set_password(validated_data['password'])
        user.save()
        return user    


    def validate(self, data):
        if data['password']:
            if data['password'] != data['confirm_password']:
                raise serializers.ValidationError(
                    "The passwords have to be the same"
                )
        return data

AuthRegister 视图

class AuthRegister(APIView):
    serializer_class = UserSerializer
    permission_classes = (permissions.AllowAny,)

    def post(self, request, format=None):
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

api/urls.py

from django.conf.urls import include, url
from .views import AuthRegister
from rest_framework_jwt.views import obtain_jwt_token, refresh_jwt_token, verify_jwt_token
from rest_framework import routers
from api import views

router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(r'albums', views.AlbumViewSet)
router.register(r'photos', views.PhotoViewSet)

urlpatterns = [
    url(r'^', include(router.urls)),
    url(r'^login/', obtain_jwt_token),
    url(r'^token-refresh/', refresh_jwt_token),
    url(r'^token-verify/', verify_jwt_token),
    url(r'^register/$', AuthRegister.as_view()),

【问题讨论】:

你能提供完整的回溯吗? 添加完整的回溯。 我不熟悉 REST 框架,但我怀疑这与将相册资源中的照片字段传播到用户之一有关。 无法真正发现这里有什么问题。尝试删除一些序列化程序,看看是否有改变。 【参考方案1】:

我终于找到了我愚蠢错误的根源。原因是早些时候我的模型中有照片字段。但是在对模型进行更改后,我忘记了进行迁移。

【讨论】:

以上是关于该字段已在序列化程序上声明,但在 django rest 中未包含错误的主要内容,如果未能解决你的问题,请参考以下文章

Django REST Framework 序列化程序字段必需=false

在 GET 中隐藏密码字段,但在 Django REST Framework 中隐藏密码字段,其中序列化程序中的 depth=1

Django - 带有序列化程序的可选字段

与 Django 序列化程序上的自定义字段的 Swagger 兼容性?

序列化程序django rest框架上的字段值属性错误

反序列化具有在 AssemblyResolve 上加载的其他程序集中声明的类型字段的对象时出错