我正在开发一个包含敏感用户数据的Django应用,因此我采取了许多步骤来匿名化User对象及其数据。
我创建了自定义“用户”对象,该对象将AbstractBaseUser模型子类化,如下所示:
class User(AbstractBaseUser, PermissionsMixin):
(...)
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
(...)
它具有以下链接的ModelAdmin
对象:
from django.contrib.auth.forms import UserChangeForm
@admin.register(User)
class UserAdmin(admin.ModelAdmin):
form = UserChangeForm
我正在使用UUID字段作为主键,以确保最大程度的匿名性,但我希望能够在Django Admin中重置用户密码(就像您可以使用默认的User
对象一样)
但是,当我以管理员身份打开用户并按链接更改密码时,出现以下错误消息:
User with ID "21362aca-6918-47ea-9b29-275350a89c54/password" doesn't exist. Perhaps it was deleted?
管理员url仍期望以整数作为其pk
值的url。
所以看来我必须在ModelAdmin定义中覆盖admin url配置,但我想知道是否有一种更简单的方法来实现所需的结果-因为我想用UUID字段替换User.pk是这是很正常的情况,我想很多开发人员都遇到了这个问题。我试图找到某种设置/切换来实现此目的,但无济于事,我有什么遗漏吗?
答案 0 :(得分:1)
您的'UserAdmin'继承自#container {
width: 960px;
margin: auto;
}
nav {
list-style-type: none;
overflow: hidden;
margin: 0;
padding: 0;
background-color: rgb(87, 222, 135, 0.3);
width: 100%;
}
hr {
margin-top: 0;
border: none;
background-color: black;
height: 2px;
width: 100%;
}
,后者通过ModelAdmin
方法提供了用于添加,更改,删除等视图的URL,还提供了一个“后备” URL:
get_urls
您要跟踪的url看起来像urlpatterns = [
#...
url(r'^(.+)/change/$', wrap(self.change_view), name='%s_%s_change' % info),
# For backwards compatibility (was the change url before 1.9)
path('<path:object_id>/', wrap(RedirectView.as_view(
pattern_name='%s:%s_%s_change' % ((self.admin_site.name,) + info)
))),
]
,仅适合后备模式的正则表达式-它将您重定向到更改页面,以这种方式将/user/<UUID>/password/
用作{{1} }。
请尝试从<UUID>/password
继承,因为其object_id
方法提供了所需的网址格式。
更多戳......
如果您的主键字段是一个AutoField,则整个过程将在尝试将django.contrib.auth.admin.UserAdmin
中的get_urls
强制转换以准备查询值时引发ValueError('invalid literal for int')
。可以理解的!
如何:int('some_integer/password')
使用基类django.db.models.fields.AutoField.get_prep_value
的{{1}}方法。 UUIDField
只是简单地返回了值,甚至没有进行检查(毕竟,验证值应该是get_prep_value
的工作)。因此,您最终得到一个查询,该查询将查找虚假的uuid Field
,该伪造品显然不存在。