Reputation: 9443
I define this viewset
and i would like to create a custom function that returns distinct of animals species_type
called distinct_species
.
class AnimalViewSet(viewsets.ModelViewSet):
"""
This viewset automatically provides `list`, `create`, `retrieve`,
`update` and `destroy` actions.
"""
queryset = Animal.objects.all()
serializer_class = AnimalSerializer
@list_route()
def distinct_species(self, request):
query_set = Animal.objects.values('species_type').distinct()
serializer = self.get_serializer(query_set, many=True)
return Response(serializer.data)
This is my Animal
model
class Animal(models.Model):
this_id = models.CharField(max_length=25)
name = models.CharField(max_length=25)
species_type = models.CharField(max_length=25)
breed = models.CharField(max_length=25)
....
This is my AnimalSerializer
class AnimalSerializer(serializers.ModelSerializer):
class Meta:
model = Animal
fields = (
'this_id',
'name',
'species_type',
'breed',
...
)
read_only_fields = ('id', 'created_at', 'updated_at')
I register the route here.
# Create a router and register our viewsets with it.
router = DefaultRouter()
router.register(r'animal', AnimalViewSet)
urlpatterns = [
url(r'^api/', include(router.urls)),
url(r'^', IndexView.as_view(), name='index'),
]
But when i do this /api/animal/distinct_species/
I got this KeyError:
u"Got KeyError when attempting to get a value for field
this_id
on serializerAnimalSerializer
.\nThe serializer field might be named incorrectly and not match any attribute or key on thedict
instance.\nOriginal exception text was: u'this_id'."
Upvotes: 6
Views: 6630
Reputation: 53734
The trouble stems from this one:
query_set = Animal.objects.values('species_type').distinct()
Your query_set
object now a list of dictionaries. The dictionary contains exactly one field - species_type
[{'species_type': 'a'},{'species_type': 'b'},...]
Thus it does not have a this_id
which your serializer requires. If you were on postgresql, you could change your query to
query_set = Animal.objects.distinct('species_type')
Second option is to list all the fields required by the serializer in the values
() call
Third option is to create a different serializer for use by the distinct_species
end point this serializer will not be a ModelSerializer
Upvotes: 11