In an attempt to write object level permissions in Django with the Django Rest Framework, I have bumped into this error (full error log at bottom)
django.core.exceptions.ValidationError: ["'' is not a valid UUID."]
The error comes from a get query, ship = Ship.objects.get(id=shipID)
. See file:
from rest_framework.permissions import BasePermission
from Ships.models import Ship
import logging
logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG)
class HasObjectLevelPermissions(BasePermission):
def has_permission(self, request, view):
if request.method == "GET":
return True
else:
logging.debug("not a GET request")
shipID = request.POST.get('id',None)
try:
ship = Ship.objects.get(id=shipID) # This line is the issue
return request.user.userprofile.ship.id == ship.id
except:
logging.debug("Error in finding ship when checking permissions")
return False
Below is the Ship model where the UUID is declared.
class Ship(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
regNum = models.CharField(max_length=100, blank=False, db_index=True)
year = models.IntegerField(blank=True)
make = models.CharField(max_length=255)
length = models.IntegerField(blank=True)
beam = models.IntegerField(blank=True)
fleet = models.ForeignKey(Fleet)
created = models.DateTimeField(auto_now_add=True, db_index=True)
def getRegNum(self):
return self.regNum
Debugging attempts
ship = Ship.objects.get(id=shipID)
to ship = Ship.objects.get(id="some string")
makes the validation error disappear. ship = Ship.objects.get(id=shipID)
to ship = Ship.objects.get(id="")
makes the validation error disappear. This one is intriguing because an empty string passes the validation.shipID = request.POST.get('id',None)
to shipID = request.GET.get('id',None)
makes the validation error disappear.class UUIDField(Field):
.Logging the id from POST body.
System check identified no issues (0 silenced).
June 21, 2017 - 00:44:24
Django version 1.11.1, using settings 'First_REST_API.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
DEBUG:CHECKING PERMISSIONS
DEBUG:not a GET request
DEBUG:6b25b0be-610a-49f5-ad60-6df9564185a0
Internal Server Error: /ships
Traceback (most recent call last):
'''Same error as below'''
Essentially I am trying to retrieve a Ship object that matches an id. This type of query has always worked in the past with strings, unsure why the validation error keeps coming up. Any ideas?
Full error log
Internal Server Error: /ships
Traceback (most recent call last):
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\fields\__init__.py", line 2392, in to_python
return uuid.UUID(value)
File "C:\Users\ptao\AppData\Local\Programs\Python\Python36-32\lib\uuid.py", line 140, in __init__
raise ValueError('badly formed hexadecimal UUID string')
ValueError: badly formed hexadecimal UUID string
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\core\handlers\exception.py", line 41, in inner
response = get_response(request)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\views\decorators\csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\views\generic\base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\rest_framework\views.py", line 489, in dispatch
response = self.handle_exception(exc)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\rest_framework\views.py", line 449, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\rest_framework\views.py", line 486, in dispatch
response = handler(request, *args, **kwargs)
File "C:\Users\ptao\Desktop\ViaFleet\ViaDjango\First_REST_API\Ships\views.py", line 110, in delete
ship = Ship.objects.get(id=id)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\query.py", line 374, in get
num = len(clone)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\query.py", line 232, in __len__
self._fetch_all()
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\query.py", line 1103, in _fetch_all
self._result_cache = list(self._iterable_class(self))
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\query.py", line 53, in __iter__
results = compiler.execute_sql(chunked_fetch=self.chunked_fetch)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\sql\compiler.py", line 863, in execute_sql
sql, params = self.as_sql()
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\sql\compiler.py", line 420, in as_sql
where, w_params = self.compile(self.where) if self.where is not None else ("", [])
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\sql\compiler.py", line 373, in compile
sql, params = node.as_sql(self, self.connection)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\sql\where.py", line 79, in as_sql
sql, params = compiler.compile(child)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\sql\compiler.py", line 373, in compile
sql, params = node.as_sql(self, self.connection)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\lookups.py", line 170, in as_sql
rhs_sql, rhs_params = self.process_rhs(compiler, connection)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\lookups.py", line 103, in process_rhs
return self.get_db_prep_lookup(value, connection)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\lookups.py", line 196, in get_db_prep_lookup
[get_db_prep_value(value, connection, prepared=True)]
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\fields\__init__.py", line 2383, in get_db_prep_value
value = self.to_python(value)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\fields\__init__.py", line 2397, in to_python
params={'value': value},
django.core.exceptions.ValidationError: ["'' is not a valid UUID."]
ERROR:Internal Server Error: /ships
Traceback (most recent call last):
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\fields\__init__.py", line 2392, in to_python
return uuid.UUID(value)
File "C:\Users\ptao\AppData\Local\Programs\Python\Python36-32\lib\uuid.py", line 140, in __init__
raise ValueError('badly formed hexadecimal UUID string')
ValueError: badly formed hexadecimal UUID string
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\core\handlers\exception.py", line 41, in inner
response = get_response(request)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\views\decorators\csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\views\generic\base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\rest_framework\views.py", line 489, in dispatch
response = self.handle_exception(exc)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\rest_framework\views.py", line 449, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\rest_framework\views.py", line 486, in dispatch
response = handler(request, *args, **kwargs)
File "C:\Users\ptao\Desktop\ViaFleet\ViaDjango\First_REST_API\Ships\views.py", line 110, in delete
ship = Ship.objects.get(id=id)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\query.py", line 374, in get
num = len(clone)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\query.py", line 232, in __len__
self._fetch_all()
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\query.py", line 1103, in _fetch_all
self._result_cache = list(self._iterable_class(self))
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\query.py", line 53, in __iter__
results = compiler.execute_sql(chunked_fetch=self.chunked_fetch)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\sql\compiler.py", line 863, in execute_sql
sql, params = self.as_sql()
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\sql\compiler.py", line 420, in as_sql
where, w_params = self.compile(self.where) if self.where is not None else ("", [])
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\sql\compiler.py", line 373, in compile
sql, params = node.as_sql(self, self.connection)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\sql\where.py", line 79, in as_sql
sql, params = compiler.compile(child)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\sql\compiler.py", line 373, in compile
sql, params = node.as_sql(self, self.connection)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\lookups.py", line 170, in as_sql
rhs_sql, rhs_params = self.process_rhs(compiler, connection)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\lookups.py", line 103, in process_rhs
return self.get_db_prep_lookup(value, connection)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\lookups.py", line 196, in get_db_prep_lookup
[get_db_prep_value(value, connection, prepared=True)]
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\fields\__init__.py", line 2383, in get_db_prep_value
value = self.to_python(value)
File "C:\Users\ptao\Desktop\ViaFleet\VirtualEnvironment\lib\site-packages\django\db\models\fields\__init__.py", line 2397, in to_python
params={'value': value},
django.core.exceptions.ValidationError: ["'' is not a valid UUID."]
[21/Jun/2017 00:08:53] "DELETE /ships HTTP/1.1" 500 20510
Edit
The issue was due to a bug in views.py. Thank you to @Sardorbek Imomaliev for pointing that out. id = request.GET.get('id', '')
should have been id = request.POST.get('id', '')
. Note that request.POST will contain the DELETE request body. See the comment under this post for more. Thank you to everything that helped.
class ShipEndpoint(generics.ListAPIView):
permission_classes = (IsAuthenticated,HasObjectLevelPermissions)
''' get, post not shown'''
def delete(self, request, format=None):
id = request.GET.get('id', '') #GET should have been DELETE
ship = Ship.objects.get(id=id)
# ship.fleet.numberOfShips = ship.fleet.numberOfShips - 1
ship.fleet.save()
return Response("success")
# ship.delete()
Your problem is that you are trying to access request.POST
shipID = request.POST.get('id',None)
on DELETE
request
[21/Jun/2017 00:08:53] "DELETE /ships HTTP/1.1" 500 20510
You are checking permission on object then why you are not using has_object_permission
? http://www.django-rest-framework.org/api-guide/permissions/#examples
Also in your traceback it clearly states that issue is your views.py
File "C:\Users\ptao\Desktop\ViaFleet\ViaDjango\First_REST_API\Ships\views.py", line 110, in delete
ship = Ship.objects.get(id=id)
We need to see your actual view code
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With