Поле 'customer_id' ожидало число, но получило <Customer: Lary

У меня есть эти две модели с их сериализаторами:

class ChronicPrescription
    chronic_prescription_id = models.AutoField(primary_key=True)
    date = models.DateField(default=datetime.date.today, validators=[no_future_date, no_old_date])
    # This field is for the prescription duration in days
    duration = models.PositiveIntegerField(default=90, validators=[MaxValueValidator(90), MinValueValidator(30)])
    customer = models.ForeignKey('customers.Customer', on_delete=models.CASCADE, related_name="chronic_prescription", 
                                 validators=[prescriptions_for_patient_only])


class Customer(models.Model):
    id = models.BigAutoField(primary_key=True)
    customer_name = models.CharField(max_length=100, null=False, blank=False, unique=True)
    phones = ArrayField(models.CharField(max_length=10, validators=[validate_phone_number, prevent_replicated_phone]), 
                                        default=list, null=True, blank=True)
    customer_type = models.CharField(max_length=10,default='patient', choices=CUSTOMER_TYPE)

Проблема заключается в том, что когда я пытаюсь создать сериализатор рецептов во время модульного теста (тест должен потерпеть неудачу из-за продолжительности, она не должна превышать 90) во время модульного теста:

 def test_upper_bound_duration(self):
        customer = Customer.objects.create(customer_name="Lary")
        prescr_serializer = ChronicPrescriptionSerializer(data={'duration': 1000, 'customer': customer.id})
        
        if prescr_serializer.is_valid():
            prescr_serializer.save()
        self.assertFalse(prescr_serializer.is_valid())
        
        self.assertEqual(set(prescr_serializer.errors), set(['duration'])) 

У меня возникла непредвиденная ошибка: Поле 'id' ожидало число, но получило <Customer: Lary>.

Даже я предоставляю id клиента, а не самого клиента, Что странно, все было хорошо, но вдруг это больше не работает.

Сериализатор рецептов:

class ChronicPrescriptionSerializer(serializers.ModelSerializer):
    drugs = PrescriptionItemSerializer(many=True, read_only=True)
    notification_status = serializers.BooleanField(default=True)

    left_days = serializers.SerializerMethodField()
    def get_left_days(self, obj):
        return obj.count_left_days()

    class Meta:
        model = ChronicPrescription
        fields = ('chronic_prescription_id', 'date', 'duration', 'notification_status', 'left_days', 'drugs', 'customer') 

Ваш код должен быть примерно таким:

def test_upper_bound_duration(self):
    customer = Customer.objects.create(customer_name="Lary")
    customer.save()
    prescr_serializer = ChronicPrescriptionSerializer(data={'duration': 1000, 'customer': customer.id})
    
    if prescr_serializer.is_valid():
        prescr_serializer.save()
    self.assertFalse(prescr_serializer.is_valid())
    
    self.assertEqual(set(prescr_serializer.errors), set(['duration'])) 

Я предполагаю, что корень проблемы был в функции валидации для модели ChronicPrescription, поэтому код работал до нее:

def prescriptions_for_patient_only(value):
    customer = Customer.objects.get(pk=value)
    if customer.customer_type != 'patient':
        raise ValidationError('Only patient customer can have prescriptions.')

Когда мы сериализуем рецепт, метод валидации получил в качестве параметра экземпляр клиента, поэтому я получил ошибку: ожидалось число, а получил Customer: Lary>. из-за

customer = Customer.objects.get(pk=value)

Поэтому я рефакторизировал метод валидации следующим образом:

def prescriptions_for_patient_only(value):
    if  isinstance(value, int):
        customer = Customer.objects.get(pk=value)
    else:
        customer = value

    if customer.customer_type != 'patient':
        raise ValidationError('Only patient customer can have prescriptions.')

И он работал нормально.

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