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 模型中 ForeignKeyrelated_name=…。如果没有指定related_name=…,默认是<i>modelname</i>_set,所以这里room_set.