我正在努力使用创建的可写嵌套序列化程序来更新记录。
我正在创建的分类应用程序有许多Listing
类别,每个类别都有一些独特的属性,但是它们也共享许多属性。我有几个从父Listing
模型继承的django模型,其中一个模型Battery
包含一些嵌套数据。到目前为止,我已经能够创建Battery
记录,但是在尝试更新它们时始终会出现AttributeErrors。
我尝试仅包含相关代码。这是我的观点:
# views.py
class ListingCreateView(CreateAPIView):
queryset = Listing.objects.all()
def get_serializer_class(self):
category = self.request.data['category']
if category == 1:
return PercussionSerializer
elif category == 6:
return BatterySerializer
return ListingSerializer
class ListingUpdateView(UpdateAPIView):
queryset = Listing.objects.all()
def get_serializer_class(self):
category = self.request.data['category']
if category == 1:
return PercussionSerializer
elif category == 6:
return BatterySerializer
return ListingSerializer
这是我的模特:
# models.py
## Parent model
class Listing(models.Model):
title = models.CharField(max_length=100)
description = models.TextField(blank=True)
price = models.DecimalField(max_digits=9, decimal_places=2, blank=True, null=True, default=0.00)
## One of the child models
class Battery(Listing):
model_name = models.TextField(blank=True, null=True, default="")
color = models.ForeignKey(Color, on_delete=models.CASCADE, blank=True, null=True)
manufacture_year = models.IntegerField(null=True)
## Model for the nested data in Battery model
class Drum(models.Model):
drum_type = models.CharField(max_length=50, blank=True)
size = models.TextField(blank=True, null=True, default="")
battery = models.ForeignKey(Battery, related_name='drums', on_delete=models.CASCADE, null=True)
这是我的序列化器:
# serializers.py
class ListingSerializer(serializers.ModelSerializer):
class Meta:
model = Listing
fields = '__all__'
class DrumSerializer(serializers.ModelSerializer):
class Meta:
model = Drum
fields = ['drum_type', 'size', 'carrier', 'stand', 'cover', 'case', 'sold']
class BatterySerializer(serializers.ModelSerializer):
drums = DrumSerializer(many=True)
class Meta:
model = Battery
fields = ['id', 'title', 'description', 'price', 'model_name', 'color', 'manufacture_year', 'drums']
def create(self, validated_data):
drum_data = validated_data.pop('drums')
battery = Battery.objects.create(**validated_data)
for drum_data in drum_data:
Drum.objects.create(battery=battery, **drum_data)
return battery
def update(self, instance, validated_data):
# Update Listing field values
instance.title = validated_data.get('title', instance.title)
instance.description = validated_data.get('description', instance.description)
instance.price = validated_data.get('price', instance.price)
# Grab the Battery record for this Listing and update its values
instance_battery = Battery.objects.get(pk=instance.pk)
instance_battery.model_name = validated_data.get('model_name', instance_battery.model_name)
instance_battery.color = validated_data.get('color', instance_battery.color)
instance_battery.manufacture_year = validated_data.get('manufacture_year', instance_battery.manufacture_year)
# Check for a list of drums
drum_data = validated_data.pop('drums')
# If it exists
if drum_data:
# Clear the existing drums
instance_battery.drums.clear()
# Create new drums
Drum.objects.bulk_create(
[
Drum(**drum)
for drum in drum_data
],
)
# Save the updated Listing & Battery
instance.save()
instance_battery.save()
# Return the updated Battery
return instance
我觉得我已经遵循有关writeable nested serializers correctly的DRF文档,但是当我尝试将更新发布到Battery
记录时,我仍然收到此AttributeError的错误:
AttributeError:尝试获取序列化程序
drums
上字段BatterySerializer
的值时,出现AttributeError。 序列化程序字段的名称可能不正确,并且与Listing
实例上的任何属性或键都不匹配。 原始的异常文本为:“列表”对象没有属性“鼓”。
从错误消息来看,我认为Django模型继承需要DRF文档提供的更具体的解决方案。有人可以帮助我了解如何创建序列化程序吗,我需要创建/更新从Battery
模型继承的Listing
记录中嵌套Drum
个记录的列表的一个export const widgetsByColor = createSelector(
(t: Widget[], props: { color: string }) => t.widgets, (state, props) => {
return t.widgets.filter(w => w.color == props.color)[0];
}
);
记录吗?
谢谢!
答案 0 :(得分:0)
我认为出现问题是因为视图等待清单实例。我可以提出以下建议:尝试重新定义def get_qyeryset(self)
例如:
class ListingUpdateView(UpdateAPIView):
def get_queryset(self):
if self.request.data['category'] == 6:
return Battery.objects.all()
else:
return Listing.objects.all()
def get_serializer_class(self):
category = self.request.data['category']
if category == 1:
return PercussionSerializer
elif category == 6:
return BatterySerializer
return ListingSerializer
也许这不是最好的方法,但是它可以解决您的问题