Search code examples
pythonsqldjangodjango-rest-frameworktraceback

django returning url kwarg string used for filtering as an int, trying to use as pk


Observe the url below

http://127.0.0.1:8000/api/neighborhood-list/chicago/

this url is tied to a resource that will return a list of all the neighborhoods in a city.

However I am currently getting this error:

    invalid literal for int() with base 10: 'chicago'
Exception Location: /home/rickus/211hospitality/suitsandtables/backend/venv/local/lib/python2.7/site-packages/django/db/models/fields/__init__.py in get_prep_value, line 966

line 966: return int(value)

Now I have already asked this question here: invalid literal for int() with base ten in listAPI view django rest framework

and have implemented the suggestions but I am still fighting the django framework it seems. It looks like the Django framework is defaulting to trying to use my key word url agrument as a primary key

here is my url, view, serializer, and model code

url:

  url(r'^neighborhood-list/(?P<city>[a-zA-Z]+)/$', NeighborhoodListView.as_view(),
name='neighborhood-list',
    )

view:

class NeighborhoodListView(generics.ListAPIView):
queryset = Neighborhood.objects.all()
serializer_class = NeighborhoodSerializer(queryset, many=True)

def get_queryset(self):
    return self.queryset.filter(city=self.kwargs.get('city'))

serializer:

class NeighborhoodSerializer(serializers.ModelSerializer):
    class Meta:
        model = Neighborhood
        fields = 'neighborhood'

model:

class  Neighborhood(models.Model):
city = models.ForeignKey(City, null=True)
neighborhood = models.CharField(max_length=150, null=False)

and if you so wish here is the full print out of the traceback which I think is going to be needed:

  Environment:


Request Method: GET
Request URL: http://127.0.0.1:8000/api/neighborhood-list/chicago/

Django Version: 1.11.2
Python Version: 2.7.12
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'rest_framework',
 'venue.apps.VenueConfig']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "/home/rickus/211hospitality/suitsandtables/backend/venv/local/lib/python2.7/site-packages/django/core/handlers/exception.py" in inner
  41.             response = get_response(request)

File "/home/rickus/211hospitality/suitsandtables/backend/venv/local/lib/python2.7/site-packages/django/core/handlers/base.py" in _get_response
  187.                 response = self.process_exception_by_middleware(e, request)

File "/home/rickus/211hospitality/suitsandtables/backend/venv/local/lib/python2.7/site-packages/django/core/handlers/base.py" in _get_response
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/home/rickus/211hospitality/suitsandtables/backend/venv/local/lib/python2.7/site-packages/django/views/decorators/csrf.py" in wrapped_view
  58.         return view_func(*args, **kwargs)

File "/home/rickus/211hospitality/suitsandtables/backend/venv/local/lib/python2.7/site-packages/django/views/generic/base.py" in view
  68.             return self.dispatch(request, *args, **kwargs)

File "/home/rickus/211hospitality/suitsandtables/backend/venv/local/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
  489.             response = self.handle_exception(exc)

File "/home/rickus/211hospitality/suitsandtables/backend/venv/local/lib/python2.7/site-packages/rest_framework/views.py" in handle_exception
  449.             self.raise_uncaught_exception(exc)

File "/home/rickus/211hospitality/suitsandtables/backend/venv/local/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
  486.             response = handler(request, *args, **kwargs)

File "/home/rickus/211hospitality/suitsandtables/backend/venv/local/lib/python2.7/site-packages/rest_framework/generics.py" in get
  201.         return self.list(request, *args, **kwargs)

File "/home/rickus/211hospitality/suitsandtables/backend/venv/local/lib/python2.7/site-packages/rest_framework/mixins.py" in list
  40.         queryset = self.filter_queryset(self.get_queryset())

File "/home/rickus/211hospitality/suitsandtables/backend/suitsandtables/venue/views.py" in get_queryset
  50.         return self.queryset.filter(city=self.kwargs.get('city'))

File "/home/rickus/211hospitality/suitsandtables/backend/venv/local/lib/python2.7/site-packages/django/db/models/query.py" in filter
  784.         return self._filter_or_exclude(False, *args, **kwargs)

File "/home/rickus/211hospitality/suitsandtables/backend/venv/local/lib/python2.7/site-packages/django/db/models/query.py" in _filter_or_exclude
  802.             clone.query.add_q(Q(*args, **kwargs))

File "/home/rickus/211hospitality/suitsandtables/backend/venv/local/lib/python2.7/site-packages/django/db/models/sql/query.py" in add_q
  1261.         clause, _ = self._add_q(q_object, self.used_aliases)

File "/home/rickus/211hospitality/suitsandtables/backend/venv/local/lib/python2.7/site-packages/django/db/models/sql/query.py" in _add_q
  1287.                     allow_joins=allow_joins, split_subq=split_subq,

File "/home/rickus/211hospitality/suitsandtables/backend/venv/local/lib/python2.7/site-packages/django/db/models/sql/query.py" in build_filter
  1217.             condition = lookup_class(lhs, value)

File "/home/rickus/211hospitality/suitsandtables/backend/venv/local/lib/python2.7/site-packages/django/db/models/lookups.py" in __init__
  24.         self.rhs = self.get_prep_lookup()

File "/home/rickus/211hospitality/suitsandtables/backend/venv/local/lib/python2.7/site-packages/django/db/models/fields/related_lookups.py" in get_prep_lookup
  112.                 self.rhs = target_field.get_prep_value(self.rhs)

File "/home/rickus/211hospitality/suitsandtables/backend/venv/local/lib/python2.7/site-packages/django/db/models/fields/__init__.py" in get_prep_value
  966.         return int(value)

Exception Type: ValueError at /api/neighborhood-list/chicago/
Exception Value: invalid literal for int() with base 10: 'chicago'

Solution

  • Your problem is here:

    self.queryset.filter(city=self.kwargs.get('city'))
    

    city is a foreign key to City, which is matched by its id property (an integer). You are trying to match it with 'chicago' which obviously fails as an integer, hence the exception.

    You have two options here, either refer to the city name:

    self.queryset.filter(city__name=self.kwargs.get('city'))
    

    Or fetch the City object first:

    city = City.objects.filter(name__contains=self.kwargs.get('city')).first()
    self.queryset.filter(city=city)
    

    I am using a filter here, a .get() would raise an exception if the city was not found.