Shift 'n Tab
Shift 'n Tab

Reputation: 9443

Cannot get distinct record - Django w / Rest Framework

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 serializer AnimalSerializer.\nThe serializer field might be named incorrectly and not match any attribute or key on the dict instance.\nOriginal exception text was: u'this_id'."

Upvotes: 6

Views: 6630

Answers (1)

e4c5
e4c5

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

Related Questions