【问题标题】:Django admin UserChangeForm with UUID field as primary key以 UUID 字段作为主键的 Django 管理员 UserChangeForm
【发布时间】:2018-11-05 16:06:28
【问题描述】:

我正在开发一个包含敏感用户数据的 Django 应用程序,因此我采取了许多步骤来匿名用户对象及其数据。

我创建了自定义“用户”对象,它继承了 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 定义中的管理 url 配置,但我想知道是否有更简单的方法来实现所需的结果 - 因为我想用 UUID 字段替换 User.pk 是相当频繁地发生,我认为许多开发人员都遇到了这个问题。我试图找到某种设置/切换来实现这一点,但无济于事,我错过了什么吗?

【问题讨论】:

  • 请分享您的网址。看起来它也占用了password 部分。

标签: python django django-admin


【解决方案1】:

您的 'UserAdmin' 继承自 ModelAdmin,它通过 get_urls 方法为添加、更改、删​​除等视图提供 url,但也提供了一个 'fallback' 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)
    ))),
]

您关注的 url 看起来像 /user/&lt;UUID&gt;/password/,它只适合回退模式的正则表达式 - 它会将您重定向到更改页面,从而使用 &lt;UUID&gt;/password 作为 object_id

尝试从 django.contrib.auth.admin.UserAdmin 继承,因为它的 get_urls 方法提供了您需要的 url 模式。


还有一些闲逛...
如果您的主键字段是 AutoField,则在尝试将 int('some_integer/password') 转换为 django.db.models.fields.AutoField.get_prep_value 以准备查询值时,整个过程将引发 ValueError('invalid literal for int')。可以理解!

但是UUIDField 使用基类Fieldget_prep_value 方法。 Field.get_prep_value 只是简单地返回值,甚至不检查(毕竟,验证值应该是 UUIDField 的工作)。因此,您最终会得到一个查找虚假 uuid '&lt;uuid&gt;/password' 的查询,这显然不存在。

【讨论】:

  • 子类化 UserAdmin 确实是可行的方法,谢谢!
猜你喜欢
  • 1970-01-01
  • 2020-04-13
  • 2018-09-02
  • 2012-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-16
相关资源
最近更新 更多