django rest 框架序列化器方法字段如何
django rest framework serializer method field how to
如何处理这个序列化方法字段?我觉得使用 initial_data
是错误的,从数据库中提取数据时是否需要验证数据?从数据库中提取数据时是否需要使用序列化程序?
class ListingSerializer(serializers.ModelSerializer):
rooms = serializers.SerializerMethodField()
# This one works as expected
def get_rooms(self, obj):
rooms = list(Room.objects.filter(listing__id=obj.id).values())
serializer = RoomSerializer(data=rooms, many=True)
return serializer.initial_data
# This one gives serializer errors
def get_rooms(self, obj):
rooms = list(Room.objects.filter(listing__id=obj.id).values())
serializer = RoomSerializer(data=rooms, many=True)
if serializer.is_valid():
return serializer.data
return serializer.errors
class Meta:
model = Listing
fields = "__all__"
class Listing(models.Model):
id = models.CharField(
primary_key=True, default=generate_uuid, editable=False, max_length=36
)
agent = models.ForeignKey(
"users.User", on_delete=models.CASCADE, blank=True, null=True
)
# property data
title = models.CharField(max_length=100, blank=False, null=False)
description = models.CharField(max_length=1000, blank=False, null=False)
floor = models.IntegerField(blank=False, null=False)
floor_count = models.IntegerField(blank=False, null=False)
price = models.DecimalField(max_digits=10, decimal_places=2, default=Decimal(0.00))
# address
street = models.CharField(max_length=60, blank=False, null=True)
house_no = models.CharField(max_length=10, blank=False, null=True)
door_no = models.CharField(max_length=10, blank=False, null=True)
city = models.CharField(max_length=20, blank=False, null=True)
country = models.CharField(max_length=20, blank=False, null=True)
postal_code = models.IntegerField(blank=False, null=True)
# property reports
tilstand_report = models.FileField(upload_to="reports", blank=False, null=True)
water_consumption_report = models.FileField(
upload_to="reports", blank=False, null=True
)
energy_level_report = models.FileField(upload_to="reports", blank=False, null=True)
property_tax_report = models.FileField(upload_to="reports", blank=False, null=True)
# metadata
is_active = models.BooleanField(default=True)
create_time = models.BigIntegerField(blank=True, null=True)
def save(self, *args, **kwargs):
self.create_time = int(datetime.now().timestamp() * 1000)
super().save(*args, **kwargs)
class Meta:
ordering = ["create_time"]
您可以将 RoomSerializer
用作 子序列化程序:
class ListingSerializer(serializers.ModelSerializer):
rooms = <strong>RoomSerializer(source='room_set', many=True)</strong>
class Meta:
model = Listing
fields = '__all__'
source=…
应指定 Room
模型中 ForeignKey
的 related_name=…
。如果没有指定related_name=…
,默认是<i>modelname</i>_set
,所以这里room_set
.
如何处理这个序列化方法字段?我觉得使用 initial_data
是错误的,从数据库中提取数据时是否需要验证数据?从数据库中提取数据时是否需要使用序列化程序?
class ListingSerializer(serializers.ModelSerializer):
rooms = serializers.SerializerMethodField()
# This one works as expected
def get_rooms(self, obj):
rooms = list(Room.objects.filter(listing__id=obj.id).values())
serializer = RoomSerializer(data=rooms, many=True)
return serializer.initial_data
# This one gives serializer errors
def get_rooms(self, obj):
rooms = list(Room.objects.filter(listing__id=obj.id).values())
serializer = RoomSerializer(data=rooms, many=True)
if serializer.is_valid():
return serializer.data
return serializer.errors
class Meta:
model = Listing
fields = "__all__"
class Listing(models.Model):
id = models.CharField(
primary_key=True, default=generate_uuid, editable=False, max_length=36
)
agent = models.ForeignKey(
"users.User", on_delete=models.CASCADE, blank=True, null=True
)
# property data
title = models.CharField(max_length=100, blank=False, null=False)
description = models.CharField(max_length=1000, blank=False, null=False)
floor = models.IntegerField(blank=False, null=False)
floor_count = models.IntegerField(blank=False, null=False)
price = models.DecimalField(max_digits=10, decimal_places=2, default=Decimal(0.00))
# address
street = models.CharField(max_length=60, blank=False, null=True)
house_no = models.CharField(max_length=10, blank=False, null=True)
door_no = models.CharField(max_length=10, blank=False, null=True)
city = models.CharField(max_length=20, blank=False, null=True)
country = models.CharField(max_length=20, blank=False, null=True)
postal_code = models.IntegerField(blank=False, null=True)
# property reports
tilstand_report = models.FileField(upload_to="reports", blank=False, null=True)
water_consumption_report = models.FileField(
upload_to="reports", blank=False, null=True
)
energy_level_report = models.FileField(upload_to="reports", blank=False, null=True)
property_tax_report = models.FileField(upload_to="reports", blank=False, null=True)
# metadata
is_active = models.BooleanField(default=True)
create_time = models.BigIntegerField(blank=True, null=True)
def save(self, *args, **kwargs):
self.create_time = int(datetime.now().timestamp() * 1000)
super().save(*args, **kwargs)
class Meta:
ordering = ["create_time"]
您可以将 RoomSerializer
用作 子序列化程序:
class ListingSerializer(serializers.ModelSerializer):
rooms = <strong>RoomSerializer(source='room_set', many=True)</strong>
class Meta:
model = Listing
fields = '__all__'
source=…
应指定 Room
模型中 ForeignKey
的 related_name=…
。如果没有指定related_name=…
,默认是<i>modelname</i>_set
,所以这里room_set
.