保存失败:
from rest_framework.authtoken.models import Token token = Token.objects.get(user=user1) token.key = '1' token.save()
给
IntegrityError:重复键值违反唯一约束"authtoken_token_user_id_key"
mariodev.. 9
看起来这样可行:
Token.objects.filter(user=user1).update(key='1')
gonz.. 7
我今天遇到了同样的问题,所以我想我应该留下回复,以便将来参考解释为什么会发生这种情况.
该key
列是Token
表的主键.
如果您编辑模型实例,则在调用save()
django时必须确定是否必须执行INSERT
或者执行UPDATE
.它是通过在数据库中查找现有行(使用主键)来实现的,因为您只是更改了主键,它将找不到它并假设它必须插入新行.由于您已为该用户提供了一行,并且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建议,你需要手动生成令牌(上面我是如何做的),是的,这将改变主键,关键列,但这是你想要的第一个地方:)
看起来这样可行:
Token.objects.filter(user=user1).update(key='1')
我今天遇到了同样的问题,所以我想我应该留下回复,以便将来参考解释为什么会发生这种情况.
该key
列是Token
表的主键.
如果您编辑模型实例,则在调用save()
django时必须确定是否必须执行INSERT
或者执行UPDATE
.它是通过在数据库中查找现有行(使用主键)来实现的,因为您只是更改了主键,它将找不到它并假设它必须插入新行.由于您已为该用户提供了一行,并且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建议,你需要手动生成令牌(上面我是如何做的),是的,这将改变主键,关键列,但这是你想要的第一个地方:)