Создать объект пользователя поля OneToOne в сериализации Django - PullRequest
1 голос
/ 12 июля 2020

Я пытаюсь создать объект User, используя свой Staff класс. Моя модель персонала выглядит следующим образом:

class Staff(models.Model):
    organization = models.ForeignKey(
        Organization, related_name='staff_organization', on_delete=models.CASCADE, blank=True)
    user = models.OneToOneField(
        User, on_delete=models.CASCADE, blank=True)
    phone = models.CharField(max_length=15, blank=True)

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

Мой класс сериализатора здесь,

# create staff serializer
class StaffSerializer(serializers.ModelSerializer):

    class Meta:
        model = Staff
        fields = "__all__"

    def create(self, validated_data):
        username = validated_data.pop('username')
        email = validated_data.pop('email')
        password = validated_data.pop('password')
        user_instance, created = User.objects.get_or_create(
            username=username, email=email)

        if not created:
            user_instance.set_password(password)

        staff_instance = Staff.objects.create(
            **validate_data, user=user_instance)
        return staff_instance

Класс Viewset,

class StaffViewSet(viewsets.ModelViewSet):
    serializer_class = StaffSerializer
    queryset = Staff.objects.all()
    permission_classes = [permissions.IsAuthenticated]


    def perform_create(self, serializer):
        staff = serializer.save(organization=self.request.user.staff.organization)
        return Response(serializer.data)

Я попробовал отправить запрос, как показано ниже ,

{"username":"tekson", "email":"tekson@gmail.com", "password":"admin"}

Но показывает ошибку

{
    "user": [
        "This field is required."
    ]
}

Я не знаю, как создать объект пользователя из персонала. Пожалуйста, помогите мне разобраться в этой ошибке.

Ответы [ 2 ]

1 голос
/ 12 июля 2020

Другой способ: определить UserSerializer

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'

Затем отредактируйте свой StaffSerializer так, как это.

class StaffSerializer(serializers.ModelSerializer):

    user = UserSerializer(many=False)

    class Meta:
        model = Staff
        fields = "__all__"

    def create(self, validated_data):
        user_data = validated_data.pop('user')
        user_instance = User.objects.create(
            username=user_data['username'],email=user_data['email'], password=user_data['password'])
        user_instance.save()
        
        staff_instance = Staff.objects.create(
            **validated_data, user=user_instance)
        staff_instance.save()
        return staff_instance

Единственным недостатком этого подхода является то, что у вас будет для поддержания вложенных отношений в отправляемых вами почтовых данных. Так что ваши данные {"username":"tekson", "email":"tekson@gmail.com", "password":"admin"} нужно будет изменить на что-то вроде этого.

{
    "phone": "",
    "user": {"username":"tekson", "email":"tekson@gmail.com", "password":"admin"}
}
1 голос
/ 12 июля 2020

Обязательно звоните user_instance.save() после set_password().

...