如何解决Serializer Create方法中DjangoRestFramework中的CreateAPI 400错误?

问题描述 投票:0回答:1

我有一个模型 Doctor,它与用户模型有外键关系。我正在通过 Doctor 模型的序列化器处理 Doctor 实例的创建。我想要的流程只是检查具有给定用户名的用户是否存在。如果存在,则使用现有用户创建一个新的Doctor实例,如果不存在,则首先创建一个新用户,然后使用该新用户创建一个Doctor实例。 这是我的 Doctor Serializer :->

class StaffSerializer(serializers.ModelSerializer):
    """
    Serializer for viewing entries Doctor model
    """

    departments_display = DepartmentSerializer(
        many=True, source="departments", read_only=True
    )
    appointment_types_display = AppointmentTypeSerializer(
        many=True, source="appointment_types", read_only=True
    )
    user = UserSerializer()
    permissions = PermissionSerializer(many=True)
    doc_image = serializers.SerializerMethodField()
    class Meta:
        model = Doctor
        exclude = ("hospitals",)
        extra_kwargs = {
            "departments": {"write_only": True},
            "appointment_types": {"required": False},
        }
    
    def get_doc_image(self,obj):
        return obj.doctor_image
    
    def create(self, validated_data):
        """
        Create and return a new `Doctor` instance, given the validated data.
        """
      #  try:
        with transaction.atomic():
                user_data = validated_data.pop("user")
                try:
                    user = User.objects.get(username = user_data["username"])
                    validated_data["user"] = user
                except ObjectDoesNotExist:
                    serializer = UserSerializer(data = user_data)
                    if serializer.is_valid():
                       serializer.save()
                    validated_data["user"] = serializer.instance
                permmissions = validated_data.pop("permissions")
                permissions_to_insert = []
                for permission_entry in permmissions:
                    uiserializer = UIElementSerializer(data = permission_entry["ui_element"])
                    uiserializer.is_valid()
                    uiserializer.save()
                    permissions_to_insert.append(
                        StaffPermissions(
                            ui_element=uiserializer.instance,
                            create=permission_entry["create"],
                            read=permission_entry["read"],
                            update=permission_entry["update"],
                            delete=permission_entry["delete"],
                        )
                    )
                permission_instance = StaffPermissions.objects.bulk_create(
                    permissions_to_insert
                )
                doc_obj = super().create(validated_data)
                doc_obj.permissions.add(*permission_instance)
                return doc_obj
        #except Exception as e:
         #   raise APIException()

这是用户和医生模型:->

class CustomUser(AbstractUser):
    name = models.CharField(max_length=100, blank=True, null=True)
    name_hi = models.CharField(max_length=100, blank=True, null=True)
    age = models.IntegerField(blank=True, null=True)
    gender = models.BooleanField(blank=True, null=True)
    profile_image = models.URLField(null=True, blank=True, max_length=127)
    role = models.IntegerField(choices=USER_ROLES, null=True, blank=True)
    language = models.CharField(
        max_length=2, choices=LANGUAGE_CHOICES, null=True, blank=True
    )
    push_tokens = models.ManyToManyField(PushNotificationToken, blank=True)

    def __str__(self):
        return self.name or ""


class Doctor(TimeStampedModel):
    user = models.ForeignKey(User, on_delete=models.CASCADE) #User = get_user_model()
    is_visible = models.BooleanField(default=True)
    is_deleted = models.BooleanField(default=False)
    is_admitting_officer = models.BooleanField(default=False)
    practice_started_year = models.IntegerField(null=True, blank=True)
    about = models.CharField(null=True, blank=True, max_length=1023)
    about_hi = models.CharField(null=True, blank=True, max_length=1023)
    credentials = models.CharField(null=True, blank=True, max_length=255)
    departments = models.ManyToManyField(Department)
    hospital = models.ForeignKey(
        Hospital, on_delete=models.CASCADE, related_name="hospital_doctor"
    )
    permissions = models.ManyToManyField(StaffPermissions, blank=True)
    appointment_types = models.ManyToManyField("appointments.AppointmentTypes")
    role = models.IntegerField(choices=ROLES, null=True, blank=True)

这是视图:-

 class StaffView(generics.ListCreateAPIView):
      

        permission_classes = (IsAuthenticated,)
        serializer_class = StaffSerializer
    
        def get_queryset(self):
            try:
                if self.request.GET.get("hospital_id"):
                    return Doctor.objects.filter(
                        hospital=self.request.GET.get("hospital_id")
                    ).order_by("-modified_date")
                else:
                    return Doctor.objects.filter(user=self.request.user)
            except ValueError as exc:
                raise APIException(
                    "Please send in a valid hospital id and/or doctor id."
                ) from exc

当我创建一个新的医生实例时,它不断抛出错误,该用户的用户已经存在。这很难相信,因为我使用 try-exception 块来验证用户是否存在,然后采取适当的操作。 有人能帮我解决这个问题吗? 预先感谢!!

django django-models django-rest-framework django-views django-serializer
1个回答
0
投票

正在引发 DoesNotExist,但不是 ObjectDoesNotExist,您应该尝试捕获该异常而不是此异常。

            try:
                user = User.objects.get(username = user_data["username"])
                validated_data["user"] = user
            except User.DoesNotExist:
                serializer = UserSerializer(data = user_data)
                if serializer.is_valid():
                   serializer.save()
                validated_data["user"] = serializer.instance

这可能会解决问题。

对于这个特定的用例,您可以尝试 get_or_create()

© www.soinside.com 2019 - 2024. All rights reserved.