django-rest: TypeError: unhashable type: 'list'

1.6k Views Asked by At

I am trying to restify my backend using django-rest-gis, in such a way that POST request adds data to database and GET request lists down the data. However, I am getting following error:-

Internal Server Error: /api/
Traceback (most recent call last):
  File "/home/vineet/env-tsl/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/home/vineet/env-tsl/lib/python3.6/site-packages/django/core/handlers/base.py", line 126, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/vineet/env-tsl/lib/python3.6/site-packages/django/core/handlers/base.py", line 124, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/vineet/env-tsl/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/home/vineet/env-tsl/lib/python3.6/site-packages/django/views/generic/base.py", line 68, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework/views.py", line 495, in dispatch
    response = self.handle_exception(exc)
  File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework/views.py", line 455, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework/views.py", line 492, in dispatch
    response = handler(request, *args, **kwargs)
  File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework/generics.py", line 241, in get
    return self.list(request, *args, **kwargs)
  File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework/mixins.py", line 48, in list
    return Response(serializer.data)
  File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework_gis/serializers.py", line 20, in data
    return super(ListSerializer, self).data
  File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework/serializers.py", line 262, in data
    self._data = self.to_representation(self.instance)
  File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework_gis/serializers.py", line 28, in to_representation
    ("features", super(GeoFeatureModelListSerializer, self).to_representation(data))
  File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework/serializers.py", line 686, in to_representation
    self.child.to_representation(item) for item in iterable
  File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework/serializers.py", line 686, in <listcomp>
    self.child.to_representation(item) for item in iterable
  File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework_gis/serializers.py", line 100, in to_representation
    fields = list(self.fields.values())
  File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework/serializers.py", line 363, in fields
    for key, value in self.get_fields().items():
  File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework/serializers.py", line 1031, in get_fields
    field_names, declared_fields, extra_kwargs
  File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework/serializers.py", line 1378, in get_uniqueness_extra_kwargs
    field_names, declared_fields, extra_kwargs
  File "/home/vineet/env-tsl/lib/python3.6/site-packages/rest_framework/serializers.py", line 1450, in _get_model_fields
    if field_name in declared_fields:
TypeError: unhashable type: 'list'
[25/May/2019 04:48:29] "GET /api/ HTTP/1.1" 500 147185

I have followed many answers on stackoverflow but could only get that it comes when you have a mutable type as key in dictionary

models.py

from django.contrib.gis.db import models


# Create your models here.

class test1(models.Model):

    date = models.DateTimeField(auto_now_add=True, null=True, blank=True)
    location = models.PointField(blank=False)
    plg = models.PolygonField(srid=4326, geography=True, null=True, blank=True)
    city = models.CharField(max_length=50, blank=False)
    state = models.CharField(max_length=50, blank=False)


    def __str__(self):
        return "%s" % (self.state)

serializers.py

from rest_framework_gis.serializers import GeoFeatureModelSerializer
from .models import test1


class test1Serializer(GeoFeatureModelSerializer):
    class Meta:
        model = test1
        geo_field = ['location','plg']
        auto_bbox = True
        id_field = False

        fields = ('city','state')

views.py

from .models import test1
from .serializers import test1Serializer
from rest_framework.generics import ListCreateAPIView

class test1SerializerCreate(ListCreateAPIView):
    serializer_class = test1Serializer
    queryset = test1.objects.all()
2

There are 2 best solutions below

0
Sanjay Kumar On

GeoFeatureModelSerializer only takes one field and it doesn't take the list, check with one field and it should work. Use Rest for multiple fields and you can parse in views. Or you can make a new GeometrySerializerMethodField field and return two geometry in that

0
Avinash On

geo_field cannot be list.

It can be this way:

class test1Serializer(GeoFeatureModelSerializer):
    m_geo_field = GeometrySerializerMethodField()

    def get_m_geo_field(self, obj):
        return # do whatever you like

    class Meta:
        model = Location
        geo_field = 'm_geo_field'