Django 引发 ValueError: int() 的无效文字,在 POST 上以 10 为基数

Posted

技术标签:

【中文标题】Django 引发 ValueError: int() 的无效文字,在 POST 上以 10 为基数【英文标题】:Django raising ValueError: invalid literal for int() with base 10 on POST 【发布时间】:2018-06-08 14:07:10 【问题描述】:

Django 在对服务器的每个 POST 请求中始终抛出 ValueError。从表格和 SE 周围游弋,这似乎是我的 Django 模型的一个问题。但是,我不确定为什么模型会抛出这个错误,或者为什么它们会被 Django 调用,因为这是在 POST 事件中抛出的。

有问题的视图:

def channel(request, channel):
    user_form = weblog_userForm(request.POST or None)
    if request.method == 'POST' and user_form.is_valid():
        nickname = user_form.cleaned_data['nickname']
        message = user_form.cleaned_data['message']
        password = user_form.cleaned_data['password']
        postDetails = 

        ... process request and eventually ...

        return HttpResponse(json.dumps(postDetails), content_type="application/json")

我的应用模型:

class Line(models.Model):
    message = models.TextField(blank=True, default="")
    nick = models.CharField(max_length=50)
    hostname = models.CharField(max_length=300)
    channel = models.CharField(max_length=200)
    timestamp = models.DateTimeField(auto_now_add=True)
    LINE_TYPES = (
        ('PMSG', 'PRIVMSG'),
        ('SMSG', 'SOCKETMSG'),
        ('WMSG', 'WEBMSG'),
        ('NTCE', 'NOTICE'),
        ('ACTN', 'ACTION'),
        ('JOIN', 'JOIN'),
        ('PART', 'PART'),
        ('QUIT', 'QUIT'),
        ('NICK', 'NICK'),
        ('TPIC', 'TOPIC'),
    )
    msgType = models.CharField(max_length=4, choices=LINE_TYPES, default='PRIVMSG')

    def __str__(self):
        return self.message

class banned_ips(models.Model):
    bannedIp = models.GenericIPAddressField()

追溯:

回溯(最近一次通话最后): 文件“/usr/local/lib/python3.5/dist-packages/django/core/handlers/exception.py”,第 35 行,在内部 响应 = get_response(请求) _get_response 中的文件“/usr/local/lib/python3.5/dist-packages/django/core/handlers/base.py”,第 128 行 response = self.process_exception_by_middleware(e, request) _get_response 中的文件“/usr/local/lib/python3.5/dist-packages/django/core/handlers/base.py”,第 126 行 响应 = Wrapped_callback(request, *callback_args, **callback_kwargs) 文件“/home/django/weblogs/log/views.py”,第 96 行,在频道中 json_data = serializers.serialize("json", list(reversed(Line.objects.filter(id__gt=latest_line_id, channel=channel).order_by('-id')[:100]))) 文件“/usr/local/lib/python3.5/dist-packages/django/db/models/manager.py”,第 82 行,在 manager_method 中 返回 getattr(self.get_queryset(), name)(*args, **kwargs) 过滤器中的文件“/usr/local/lib/python3.5/dist-packages/django/db/models/query.py”,第 836 行 return self._filter_or_exclude(False, *args, **kwargs) _filter_or_exclude 中的文件“/usr/local/lib/python3.5/dist-packages/django/db/models/query.py”,第 854 行 clone.query.add_q(Q(*args, **kwargs)) 文件“/usr/local/lib/python3.5/dist-packages/django/db/models/sql/query.py”,第 1252 行,在 add_q 子句,_ = self._add_q(q_object, self.used_aliases) 文件“/usr/local/lib/python3.5/dist-packages/django/db/models/sql/query.py”,第 1276 行,在 _add_q split_subq=split_subq, 文件“/usr/local/lib/python3.5/dist-packages/django/db/models/sql/query.py”,第 1214 行,在 build_filter 条件 = self.build_lookup(查找,列,值) 文件“/usr/local/lib/python3.5/dist-packages/django/db/models/sql/query.py”,第 1084 行,在 build_lookup 查找 = lookup_class(lhs, rhs) 文件“/usr/local/lib/python3.5/dist-packages/django/db/models/lookups.py”,第 18 行,在 __init__ self.rhs = self.get_prep_lookup() 文件“/usr/local/lib/python3.5/dist-packages/django/db/models/lookups.py”,第 68 行,在 get_prep_lookup 返回 self.lhs.output_field.get_prep_value(self.rhs) 文件“/usr/local/lib/python3.5/dist-packages/django/db/models/fields/__init__.py”,第 947 行,在 get_prep_value 返回整数(值) ValueError: int() 以 10 为底的无效文字:''

任何帮助或想法都将不胜感激,这真的让我摸不着头脑。

【问题讨论】:

错误指向File "/home/django/weblogs/log/views.py", line 96, in channeljson_data = serializers.serialize("json", list(reversed(Line.objects.filter(id__gt=latest_line_id, channel=channel).order_by('-id')[:100]))) latest_line_id 的值是多少?回溯表明它可能不是整数,导致错误。 【参考方案1】:

guillermo chamorro 和口袋对子都在这里找到了我的收获。在我的views.py snip 中发布的一个(看似无关的)逻辑块中,是以下代码:

if (request.is_ajax()):
    latest_line_id = request.GET.get('latest_id', '')
    if latest_line_id == '-1': # Return all lines
        json_data = serializers.serialize("json", list(reversed(Line.objects.filter(channel=channel).order_by('-id')[:100])))
    else:
        json_data = serializers.serialize("json", list(reversed(Line.objects.filter(id__gt=latest_line_id, channel=channel).order_by('-id')[:100])))
    return HttpResponse(json_data, content_type="application/json")

尽管逻辑上从未被调用,但两个响应者都是正确的,ValueError 失败源于 Django,但仍试图评估 json_data

如果latest_line_id 为空(就像在 POST 请求中一样),它将被设置为'',这将在尝试基于此 ID 的数据库查询时由 Django 触发ValueError。这可以通过尝试在 Django shell 中自己查询过滤器来证明(使用$python manage.py shell):

(注意:如果使用 django shell,请不要忘记使用 from <yourapp>.models import <yourModel> 之类的内容导入模型)

>>> list(Line.objects.filter(channel="test").filter(id__lte='').order_by('id'))
Traceback (most recent call last):
...
ValueError: invalid literal for int() with base 10: ''

经验教训,编辑视图时要非常勤奋,记得仔细检查所有逻辑块,阅读回溯时要小心(多一双眼睛可以帮助;))。希望我的疏忽可以节省其他人我失去的时间。

【讨论】:

以上是关于Django 引发 ValueError: int() 的无效文字,在 POST 上以 10 为基数的主要内容,如果未能解决你的问题,请参考以下文章

在 Django 的详细视图中使用两个参数时,得到“ValueError:int() 的无效文字,基数为 10:'Trancel'”

Django ORM 迁移在 IntegerField 上给出“ValueError:int() 的无效文字”

django ValueError:以 10 为基数的 int() 的无效文字:''

Django celery 4 - ValueError: int() 的无效文字,当启动 celery worker 时,基数为 10

Django ValueError: invalid literal for int() with base 10: 'xxx'解决办法

UUIDField在Django Model中的使用经验