11

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

  1. Changing ship = Ship.objects.get(id=shipID) to ship = Ship.objects.get(id="some string") makes the validation error disappear.
  2. Changing 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.
  3. Changing shipID = request.POST.get('id',None) to shipID = request.GET.get('id',None) makes the validation error disappear.
  4. I have logged the uuid being passed in from the POST request and it is indeed a properly formatted uuid (see below)

enter image description here

  1. I have tried deleting the entire Postgres database along with migrations as suggested here.
  2. I have run a "SELECT * FROM" on every single table to ensure that no table has an empty uuid
  3. I have consulted the official docs under class UUIDField(Field):.
  4. 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()
14
  • 1
    well the error is because the uuid field is getting blank Commented Jun 21, 2017 at 4:36
  • How is it getting blank? Commented Jun 21, 2017 at 4:40
  • 2
    try to print(shipID) after taking it from the post input and see if the id is displayed in terminal or not Commented Jun 21, 2017 at 4:43
  • It is displayed, posted output in the debugging section in the question Commented Jun 21, 2017 at 4:48
  • badly formed hexadecimal UUID string, this is the error what it displays in the terminal, that means somehow the id that you are passing to get is getting truncated to blank string, Commented Jun 21, 2017 at 4:51

3 Answers 3

6

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

Sign up to request clarification or add additional context in comments.

1 Comment

Can you please take a look at my question too? I'm getting this error too, but from another part of the problem. here is the question link: stackoverflow.com/questions/74768301/…
4

You write

I have logged the uuid being passed in from the POST request and it is indeed a properly formatted uuid (see below)

and your uuid image has the required 32 digits. However, the line quoted in uuid.py throws that exception when the stripped string has other than 32 digits.

So something is wrong with the type of the id.

From https://docs.djangoproject.com/en/1.11/ref/models/fields/:

UUIDField¶

class UUIDField(**options)[source]¶

A field for storing universally unique identifiers. Uses Python’s UUID class. When used on PostgreSQL, this stores in a uuid datatype, otherwise in a char(32).

The error line is

ship = Ship.objects.get(id=shipID)

where shipID is a string. Should your line be

get(id=UUID(shipID))

?

10 Comments

Good idea, but no cookie. I tried like so ship = Ship.objects.get(id=uuid.UUID(shipID)). Same validation error.
Ouch.Is it still printing out the correct uuid just before the call to get()?
Yeah, I just tried editing the uuid (just the last digit) to make it incorrect but properly formatted. Got an DoesNotExist error, which means that Django was happy with that format. Thoughts?
I just checked your model. Could you try ship = Ship.objects.get(id=uuid.uuid4(shipID))?
Another good idea, but yet another error TypeError at /ships uuid4() takes 0 positional arguments but 1 was given
|
0

add a condition for if the id is empty string nor none, because id is expecting a uuid,
if not shipId:
log.error("empty shipId")
return False

1 Comment

This does not answer the question. The original poster (OP) wanted to know why they were getting the error, not how they should handle it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.