Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x Django Rest框架-到\u内部\u值错误不一致_Python 3.x_Django_Django Rest Framework - Fatal编程技术网

Python 3.x Django Rest框架-到\u内部\u值错误不一致

Python 3.x Django Rest框架-到\u内部\u值错误不一致,python-3.x,django,django-rest-framework,Python 3.x,Django,Django Rest Framework,我有一个模型,User,其中主要的唯一字段是email。我有一个单独的组织模型,允许用户通过多对多映射映射到组织 我希望序列化程序允许用户创建,如果他们有一个现有的电子邮件,但没有组织关联(组织是从用户提出请求,所以不在有效负载) 标准ModelSerializer包含对to_internal_value()中字段的检查。因此,我试图这样覆盖它: def to_internal_value(self, data): """ D

我有一个模型,User,其中主要的唯一字段是email。我有一个单独的组织模型,允许用户通过多对多映射映射到组织

我希望序列化程序允许用户创建,如果他们有一个现有的电子邮件,但没有组织关联(组织是从用户提出请求,所以不在有效负载)

标准ModelSerializer包含对to_internal_value()中字段的检查。因此,我试图这样覆盖它:

    def to_internal_value(self, data):
        """
        Dict of native values <- Dict of primitive datatypes.
        """
        fields = self._writable_fields
        for field in fields:
            validate_method = getattr(self, 'validate_' + field.field_name, None)
            primitive_value = field.get_value(data)
            try:
                if validate_method == self.validate_email:
                    if User.objects.filter(email=primitive_value).exists():
                        if not self.active_organization.members.filter(email=primitive_value).exists():
                            continue
                else:
                    validated_value = field.run_validation(primitive_value)
                    if validate_method is not None:
                        validated_value = validate_method(validated_value)
            except ValidationError as exc:
                errors[field.field_name] = exc.detail
            except DjangoValidationError as exc:
                errors[field.field_name] = get_error_detail(exc)
            except SkipField:
                pass
            else:
                set_value(ret, field.source_attrs, validated_value)
        return super().to_internal_value(data)
输出:

trying custom
<bound method CharField.run_validation of EmailField(max_length=254, validators=[<UniqueValidator(queryset=User.objects.all())>])>
error custom
[ErrorDetail(string='User with this Email already exists.', code='unique')]

Trying original
Exception - original
{'email': [ErrorDetail(string='User with this Email already exists.', code='unique')]}
尝试自定义
错误自定义
[ErrorDetail(string='User with this Email已存在',code='unique')]
尝试原创
例外-原件
{'email':[ErrorDetail(string='User with this email已经存在',code='unique')]}

有人能帮我理解为什么会这样吗?我真的很想知道这是怎么发生的。

我无法弄清楚为什么当我从底层ModelSerializer复制代码而不是调用super()时,
到内部值(self,data)
生成的错误会发生变化。然而,我确实找到了一种黑客的解决方法

因为我事先去掉了所有其他相关的信息(嵌套序列化程序),所以我真的很担心电子邮件。因此,我遍历了两次_writable_字段:第一次查找不在组织中的现有电子邮件。如果这些条件为真,我将返回一个dictionary并继续执行create()方法。如果他们失败了,我叫超级。到目前为止,这似乎是可行的。这是我的简化课程

    def to_internal_value(self, data):
        """
        Dict of native values <- Dict of primitive datatypes.
        """
        try:
            for field in self._writable_fields:
                if field.field_name == 'email':
                    primitive_value = field.get_value(data)
                    validator = EmailValidator()
                    validator(primitive_value)
                    if User.objects.filter(email=primitive_value).exists():
                        if not self.active_organization.members.filter(email=primitive_value).exists():
                            self.email_already_exists = True
                            return {'email': primitive_value}
        except:
            pass

        return super().to_internal_value(data)
def到_内部_值(自身,数据):
"""

本机值的Dict您希望如何创建已存在电子邮件的用户?如果您的用户模型上有email unique=True,则不可能。这就是我尝试此操作的原因。基本上,我检查用户是否已存在于此to_internal_value()中call.If they do&&它们存在于组织中,我希望返回正常的失败消息。如果它们仅作为电子邮件而不是组织存在,则数据将被提供给create()方法,在该方法中,我不创建电子邮件,而是将它们添加到组织中:organization.members.add(User.objects.get(email=email))。奇怪的是,当我重写to_internal_value方法时,错误不会作为以“email”为键的字典返回。我会在接下来的半天里帮助你。基本上尝试在serializer中使用validate_email方法(在这里你可以验证email,不要重写to_internal_value方法!),并尝试使用self context['request'].user(在序列化程序中)…以获取活动组织。
    def to_internal_value(self, data):
        """
        Dict of native values <- Dict of primitive datatypes.
        """
        try:
            for field in self._writable_fields:
                if field.field_name == 'email':
                    primitive_value = field.get_value(data)
                    validator = EmailValidator()
                    validator(primitive_value)
                    if User.objects.filter(email=primitive_value).exists():
                        if not self.active_organization.members.filter(email=primitive_value).exists():
                            self.email_already_exists = True
                            return {'email': primitive_value}
        except:
            pass

        return super().to_internal_value(data)
class AdminUsersSerializer(serializers.ModelSerializer):
    """User serializer for the admin user view"""
    groups = GenericGroupSerializer(source='group_set', many=True, required=False)
    permission_sets = GenericPermissionSetSerializer(source='permissionset_set', many=True, required=False)
    active_organization = None
    email_already_exists = False

    class Meta:
        model = User
        fields = ['pk', 'email', 'groups', 'permission_sets']  # , 'permissions']

    def set_active_organization(self, organization):
        self.active_organization = organization

    def create(self, validated_data):
        if not self.email_already_exists:
            user = User.objects.create(
                email=validated_data['email']
            )
            user.set_password(None)
            user.save()
        else:
            user = User.objects.get(email=validated_data['email'])
        return user

    def to_internal_value(self, data):
        """
        Dict of native values <- Dict of primitive datatypes.
        """
        try:
            for field in self._writable_fields:
                if field.field_name == 'email':
                    primitive_value = field.get_value(data)
                    validator = EmailValidator()
                    validator(primitive_value)
                    if User.objects.filter(email=primitive_value).exists():
                        if not self.active_organization.members.filter(email=primitive_value).exists():
                            self.email_already_exists = True
                            return {'email': primitive_value}
        except:
            pass

        return super().to_internal_value(data)

class AdminUsersViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = AdminUsersSerializer
    permission_classes = [account_permissions.IsAdminRequired]
    http_method_names = ['get', 'post']
    active_organization = None

    def create(self, request, *args, **kwargs):
        self.active_organization = self.request.user.activeorganization.organization
        groups = None
        permission_sets = None
        serializer = self.get_serializer(data=request.data)
        serializer.set_active_organization(self.active_organization)
        if 'groups' in serializer.initial_data:
            if serializer.initial_data.get('groups'):
                groups = serializer.initial_data.pop('groups')
            else:
                serializer.initial_data.pop('groups')
        if 'permission_sets' in serializer.initial_data:
            if serializer.initial_data.get('permission_sets'):
                permission_sets = serializer.initial_data.pop('permission_sets')
            else:
                serializer.initial_data.pop('permission_sets')
        # Normal method functions
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        # Created user
        user = User.objects.get(email=serializer.data['email'])
        # Add user to organization
        self.active_organization.members.add(user)
        # Make sure to format the ajax groups data properly
        if groups:
            try:
                group = Group.objects.get(
                    id=groups,
                    organization=self.active_organization
                )
                group.members.add(user)
            except:
                pass
        if permission_sets:
            try:
                permission_set = PermissionSet.objects.get(
                    id=permission_sets,
                    organization=self.active_organization
                )
                permission_set.members.add(user)
            except:
                pass
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def get_queryset(self):
        return self.queryset.filter(
            userorganizationmembership__organization=self.request.user.activeorganization.organization
        ).all()