如何在django-rest-framework的authtoken中更改现有令牌?

时间:2013-12-19 14:07:32

标签: django django-models django-rest-framework

保存失败:

from rest_framework.authtoken.models import Token

token = Token.objects.get(user=user1)
token.key = '1'
token.save()

给出

  

IntegrityError:重复键值违反唯一约束   “authtoken_token_user_id_key”

3 个答案:

答案 0 :(得分:6)

我今天遇到了同样的问题,所以我想我应该留下回复,以便日后参考解释为什么会这样。

key Token表的主键。

如果您编辑模型实例,则在致电save() django时必须确定是否必须执行INSERTUPDATE。它是通过在数据库中查找现有行(使用主键)来实现的,因为您只是更改了主键,它将找不到它并假设它必须插入新行。由于您已为该用户提供了一行,并且user_id列具有唯一约束,因此插入将失败。

使用相应生成的sql的示例。

>>> t = Token.objects.get(user=User.objects.get(id=1))
>>> t.key
u'b0750c801a1b075051ed084841f3001bb55dd1f1'
>>> t.key = t.generate_key()
'cafb2efb9b26912d60fc5a0a75b2b7ba0348a2ec'
t.save()

save()调用呈现

SELECT (1) AS "a"
  FROM "authtoken_token"
  WHERE "authtoken_token"."key" = 'cafb2efb9b26912d60fc5a0a75b2b7ba0348a2ec'
  LIMIT 1;
INSERT
  INTO "authtoken_token" ("key", "user_id", "created")
  VALUES ('cafb2efb9b26912d60fc5a0a75b2b7ba0348a2ec', 1, '2014-03-18 21:48:30.434677+00:00');

很明显,SELECT正在寻找带有编辑过的令牌的行(cafb2efb9b26912d60fc5a0a75b2b7ba0348a2ec)。

<强>解决方案

我想在这种特定情况下你可以删除旧的Token实例并创建一个新实例(在单个事务中),它会自动为你生成密钥,如:

token.delete()
Token.objects.create(user=user1)

请注意,这是ORM级别的问题,您可以避免删除/插入,只需更改该行的值,但不能使用save()方法。

使用update()方法是一个很好的选择,因为mariodev建议,你需要手动生成令牌(上面我是如何做的),是的,这将改变主键,键列,但这首先是你想要的:)

答案 1 :(得分:5)

似乎这样可行:

Token.objects.filter(user=user1).update(key='1')

答案 2 :(得分:0)

此示例代码适用于我并更新数据库中的令牌:

t = Token.objects.filter(user=user1)
new_key = t[0].generate_key()
t.update(key=new_key)
相关问题