简体   繁体   中英

DRF Response returning all fields when using queryset method only

I'm doing a university project that requires me to implement a Web App using an API as backend and I've decided to use DRF to do it but I'm having some troubles right now.

I'm trying to override the list method in View to only show some fields when retrieving the list of all airports' records but still all fields are being returned in the Response.

Model:

class Airport(models.Model):
    code = models.CharField(max_length=10)
    name = models.TextField()
    carriers = models.ManyToManyField(Carrier, related_name='airports')

    def __str__(self):
        return self.name

Serializer:

class AirportSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = models.Airport
        fields = ('id', 'name', 'code', 'url', 'carriers')

View:

class AirportView(viewsets.ModelViewSet):
    queryset = models.Airport.objects.all()
    serializer_class = AirportSerializer

    def list(self, request):
        airports = models.Airport.objects.only('id', 'name', 'code')
        data = AirportSerializer(airports, many=True, context={'request': request}).data
        return Response(data)

Response:

{
        "id": 4,
        "name": "Leo",
        "code": "Test",
        "url": "http://localhost:8000/api/airports/4/",
        "carriers": []
    },
    {
        "id": 5,
        "name": "asdasd",
        "code": "aasdasd",
        "url": "http://localhost:8000/api/airports/5/",
        "carriers": [
            "http://localhost:8000/api/carriers/1/"
        ]
    },
    {
        "id": 6,
        "name": "asdasd",
        "code": "aasdasd",
        "url": "http://localhost:8000/api/airports/6/",
        "carriers": [
            "http://localhost:8000/api/carriers/1/"
        ]
    }

How can I solve this? Is there a better way to do it, I mean not using QuerySet.only method?

您应该定义一个单独的序列化器并返回它。

It is the serializer that defines how objects are serialized, not how you filter the data from the database. Currently, you have all fields available in the serializer. If you do not want some fields to be returned while listing or retrieving items, you can define those fields in the serializer as write_only , like this:

class AirportSerializer(serializers.HyperlinkedModelSerializer):
    url = serializer.CharField(write_only=True)
    carriers = serializer.PrimaryKeyRelatedField(many=True, write_only=True)

    class Meta:
        model = models.Airport
        fields = ('id', 'name', 'code', 'url', 'carriers')

This way, url and carriers fields will not be present when data is returned, but will be required while inserting data.

just put the field which want in your serializer like that:

class AirportSerializer(serializers.HyperlinkedModelSerializer):
  class Meta:
     model = models.Airport
    fields = ('id', 'name', 'code')

You are good to go.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM