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 = RoomSerializer(source='room_set', many=True)
class Meta:
model = Listing
fields = '__all__'
В source=…
следует указать related_name=…
из ForeignKey
в Room
модели. Если вы не указали related_name=…
, по умолчанию используется modelname_set
, поэтому здесь room_set
.