Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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'."

like image 964
Roel Avatar asked Nov 14 '16 03:11

Roel


People also ask

How do you pass extra context data to Serializers in Django REST framework?

In function-based views, we can pass extra context to serializer with “context” parameter with a dictionary. To access the extra context data inside the serializer we can simply access it with “self. context”. From example, to get “exclude_email_list” we just used code 'exclude_email_list = self.

How do you save a foreign key field in Django REST framework?

Your code is using serializer only for validation, but it is possible use it to insert or update new objects on database calling serializer. save() . To save foreign keys using django-rest-framework you must put a related field on serializer to deal with it. Use PrimaryKeyRelatedField .


1 Answers

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

like image 115
e4c5 Avatar answered Sep 24 '22 23:09

e4c5