更改 Django UserAdmin 的下拉标签

Change drop-down labels for Django UserAdmin

我有一个 User 模型,上面有一个 timezone 字段:

class User(AbstractBaseUser, PermissionsMixin):
    timezone = models.CharField(
        max_length=64,
        choices=[(tz, tz) for tz in pytz.common_timezones],
        default="UTC",
    )

在 Django 管理中查看时,这会创建一个时区下拉列表,但只有名称。我想为此下拉列表动态生成标签,将偏移量添加为前缀(例如 +02:00)并按此对列表进行排序。我知道我可以通过执行以下操作来创建这些:

choices=[
    (tz, display_with_offset(tz))
    for tz in pytz.common_timezones
],

其中 display_with_offset 生成所需的标签,但我认为这只会在迁移 运行 时计算它,并且会忽略某些地区全年发生的任何夏令时变化。

我的管理文件如下所示:

class MyUserAdmin(UserAdmin):
    fieldsets = [
        ("Info", {"fields": ("timezone")}),
    ]

admin.site.register(models.User, MyUserAdmin)

有没有办法动态设置下拉标签?

您可以创建一个 ModelForm 并覆盖选项。例如:

class UserAdminForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
      super().__init__(*args, **kwargs)
      self.fields['timezone'].choices = [
          (tz, display_with_offset(tz)) for tz in pytz.common_timezones
      ]

    class Meta:
        model = User
        fields = '__all__'

class MyUserAdmin(UserAdmin):
    fieldsets = [
        ("Info", {"fields": ("timezone")}),
    ]
    form = UserAdminForm

可以在 documentation 中找到更多信息。