Ошибка Django Rest Framework: {'user': [ErrorDetail(string='Это поле обязательно.', code='required')]}

Невозможно добавить нового клиента в базу данных... Я создал класс customer, который имеет отношения один-к-одному с классом User, который является AbstractUser

Я хочу отправить данные через rest API, чтобы я мог создать нового клиента в таблице клиентов и нового пользователя, который один к одному связан с клиентом, из того же представления. Модель пользователя

class User(AbstractUser):
# Add additional fields here
id = None
email = models.EmailField(max_length=254, primary_key=True)
name = models.CharField(max_length=100)
password = models.CharField(max_length=100)
is_patient = models.BooleanField(default=False)
is_doctor = models.BooleanField(default=False)
is_homesampler = models.BooleanField(default=False)
is_pathologist = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=False)
date_joined = models.DateTimeField(auto_now_add=True)
last_login = models.DateTimeField(auto_now=True)
first_name = None
last_name = None
username = None

USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['name', 'password']
objects = CustomUserManager()

def __str__(self):
    return self.email

# Ensure that the password is hashed before saving it to the database
def save(self, *args, **kwargs):
    self.password = make_password(self.password)
    super(User, self).save(*args, **kwargs)

def has_perm(self, perm, obj=None):
    return self.is_superuser

User Serializer

class UserSerializer(serializers.ModelSerializer):

class Meta:
    model = get_user_model()
    # fields = (['id', 'username', 'email', 'name'])
    fields = '__all__'

Модель клиента

class customer(models.Model):
user = models.OneToOneField(
    get_user_model(), on_delete=models.CASCADE, primary_key=True)
real = models.BooleanField(default=False)

def __str__(self):
    return self.user.name

Сериализатор клиента

class CustomerSerializer(serializers.ModelSerializer):
userdata = UserSerializer(read_only=True, source='user')

class Meta:
    model = customer
    fields = '__all__'

    def create(self, validated_data):
        user_data = validated_data.pop('user')
        user = get_user_model().objects.create(**user_data)
        user.is_Patient = True
        customer = customer.objects.create(user=user, **validated_data)
        return customer

Создать представление клиента

# Create add customer API
@api_view(['POST'])
def addCustomer(request):

    customer_serializer = CustomerSerializer(data=request.data)
    if(customer_serializer.is_valid()):
        customer_serializer.save()
    print(customer_serializer.errors)

    return Response({'message': 'okay'})

Тело вызова API

{
    "email" : "test@test.com",
    "password": "Abc"
}

Вопрос в том, как я могу создать представление, чтобы я мог создать нового пользователя и клиента, используя только один вызов API

Тело вашего вызова не соответствует CustomerSerializer.

CustomerSerializer полями являются "user" и "rest", поэтому вы можете передать только эти два, если только не сделаете что-то вроде этого:

class CustomerSerializer(serializers.ModelSerializer):
    userdata = UserSerializer(read_only=True, source='user')
    email = serializers.EmailField(write_only=True)
    password = serializers.CharField(write_only=True)

    class Meta:
        model = customer
        fields = ["userdata", "email", "password", "id", "real"]


    def create(self, validated_data):
        email = validated_data.pop("email")
        password = validated_data.pop("password")

        user = get_user_model().objects.create(**{
          "email": email,
          "password": password
        })
        user.is_Patient = True
        customer = customer.objects.create(user=user, **validated_data)
        
        return customer

По поводу метода create, он не будет работать правильно:

Причина:

  1. Не следует использовать create для создания нового пользователя, вместо этого следует использовать create_user More
  2. Я заметил, что вы удалили имя пользователя, так что этот метод будет бесполезен :)
  3. После user.is_Patient = True вы забыли сохранить пользователя

Правильным кодом будет:

class CustomerSerializer(serializers.ModelSerializer):
    userdata = UserSerializer(read_only=True, source='user')
    email = serializers.EmailField(write_only=True)
    password = serializers.CharField(write_only=True)

    class Meta:
        model = customer
        fields = ["userdata", "email", "password", "id", "real"]


    def create(self, validated_data):
        email = validated_data.pop("email")
        password = validated_data.pop("password")

        user = get_user_model().objects.create(email=email)
        user.set_password(password)
        user.is_Patient = True
        user.save()

        customer = customer.objects.create(user=user, **validated_data)
        
        return customer

ПРИМЕЧАНИЕ 1:

# Ensure that the password is hashed before saving it to the database
def save(self, *args, **kwargs):
    self.password = make_password(self.password)
    super(User, self).save(*args, **kwargs)

Здесь неправильный подход к make_password, потому что всякий раз, когда вы вносите изменения в пользователя, он будет запускаться.

идеальным подходом было бы использование user.set_password("new_pass") всякий раз, когда вы получаете новый пароль от пользователя.

ПРИМЕЧАНИЕ 2:

Когда вы передаете read_only в сериализатор, это средство будет проигнорировано, если вы передадите его как data в сериализатор.

Что касается write_only, то это противоположность read_only. Он не будет возвращен, если вы вызовете serializer.data. Например, мы хотим только записывать в пароль, и не хотим читать его из сериализатора, поэтому мы сделали его write_only.

Вернуться на верх