Django DRF сериализаторы, как добавить новое поле, слияние двух моделей?

У меня есть две модели, мне нужно сделать конечную точку, где в json должны появляться результаты двух таблиц, которые имеют fongeringkey, объединяющий их.

Мой код следующий: models.py

class Property(models.Model):
    address = models.CharField(max_length=120)
    city = models.CharField(max_length=32)
    price = models.BigIntegerField()
    description = models.TextField(blank=True, null=True)
    year = models.IntegerField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'property'

class StatusHistory(models.Model):
    property = models.ForeignKey(Property, on_delete=models.CASCADE)
    status = models.ForeignKey(Status, on_delete=models.CASCADE)
    update_date = models.DateTimeField()

    class Meta:
        managed = False
        db_table = 'status_history'

views.py

class StandardResultsSetPagination(PageNumberPagination):
    page_size = 10
    page_size_query_param = "page_size"
    max_page_size = 1000

class PropertyListView(viewsets.ModelViewSet):
    http_method_names = ['get', 'head']
    serializer_class = PropertyListSerializer
    queryset = Property.objects.all()
    pagination_class = StandardResultsSetPagination

    def get_serializer_class(self):
        if self.action == 'list':
            return PropertyListSerializer
        return PropertyListSerializer

    def get_queryset(self):
        queryset = Property.objects.all()
        if self.request.GET.get('year'):
            queryset = queryset.filter(year=self.request.GET.get('year'))
        if self.request.GET.get('city'):
            queryset = queryset.filter(city=self.request.GET.get('city'))
        if self.request.GET.get('status'):
            queryse = queryset.filter(statushistory__status=self.request.GET.get('status'))            
        else:
            queryset = queryset.order_by('-year')
        return queryset

    def list(self, request):
        queryset = self.filter_queryset(self.get_queryset())
        page = self.paginate_queryset(queryset)
        
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
            
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

serializers.py

class PropertyListSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Property
        fields = ('id', 'address', 'city', 'price', 'description', 'year')

class StatusHistoryListSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = StatusHistory
        fields = ('property', 'status', 'update_date')

Я могу правильно отфильтровать параметры, город, год (модель Property) и, прежде всего, статус (модель StatusHistory) с помощью следующего фрагмента кода:

if self.request.GET.get('status'):
            queryset = queryset.filter(statushistory__status=self.request.GET.get('status'))

Моя проблема в том, как мне показать в моем JSON-ответе слияние новых полей двух моделей statushistory__status попробуйте добавить следующее в serializers.py

class PropertyListSerializer(serializers.HyperlinkedModelSerializer):
    statushistory_set =StatusHistoryListSerializer(many=True)
    class Meta:
        model = Property
        fields = ('id', 'address', 'city', 'price', 'description', 'year', 'statushistory_set')

class StatusHistoryListSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = StatusHistory
        fields = ('property', 'status', 'update_date')

Безрезультатно.

Я думаю, вы можете установить атрибут related_name в поле внешнего ключа.

class StatusHistory(models.Model):
    property = models.ForeignKey(Property, on_delete=models.CASCADE, related_name = 'status_histories')
    status = models.ForeignKey(Status, on_delete=models.CASCADE)
    ...

А в PropertyListSerializer,

class PropertyListSerializer(serializers.HyperlinkedModelSerializer):
    status_histories = StatusHistoryListSerializer(many=True, read_only = True)

    class Meta:
        model = Property
        fields = ('id', 'address', 'city', 'price', 'description', 'year', 'status_histories')

Вы также можете получить поле property как объект в StatusHistory следующим образом:

class StatusHistoryListSerializer(serializers.HyperlinkedModelSerializer):
    property = PropertyListSerializer(read_only = True)

    class Meta:
        model = StatusHistory
        fields = ('property', 'status', 'update_date')
Вернуться на верх