How do we define @list_route that accept arguments

2019-07-04 03:32发布

问题:

In my application i have this ModelViewSet with one @list_route() defined function for getting list but with different serializer.

class AnimalViewSet(viewsets.ModelViewSet):
    """
    This viewset automatically provides `list`, `create`, `retrieve`,
    `update` and `destroy` actions.
    """
    queryset = Animal.objects.all()
    serializer_class = AnimalSerializer // Default modelviewset serializer

    lookup_field = 'this_id'

    @list_route()
    def listview(self, request):
        query_set = Animal.objects.all()
        serializer = AnimalListingSerializer(query_set, many=True) // Serializer with different field included.
         return Response(serializer.data)

The Default AnimalViewSet with this /api/animal/ end point yield this serialized data result as based on AnimalSerializer definition.

{
    "this_id": "1001",
    "name": "Animal Testing 1",
    "species_type": "Cow",
    "breed": "Brahman",
    ...
    "herd": 1
},
{
    "this_id": "1004",
    "name": "Animal Testing 2",
    "species_type": "Cow",
    "breed": "Holstien",
    ....
    "herd": 1
},
{
    "this_id": "1020",
    "name": "Animal Testing 20",
    "species_type": "Cow",
    "breed": "Brahman",
    ....
    "herd": 4
},

And the other one which is a @list_route() defined function named listview may have this end point /api/animal/listview/ which yields this result as defined in AnimalListingSerializer structure.

{
    "this_id": "1001",
    "name": "Animal Testing 1",
    "species_type": "Cow",
    "breed": "Brahman",
    ....
    "herd": {
        "id": 1,
        "name": "High Production",
        "description": null
    }
},
{
    "this_id": "1004",
    "name": "Animal Testing 2",
    "species_type": "Cow",
    "breed": "Holstien",
    ....
    "herd": {
        "id": 1,
        "name": "High Production",
        "description": null
    }
},
{
    "this_id": "1020",
    "name": "Animal Testing 20",
    "species_type": "Cow",
    "breed": "Brahman",
    ....
    "herd": {
        "id": 4,
        "name": "Bad Production",
        "description": "Bad Production"
    }
}

Now what i am trying to do is i want to define another @list_route() function that takes an argument and uses AnimalListingSerializer in order to filter the query_set result of the model object. A work around my help for a beginner like us.

@list_route()
def customList(self, request, args1, args2):
        query_set = Animal.objects.filter(species_type=args1, breed=args2)
        serializer = AnimalListingSerializer(query_set, many=True)
         return Response(serializer.data)

Let us assumed that args1 = "Cow" and args2 = "Brahman". And i am expecting this result.

{
    "this_id": "1001",
    "name": "Animal Testing 1",
    "species_type": "Cow",
    "breed": "Brahman",
    ....
    "herd": {
        "id": 1,
        "name": "High Production",
        "description": null
    }
},
{
    "this_id": "1020",
    "name": "Animal Testing 20",
    "species_type": "Cow",
    "breed": "Brahman",
    ....
    "herd": {
        "id": 4,
        "name": "Bad Production",
        "description": "Bad Production"
    }
},

But i know my syntax is wrong, but that is what i am talking about. Please help.

回答1:

parameters in the view function are reserved for URL references. ie the route animals/5 would be passed to a view function that has pk as an argument.

def get(self, request, pk):
    # get animal with pk
    return animal with pk

You can pass parameters to your url via a query param ie

/animals/listview/?speceis_type=cow&breed=braham

then access it in your view using the request object request.query_params['speceis_type'] and request.query_params['braham'] or you can use the django rest filter middleware that is documented here