Поле '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.')
И он работал нормально.