2

我正在尝试使用 django 中的 F() 对象更新模型的自我日期时间字段。

HeatWatchList.objects.filter(
    user=request.user,
    next_date_to__lt=datetime.combine(datetime.now().date(), time.min)
).update(
    next_date_from = F('next_date_from') + relativedelta(months=1),
    next_date_to = F('next_date_to') + relativedelta(months=1)
)

但是当我这样做时,我得到了AttributeError: relativedelta object has no attribute translate

这是我在执行代码时得到的回溯,可能在使用日期时间类型 relativedelta 添加值时使用 F() 对象存在问题。

Traceback (most recent call last):
  File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\django\core\handlers\exception.py", line 39, in inner
    response = get_response(request)
  File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\django\views\decorators\csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\rest_framework\viewsets.py", line 83, in view
    return self.dispatch(request, *args, **kwargs)
  File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\rest_framework\views.py", line 477, in dispatch
    response = self.handle_exception(exc)
  File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\rest_framework\views.py", line 437, in handle_exception
    self.raise_uncaught_exception(exc)
  File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\rest_framework\views.py", line 474, in dispatch
    response = handler(request, *args, **kwargs)
  File "C:\Users\Web\Desktop\PyDev\Envs\djangular\farm_management\heat\views.py", line 192, in update_watchlist
    next_date_to = F('next_date_to') + relativedelta(months=1)
  File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\django\db\models\query.py", line 637, in update
    rows = query.get_compiler(self.db).execute_sql(CURSOR)
  File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\django\db\models\sql\compiler.py", line 1148, in execute_sql
    cursor = super(SQLUpdateCompiler, self).execute_sql(result_type)
  File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\django\db\models\sql\compiler.py", line 835, in execute_sql
    cursor.execute(sql, params)
  File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\django\db\backends\utils.py", line 79, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\django\db\backends\utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\django\db\backends\mysql\base.py", line 110, in execute
    return self.cursor.execute(query, args)
  File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\pymysql\cursors.py", line 164, in execute
    query = self.mogrify(query, args)
  File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\pymysql\cursors.py", line 143, in mogrify
    query = query % self._escape_args(args, conn)
  File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\pymysql\cursors.py", line 118, in _escape_args
    return tuple(conn.literal(arg) for arg in args)
  File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\pymysql\cursors.py", line 118, in <genexpr>
    return tuple(conn.literal(arg) for arg in args)
  File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\pymysql\connections.py", line 800, in literal
    return self.escape(obj, self.encoders)
  File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\pymysql\connections.py", line 793, in escape
    return escape_item(obj, self.charset, mapping=mapping)
  File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\pymysql\converters.py", line 27, in escape_item
    val = encoder(val, mapping)
  File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\pymysql\converters.py", line 110, in escape_unicode
    return u"'%s'" % _escape_unicode(value)
  File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\pymysql\converters.py", line 73, in _escape_unicode
    return value.translate(_escape_table)
AttributeError: 'relativedelta' object has no attribute 'translate'
4

2 回答 2

1

好像 pymysql 的转换器不支持relativedelta 对象。一种可能的解决方案是遍历对象并更新它(低效):

objects_list = HeatWatchList.objects.filter(
user=request.user,
next_date_to__lt=datetime.combine(datetime.now().date(), time.min)
)

for obj in object_list:
    obj.next_date_from = onj.next_date_from + relativedelta(months=1)
    obj.next_date_to = onj.next_date_to + relativedelta(months=1)
    objsave()  

或者更好地使用datetime.timedelta而不是relativedelta如果可能的话:

HeatWatchList.objects.filter(
user=request.user,
next_date_to__lt=datetime.combine(datetime.now().date(), time.min)
).update(
next_date_from = F('next_date_from') + timedelta(days=31),
next_date_to = F('next_date_to') + timedelta(days=31)
)
于 2016-12-26T05:57:44.660 回答
-1

从 PostgreSQL文档中,发现 1 个月的间隔被视为 30 天:

在此处输入图像描述

因此,如果您使用的是 PostgreSQL,则它与 using timedelta(days=30)as using相同。relativedelta(months=1)您可以简单地添加30 天的F()表达式timedelta(即F('datetimefield') + timedelta(days=30)

于 2019-01-04T00:38:33.500 回答