1

I have two models, I have to make an endpoint where the results of two tables should appear in the json, which have a fongeringkey that joins them.

My code is the following: 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')

I can correctly filter the parameters, city, year(model Property) and above all status(model StatusHistory) with the following code snippet:

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

My problem is how I show in my JSON Response the new field fusion of the two models statushistory__statustry adding the following in 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')

Without any result.

laur
  • 500
  • 1
  • 9
  • 23

1 Answers1

1

I think you could set related_name attribute in the foreign key field.

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

And in the 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')

You can also get property field as an object in the StatusHistory like the following:

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

    class Meta:
        model = StatusHistory
        fields = ('property', 'status', 'update_date')
Metalgear
  • 3,391
  • 1
  • 7
  • 16