REST Framework 中相关对象的问题
Problem with related objects in REST Framework
我有一个简单的 django 应用程序,具有以下模型:
class Product(models.Model):
__metaclass__ = ABCMeta
title = models.CharField(max_length=50)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
slug = models.SlugField(max_length=100, unique=True)
price = models.IntegerField()
is_published = models.BooleanField(default=True)
@abstractmethod
def __str__(self):
pass
@abstractmethod
def get_absolute_url(self):
pass
class SupplyType(models.Model):
title = models.CharField(max_length=10)
slug = models.SlugField(max_length=100, unique=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('supply_type_detail', kwargs={'slug': self.slug})
class Processor(Product):
supply_type = models.ForeignKey(SupplyType, on_delete=models.CASCADE)
cores_amount = models.IntegerField()
threads_amount = models.IntegerField()
technological_process = models.IntegerField()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('processor_detail', kwargs={'slug': self.slug})
为它们编写了相应的序列化程序:
class SupplyTypeSerializer(ModelSerializer):
class Meta:
model = SupplyType
fields = '__all__'
class ProcessorSerializer(ModelSerializer):
class Meta:
model = Processor
fields = '__all__'
depth = 1
也写了相应的观点(我只举创作的观点举例):
class ProcessorCreateAPIView(CreateAPIView):
model = Processor
serializer_class = ProcessorSerializer
class SupplyTypeCreateAPIView(CreateAPIView):
model = SupplyType
serializer_class = SupplyTypeSerializer
当我尝试使用 POST 请求添加“供应类型”时,它成功运行。
但是,当我尝试添加这样的处理器时:
{
"title": "Intel Pentium Gold G6400",
"slug": "intel-pentium-gold-g6400",
"price": 19690,
"is_published" : true,
"cores_amount": 2,
"threads_amount": 4,
"technological_process": 14,
"supply_type": 1
}
我得到一个错误:
django.db.utils.IntegrityError:关系“store_processor”的列“supply_type_id”中的空值违反了非空约束
详细信息:失败的行包含 (1, 2, 4, 14, null).
最终,存在以下问题:如何解决这个问题,以及如何在这种情况下通过 API(仍然通过 id)或其他方式添加具有所需电源类型的处理器方式?
因此,当我做一个 GET 请求时,我想得到这样的东西:
{
"title": "Intel Pentium Gold G6400",
"slug": "intel-pentium-gold-g6400",
"price": 19690,
"is_published" : true,
"cores_amount": 2,
"threads_amount": 4,
"technological_process": 14,
"supply_type":
{
"id": 1,
"title": "OEM",
"slug": "oem"
}
是的,对不起我的英语。
您需要使用嵌套序列化程序的概念。见下面代码
class ProcessorSerializer(ModelSerializer):
supply_type = SupplyTypeSerializer()
class Meta:
model = Processor
fields = '__all__'
因此,当您执行 GET 请求时,您会得到如下内容:
{
"title": "Intel Pentium Gold G6400",
"slug": "intel-pentium-gold-g6400",
"price": 19690,
"is_published" : true,
"cores_amount": 2,
"threads_amount": 4,
"technological_process": 14,
"supply_type": {
"id": 1,
"title": "OEM",
"slug": "oem"
}
}
为了创建处理器,您必须传递 supply_type dict 对象,类似于您在输出中获得的对象。但是由于您想传递 supply_type id,您可以按如下方式覆盖 to_internal_value 方法并设置 supply_type 字段为 read_only:
def to_internal_value(self, data):
supply_type_id = data.get('supply_type')
internal_data = super().to_internal_value(data)
try:
supply_type = SupplyType.objects.get(id=supply_type_id)
except SupplyType.DoesNotExist:
raise serializers.ValidationError(
{'supply_type': ['Item does not exist']},
)
internal_data['supply_type'] = supply_type
return internal_data
现在您可以像这样创建一个处理器:
{
"title": "Intel Pentium Gold G6400",
"slug": "intel-pentium-gold-g6400",
"price": 19690,
"is_published" : true,
"cores_amount": 2,
"threads_amount": 4,
"technological_process": 14,
"supply_type": 1
}
最终代码:
class ProcessorSerializer(serializers.ModelSerializer):
supply_type = SupplyTypeSerializer(read_only=True)
class Meta:
model = Processor
fields = '__all__'
def to_internal_value(self, data):
supply_type_id = data.get('supply_type')
internal_data = super().to_internal_value(data)
try:
supply_type = SupplyType.objects.get(id=supply_type_id)
except SupplyType.DoesNotExist:
raise serializers.ValidationError(
{'supply_type': ['Item does not exist']},
)
internal_data['supply_type'] = supply_type
return internal_data
我有一个简单的 django 应用程序,具有以下模型:
class Product(models.Model):
__metaclass__ = ABCMeta
title = models.CharField(max_length=50)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
slug = models.SlugField(max_length=100, unique=True)
price = models.IntegerField()
is_published = models.BooleanField(default=True)
@abstractmethod
def __str__(self):
pass
@abstractmethod
def get_absolute_url(self):
pass
class SupplyType(models.Model):
title = models.CharField(max_length=10)
slug = models.SlugField(max_length=100, unique=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('supply_type_detail', kwargs={'slug': self.slug})
class Processor(Product):
supply_type = models.ForeignKey(SupplyType, on_delete=models.CASCADE)
cores_amount = models.IntegerField()
threads_amount = models.IntegerField()
technological_process = models.IntegerField()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('processor_detail', kwargs={'slug': self.slug})
为它们编写了相应的序列化程序:
class SupplyTypeSerializer(ModelSerializer):
class Meta:
model = SupplyType
fields = '__all__'
class ProcessorSerializer(ModelSerializer):
class Meta:
model = Processor
fields = '__all__'
depth = 1
也写了相应的观点(我只举创作的观点举例):
class ProcessorCreateAPIView(CreateAPIView):
model = Processor
serializer_class = ProcessorSerializer
class SupplyTypeCreateAPIView(CreateAPIView):
model = SupplyType
serializer_class = SupplyTypeSerializer
当我尝试使用 POST 请求添加“供应类型”时,它成功运行。
但是,当我尝试添加这样的处理器时:
{
"title": "Intel Pentium Gold G6400",
"slug": "intel-pentium-gold-g6400",
"price": 19690,
"is_published" : true,
"cores_amount": 2,
"threads_amount": 4,
"technological_process": 14,
"supply_type": 1
}
我得到一个错误:
django.db.utils.IntegrityError:关系“store_processor”的列“supply_type_id”中的空值违反了非空约束 详细信息:失败的行包含 (1, 2, 4, 14, null).
最终,存在以下问题:如何解决这个问题,以及如何在这种情况下通过 API(仍然通过 id)或其他方式添加具有所需电源类型的处理器方式?
因此,当我做一个 GET 请求时,我想得到这样的东西:
{
"title": "Intel Pentium Gold G6400",
"slug": "intel-pentium-gold-g6400",
"price": 19690,
"is_published" : true,
"cores_amount": 2,
"threads_amount": 4,
"technological_process": 14,
"supply_type":
{
"id": 1,
"title": "OEM",
"slug": "oem"
}
是的,对不起我的英语。
您需要使用嵌套序列化程序的概念。见下面代码
class ProcessorSerializer(ModelSerializer):
supply_type = SupplyTypeSerializer()
class Meta:
model = Processor
fields = '__all__'
因此,当您执行 GET 请求时,您会得到如下内容:
{
"title": "Intel Pentium Gold G6400",
"slug": "intel-pentium-gold-g6400",
"price": 19690,
"is_published" : true,
"cores_amount": 2,
"threads_amount": 4,
"technological_process": 14,
"supply_type": {
"id": 1,
"title": "OEM",
"slug": "oem"
}
}
为了创建处理器,您必须传递 supply_type dict 对象,类似于您在输出中获得的对象。但是由于您想传递 supply_type id,您可以按如下方式覆盖 to_internal_value 方法并设置 supply_type 字段为 read_only:
def to_internal_value(self, data):
supply_type_id = data.get('supply_type')
internal_data = super().to_internal_value(data)
try:
supply_type = SupplyType.objects.get(id=supply_type_id)
except SupplyType.DoesNotExist:
raise serializers.ValidationError(
{'supply_type': ['Item does not exist']},
)
internal_data['supply_type'] = supply_type
return internal_data
现在您可以像这样创建一个处理器:
{
"title": "Intel Pentium Gold G6400",
"slug": "intel-pentium-gold-g6400",
"price": 19690,
"is_published" : true,
"cores_amount": 2,
"threads_amount": 4,
"technological_process": 14,
"supply_type": 1
}
最终代码:
class ProcessorSerializer(serializers.ModelSerializer):
supply_type = SupplyTypeSerializer(read_only=True)
class Meta:
model = Processor
fields = '__all__'
def to_internal_value(self, data):
supply_type_id = data.get('supply_type')
internal_data = super().to_internal_value(data)
try:
supply_type = SupplyType.objects.get(id=supply_type_id)
except SupplyType.DoesNotExist:
raise serializers.ValidationError(
{'supply_type': ['Item does not exist']},
)
internal_data['supply_type'] = supply_type
return internal_data