I am using a view in django rest framework. In this view it takes an argument city
to then fetch a list a neighborhoods in that city.
the example of the url looks like this:
http://127.0.0.1:8000/api/neighborhood-list/chicago/
the url code looks like this:
url(r'neighborhood-list/(?P<city>[a-zA-Z]+)/', VenueFilterOptionsView.as_view()),
the view:
class NeighborhoodListView(generics.ListAPIView):
lookup_field = 'city'
def list(self, request, city):
self.city = city
queryset = Neighborhood.objects.filter(city=self.city)
serializer = NeighborhoodSerializer(queryset, many=True)
the serializer:
class NeighborhoodSerializer(serializers.ModelSerializer):
class Meta:
model = Neighborhood
fields = 'neighborhood'
the model:
class Neighborhood(models.Model):
city = models.ForeignKey(City, null=True)
neighborhood = models.CharField(max_length=150, null=False)
what I don't understand is I set the lookup field to city, unless that only works for instances not lists? And even so I am using the listAPIView
generic
the exception location is here:
/home/rickus/211hospitality/suitsandtables/backend/venv/local/lib/python2.7/site-packages/django/db/models/fields/__init__.py in get_prep_value, line 966
and the code on line 966 is the following:
def get_prep_value(self, value):
value = super(AutoField, self).get_prep_value(value)
if value is None:
return None
return int(value)
the return value of this method in the init folder being referenced by the stack trace is being cast as an int every time. SO I guess now the question is how do we override this nonsense or work around it.
so now I am working my way back trying to figure out what is going on.
anyone have any ideas?
Update - My original answer was incorrect. List view doesn't actually work with the lookup_field
and lookup_url_kwarg
attributes, those attributes are used by Rest Frameworks DetailView in the get_object(self)
method to retrieve a single instance using those lookup fields.
I've updated the answer so it overrides the get_queryset(self)
method to return the correctly filtered list. This is how ListView should be customised.
It looks like you haven't defined your ListView properly. The problem seems to be that you are trying to filter on the Cities Primary Key, which is an integer field, using a string that can't be parsed as an integer. I'll write up how I think your view should look presuming your trying to do your filtering based on some field on the City model.
# models.py
class City(models.Model):
name = models.CharField(max_length=32)
class Neighbourhood(models.Model):
city = models.ForeignKey(City)
# views.py
class NeighbourhoodListView(generics.ListAPIView):
queryset = Neighbourhood.objects.all()
serializer_class = NeighbourhoodSerializer
def get_queryset(self):
return self.queryset.filter(city__name=self.kwargs.get('city')
# urls.py
urlpatterns = [
url(
r'^neighbourhood-list/(?P<city>[a-zA-Z]+)/$',
NeighbourhoodListView.as_view(),
name='neighbourhood-list',
)
]
This will filter your Neighbourhoods by the Cities name. If you want to filter Neighbourhoods by the cities Primary Key, then you should use:
# views.py
class NeighbourhoodListView(generics.ListAPIView):
queryset = Neighbourhood.objects.all()
serializer_class = NeighbourhoodSerializer
def get_queryset(self):
return self.queryset.filter(city=self.kwargs.get('city'))
# urls.py
urlpatterns = [
url(
r'^neighbourhood-list/(?P<city>\d+)/$',
NeighbourhoodListView.as_view(),
name='neighbourhood-list',
)
]
This fixes the view and url's to filter Neighbourhoods by the Cities Primary Key. This would be more performant because it doesn't need to perform a join between City and Neighbourhood.