ValueError: Невозможно присвоить "1": "LeadFacilityAssign.assigned_facilities" должен быть экземпляром "Facility".
Я пытаюсь создать конечную точку api для обновления моих объектов "lead" и добавления к ним списка объектов при отправке запроса put (каждый раз разное количество объектов). Объекты "lead" уже существуют в базе данных, как и объекты "facility". Поскольку мне нужны дата и время, связанные с каждым объектом, когда они добавляются к свинцу, я создал класс "LeadFacilityAssign". Поскольку я не смог заставить его работать, я попытался сделать это просто с помощью пост-запроса во время процесса создания объекта. Мне сказали, что я должен использовать bulk_create, если мне нужно добавить более одного объекта таким образом. Я не смог найти ничего о bulk_create в документации по drf, поэтому я решил пока сделать это только с одним объектом и улучшать свой код по одному вопросу за раз, так как я новичок в drf.
Кто-нибудь знает, что вызывает эту ошибку? Я пробовал несколько разных вещей, но пока ничего не помогло.
ValueError: Cannot assign "1": "LeadFacilityAssign.assigned_facilities" must be a "Facility" instance.
serializers.py
class LeadUpdateSerializer(serializers.ModelSerializer):
is_owner = serializers.SerializerMethodField()
assigned_facilities = serializers.IntegerField(required=True)
datetime = serializers.DateTimeField(required=True)
class Meta:
model = Lead
fields = (
"id",
"first_name",
"last_name",
"assigned_facilities",
"datetime",
)
read_only_fields = ("id", "created_at", "agent", "is_owner")
def get_is_owner(self, obj):
user = self.context["request"].user
return obj.agent == user
def create(self, validated_data):
assigned_facilities = validated_data.pop("assigned_facilities")
datetime = validated_data.pop("datetime")
instance = Lead.objects.create(**validated_data)
instance.leadfacility.create(assigned_facilities=assigned_facilities,datetime=datetime)
print(instance)
return instance
models.py
class Facility(models.Model):
name = models.CharField(max_length=150, null=True, blank=False)
def __str__(self):
return self.name
class Lead(models.Model):
first_name = models.CharField(max_length=40, null=True, blank=True)
last_name = models.CharField(max_length=40, null=True, blank=True)
def __str__(self):
return f"{self.first_name} {self.last_name}"
class LeadFacilityAssign(models.Model):
assigned_facilities = models.ForeignKey(Facility, on_delete=models.CASCADE, related_name='leadfacility')
lead = models.ForeignKey(Lead, on_delete=models.CASCADE, related_name='leadfacility')
datetime = models.DateTimeField()
views.py
class LeadCreateView(CreateAPIView):
permission_classes = [IsAuthenticated, IsLeadOwner]
serializer_class = LeadUpdateSerializer
def perform_create(self, serializer):
serializer.save(agent=self.request.user)
class LeadUpdateView(UpdateAPIView):
permission_classes = [IsAuthenticated, IsLeadOwner]
serializer_class = LeadUpdateSerializer
def get_queryset(self):
return Lead.objects.all()
Вы пытаетесь добавить значение Integer
в FK field
.
У вас есть 2 варианта. Вы можете изменить поле сериализатора.
assigned_facilities = serializers.PrimaryKeyRelatedField(queryset=Facility.objects.all(), required=True)
ИЛИ
instance.leadfacility.create(assigned_facilities_id=assigned_facilities,datetime=datetime)
Я бы предпочел использовать 1 вариант.
Другое потенциальное решение, которое вы можете применить:
class LeadUpdateSerializer(serializers.ModelSerializer):
is_owner = serializers.SerializerMethodField()
assigned_facilities = serializers.IntegerField(required=True)
datetime = serializers.DateTimeField(required=True)
class Meta:
model = Lead
fields = (
"id",
"first_name",
"last_name",
"assigned_facilities",
"datetime",
)
read_only_fields = ("id", "created_at", "agent", "is_owner")
def validate_assigned_facility(self, facility_pk)->:
assigned_facility = Facility.objects.filter(pk=facility_pk).first()
if assigned_facility:
return assigned_facility
raise ValidationError('Facility not found, provide a valid pk')
def get_is_owner(self, obj):
user = self.context["request"].user
return obj.agent == user
def create(self, validated_data):
assigned_facilities = validated_data.pop("assigned_facilities")
datetime = validated_data.pop("datetime")
instance = Lead.objects.create(**validated_data)
instance.leadfacility.create(assigned_facilities=assigned_facilities,datetime=datetime)
print(instance)
return instance
Это решение вроде бы большое, но очень гибкое, потому что дает вам возможность добавить больше бизнес-логики вокруг входных и ожидаемых данных в модели или источнике данных.