如何从序列化器返回实际数据Django

uelo1irk  于 2023-11-20  发布在  Go
关注(0)|答案(1)|浏览(131)

我试图在Django上测试一个register_customer API端点,但我得到的是user_id作为响应,而不是实际用户的数据。
{

"data": {

    "user_id": 15

},

"message": "Thank you for registering"

字符串
}我有一个与CustomUser具有一对一关系的Customer模型
class Customer(models.Model):

user_id = models.OneToOneField(CustomUser, on_delete=models.CASCADE)`


下面是我的serializer:
`
从rest_framework导入序列化器
from .models import Customer,CustomUser
输入记录
logger = logging.getLogger(name
class UserSerializer(serializers.ModelSerializer):

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

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

class Meta:

    model = CustomUser

    fields = [

        "email",

        "first_name",

        "last_name",

        "phone_number",

        "password",

        "confirm_password",

    ]

def validate_password(self, value):

    # Password must be at least 8 characters long

    if len(value) < 8:

        raise serializers.ValidationError(

            "Password must be at least 8 characters long."

        )

    # Check for at least one uppercase character

    if not any(char.isupper() for char in value):

        raise serializers.ValidationError(

            "Password must contain at least one uppercase character."

        )

    # Check for at least one special character

    special_characters = "!@#$%^&*()-_=+[]{}|;:'\",.<>/?"

    if not any(char in special_characters for char in value):

        raise serializers.ValidationError(

            "Password must contain at least one special character."

        )

    # Check for at least one number

    if not any(char.isdigit() for char in value):

        raise serializers.ValidationError(

            "Password must contain at least one number."

        )

    return value

def validate_email(self, value):

    if CustomUser.objects.filter(email=value).exists():

        raise serializers.ValidationError("This email is already in use.")

    return value

def validate(self, data):

    # Check if password and confirm_password match

    password = data.get("password")

    confirm_password = data.get("confirm_password")

    logger.debug({password, confirm_password})

    if password != confirm_password:

        raise serializers.ValidationError("Passwords do not match.")

    return data

def create(self, validated_data):

    # Remove 'confirm_password' from the data before creating the user

    validated_data.pop("confirm_password", None)

    # Retrieve password directly from validated_data

    password = validated_data.get("password")

    # Ensure that password is not None before validating its length

    if password is None:

        raise serializers.ValidationError("Password cannot be empty.")

    self.validate_password(password)

    # Create the user without 'confirm_password'

    user = CustomUser.objects.create_user(**validated_data)

    # Set the password for the user

    user.set_password(password)

    user.save()

    return user


class CustomerSerializer(serializers.ModelSerializer):

class Meta:

    model = Customer

    fields = ["user_id"] `


这是我正在测试的视图:
`
类RegisterCustomerView(APIView):

@transaction.atomic

def post(self, request, *args, **kwargs):

    logger.debug(f"Request_data: {request.data}")

    user_data = request.data

    # Validate UserSerializer first

    user_serializer = UserSerializer(data=user_data)

    if user_serializer.is_valid():

        # Access validated data after validation

        user_data = user_serializer.validated_data

        if user_data:

            try:

                user = user_serializer.save()

                customer_data = {"user_id": user.id}

                customer_serializer = CustomerSerializer(data=customer_data)

                if customer_serializer.is_valid():

                    customer_serializer.save()

                    # Automatically send verification email upon successful registration

                    send_verification_email(user)

                    return Response(

                        {

                            "data": customer_serializer.data,

                            "message": "Thank you for registering",

                        },

                        status=status.HTTP_201_CREATED,

                    )

                else:

                    raise ValidationError(detail=customer_serializer.errors)

            except IntegrityError as e:

                logger.error(f"Integrity error: {e}")

                return Response(

                    {"detail": "Integrity error. Please ensure the data is unique."},

                    status=status.HTTP_400_BAD_REQUEST,

                )

            except Exception as e:

                logger.error(f"An unexpected error occurred: {e}")

                return Response(

                    {"detail": "An unexpected error occurred."},

                    status=status.HTTP_500_INTERNAL_SERVER_ERROR,

                )

    else:

        raise ValidationError(detail=user_serializer.errors)`


我已经在CustomerSerializer上尝试过了
`
class CustomerSerializer(serializers.ModelSerializer):

email = serializers.EmailField(source='user.email')

first_name = serializers.CharField(source='user.first_name')

last_name = serializers.CharField(source='user.last_name')

phone_number = serializers.CharField(source='user.phone_number')

class Meta:

    model = Customer

    fields = ["email", "first_name", "last_name", "phone_number"] `


但我没有得到预期的实际React,
`
{

"detail": {

    "email": [

        "This field is required."

    ],

    "first_name": [

        "This field is required."

    ],

    "last_name": [

        "This field is required."

    ],

    "phone_number": [

        "This field is required."

    ]

}


}`
我很感激任何帮助。谢谢

0x6upsns

0x6upsns1#

如果你想在Customer模型中获取CustomUser数据,你可以为CustomUser模型定义嵌套的序列化器,并将其添加到CustomerSerializer中:

class CustomUserNestedSerializer(serializers.ModelSerializer):
    class Meta:
        model = CustomUser
        fields = ('pk', 'email', 'first_name', 'last_name', 'phone_number',)

class CustomerSerializer(serializers.ModelSerializer):
    user_id = CustomUserNestedSerializer(read_only=True)

    class Meta:
        model = Customer
        fields = ('pk', 'user_id',)

字符串
同样在你的视图中,你正在使用序列化器创建Customer对象。而不是这样,直接用model创建customer,然后将对象传递给序列化器返回它:

customer_obj = Customer.objects.create(user_id=user)
customer_serialized = CustomerSerializer(customer_obj).data
return Response(customer_serialized, status=status.HTTP_20_CREATED)


您修改的Customer的序列化程序是可以的,只需将source修改为user_id而不是user,因为您的字段名称在Customer模型中是user_id,并且read_only=True也是字段。

相关问题