【问题标题】:django.core.exceptions.ValidationError: ["'' is not a valid UUID."]django.core.exceptions.ValidationError: ["'' 不是有效的 UUID。"]
【发布时间】:2017-11-23 19:35:36
【问题描述】:

在尝试使用 Django Rest 框架在 Django 中编写对象级权限时,我遇到了这个错误(底部的完整错误日志)

django.core.exceptions.ValidationError: ["'' is not a valid UUID."]

错误来自 get 查询 ship = Ship.objects.get(id=shipID)。见文件:

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

下面是声明了 UUID 的 Ship 模型。

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

调试尝试

  1. ship = Ship.objects.get(id=shipID) 更改为ship = Ship.objects.get(id="some string") 会使验证错误消失。
  2. ship = Ship.objects.get(id=shipID) 更改为ship = Ship.objects.get(id="") 会使验证错误消失。这很有趣,因为一个空字符串通过了验证。
  3. shipID = request.POST.get('id',None) 更改为shipID = request.GET.get('id',None) 会使验证错误消失。
  4. 我已经记录了从 POST 请求传入的 uuid,它确实是一个格式正确的 uuid(见下文)

  1. 我已尝试按照here 的建议删除整个 Postgres 数据库以及迁移。
  2. 我已在每个表上运行“SELECT * FROM”以确保没有表的 uuid 为空
  3. 我已经咨询了official docsclass UUIDField(Field):
  4. 从 POST 正文记录 id。

    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'''

基本上我正在尝试检索与 id 匹配的 Ship 对象。这种类型的查询过去一直使用字符串,不确定为什么验证错误不断出现。有什么想法吗?

完整的错误日志

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

编辑 该问题是由于views.py 中的错误引起的。感谢@Sardorbek Imomaliev 指出这一点。 id = request.GET.get('id', '') 应该是 id = request.POST.get('id', '')。请注意,request.POST 将包含 DELETE 请求正文。有关更多信息,请参阅此 post 下的评论。感谢所有提供帮助的人。

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()

【问题讨论】:

  • 这个错误是因为 uuid 字段变得空白
  • 怎么变成空白了?
  • 从 post 输入中获取后尝试打印(shipID) 并查看 id 是否显示在终端中
  • 在问题的调试部分显示、发布输出
  • 格式错误的十六进制 UUID 字符串,这是它在终端中显示的错误,这意味着您传递的 id 以某种方式被截断为空白字符串,

标签: python django postgresql


【解决方案1】:

您的问题是您正在尝试访问request.POST

shipID = request.POST.get('id',None)

DELETE请求上

[21/Jun/2017 00:08:53]“删除 /ships HTTP/1.1”500 20510

您正在检查对象的权限,那么为什么不使用has_object_permissionhttp://www.django-rest-framework.org/api-guide/permissions/#examples

还在您的回溯中明确指出问题是您的views.py

文件“C:\Users\ptao\Desktop\ViaFleet\ViaDjango\First_REST_API\Ships\views.py”,第 110 行,删除ship = Ship.objects.get(id=id)

我们需要查看您的实际查看代码

【讨论】:

    【解决方案2】:

    你写

    我已经记录了从 POST 请求传入的 uuid,它确实是一个格式正确的 uuid(见下文)

    并且您的 uuid 图像具有所需的 32 位数字。但是,当剥离的字符串不是 32 位数字时,uuid.py 中引用的行会引发该异常。

    所以 id 的类型有问题。

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

    UUID字段¶

    类 UUIDField(**options)[源代码]¶

    用于存储通用唯一标识符的字段。使用 Python 的 UUID 类。在 PostgreSQL 上使用时,它以 uuid 数据类型存储,否则以 char(32) 形式存储。

    错误行是

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

    其中shipID 是一个字符串。如果你的线路是

    get(id=UUID(shipID))
    

    ?

    【讨论】:

    • 好主意,但没有 cookie。我试过这样ship = Ship.objects.get(id=uuid.UUID(shipID))。同样的验证错误。
    • 哎呀。在调用 get() 之前它是否仍然打印出正确的 uuid?
    • 是的,我只是尝试编辑 uuid(只是最后一个数字)以使其不正确但格式正确。得到一个DoesNotExist 错误,这意味着 Django 对这种格式很满意。想法?
    • 我刚刚检查了你的模型。你可以试试 ship = Ship.objects.get(id=uuid.uuid4(shipID)) 吗?
    • 另一个好主意,但又一个错误TypeError at /ships uuid4() takes 0 positional arguments but 1 was given
    猜你喜欢
    • 2018-02-09
    • 2017-11-09
    • 2018-06-14
    • 1970-01-01
    • 2017-06-03
    • 1970-01-01
    • 2015-04-12
    • 1970-01-01
    • 2015-04-25
    相关资源
    最近更新 更多