将自定义 UserCreationForm 与 GeoDjango 管理员 (OSMGeoAdmin) 结合使用
Use custom UserCreationForm with GeoDjango admin (OSMGeoAdmin)
Django==2.2.1
GDAL==2.3.2
django-username-email==2.2.4
我有一个简单的 Django 应用程序,带有基于 django-username-email 的 AbstractCUser
的自定义用户模型,它从用户模型中删除了 username
,改用电子邮件地址.在用户模型上,我定义了一个 PointField
字段来存储用户的当前位置。
models.py
from django.contrib.gis.db import models as gis_models
from cuser.models import AbstractCUser
class User(AbstractCUser):
"""Custom user model that extends AbstractCUser."""
current_location = gis_models.PointField(null=True, blank=True,)
我想在 Django 管理中注册这个模型,这样我就可以注册新用户并 view/set 他们使用地图小部件的位置。如果我将基于 admin.OSMGeoAdmin
的自定义用户管理员与自定义用户更改表单结合使用,则这种方法有效:
admin.py
from django.contrib.gis import admin
from django.contrib.auth import get_user_model
from .forms import CustomUserCreationForm, CustomUserChangeForm
class CustomUserAdmin(admin.OSMGeoAdmin):
model = get_user_model()
add_form = CustomUserCreationForm # <- there seems to be a problem here
form = CustomUserChangeForm
list_display = ['email', 'last_name', 'first_name']
readonly_fields = ['last_login', 'date_joined']
admin.site.register(get_user_model(), CustomUserAdmin)
forms.py
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
model = get_user_model()
exclude = ('username',)
class CustomUserChangeForm(UserChangeForm):
class Meta(UserChangeForm.Meta):
model = get_user_model()
fields = (
'email',
'first_name',
'last_name',
'current_location',
# ...
)
当我在 Django 管理中打开现有用户记录时,必填字段按预期显示,当前位置显示在地图上。然而,相同的表单似乎也用于用户创建(即 add_form
无效),这使得无法通过管理员添加新用户,因为密码设置功能未正确嵌入(见屏幕射击)。
问题似乎是 OSMGeoAdmin
inherits from ModelAdmin,与标准 UserAdmin
相比,它没有 add_form
属性。
在这种情况下是否有任何方法可以指定自定义用户创建表单(最好是 django-username-email
提供的 UserCreationForm
同时保持在用户更改表单上的地图上显示点字段的能力?
您需要像 django.contrib.auth.admin.UserAdmin
那样覆盖 get_form
。
def get_form(self, request, obj=None, **kwargs):
"""
Use special form during user creation
"""
defaults = {}
if obj is None:
defaults['form'] = self.add_form
defaults.update(kwargs)
return super().get_form(request, obj, **defaults)
根据 schillingt 的建议,这是我最终使用的代码:
from django.contrib.gis import admin
from django.contrib.auth import get_user_model
from cuser.forms import UserCreationForm
from .forms import CustomUserChangeForm
class CustomUserAdmin(admin.OSMGeoAdmin):
model = get_user_model()
add_form = UserCreationForm
form = CustomUserChangeForm
list_display = ['email', 'last_name', 'first_name']
readonly_fields = ['last_login', 'date_joined']
def get_form(self, request, obj=None, **kwargs):
"""
Use special form during user creation.
Override get_form method in the same manner as django.contrib.auth.admin.UserAdmin does.
"""
defaults = {}
if obj is None:
defaults['form'] = self.add_form
defaults.update(kwargs)
return super().get_form(request, obj, **defaults)
admin.site.register(get_user_model(), CustomUserAdmin)
Django==2.2.1
GDAL==2.3.2
django-username-email==2.2.4
我有一个简单的 Django 应用程序,带有基于 django-username-email 的 AbstractCUser
的自定义用户模型,它从用户模型中删除了 username
,改用电子邮件地址.在用户模型上,我定义了一个 PointField
字段来存储用户的当前位置。
models.py
from django.contrib.gis.db import models as gis_models
from cuser.models import AbstractCUser
class User(AbstractCUser):
"""Custom user model that extends AbstractCUser."""
current_location = gis_models.PointField(null=True, blank=True,)
我想在 Django 管理中注册这个模型,这样我就可以注册新用户并 view/set 他们使用地图小部件的位置。如果我将基于 admin.OSMGeoAdmin
的自定义用户管理员与自定义用户更改表单结合使用,则这种方法有效:
admin.py
from django.contrib.gis import admin
from django.contrib.auth import get_user_model
from .forms import CustomUserCreationForm, CustomUserChangeForm
class CustomUserAdmin(admin.OSMGeoAdmin):
model = get_user_model()
add_form = CustomUserCreationForm # <- there seems to be a problem here
form = CustomUserChangeForm
list_display = ['email', 'last_name', 'first_name']
readonly_fields = ['last_login', 'date_joined']
admin.site.register(get_user_model(), CustomUserAdmin)
forms.py
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
model = get_user_model()
exclude = ('username',)
class CustomUserChangeForm(UserChangeForm):
class Meta(UserChangeForm.Meta):
model = get_user_model()
fields = (
'email',
'first_name',
'last_name',
'current_location',
# ...
)
当我在 Django 管理中打开现有用户记录时,必填字段按预期显示,当前位置显示在地图上。然而,相同的表单似乎也用于用户创建(即 add_form
无效),这使得无法通过管理员添加新用户,因为密码设置功能未正确嵌入(见屏幕射击)。
问题似乎是 OSMGeoAdmin
inherits from ModelAdmin,与标准 UserAdmin
相比,它没有 add_form
属性。
在这种情况下是否有任何方法可以指定自定义用户创建表单(最好是 django-username-email
提供的 UserCreationForm
同时保持在用户更改表单上的地图上显示点字段的能力?
您需要像 django.contrib.auth.admin.UserAdmin
那样覆盖 get_form
。
def get_form(self, request, obj=None, **kwargs):
"""
Use special form during user creation
"""
defaults = {}
if obj is None:
defaults['form'] = self.add_form
defaults.update(kwargs)
return super().get_form(request, obj, **defaults)
根据 schillingt 的建议,这是我最终使用的代码:
from django.contrib.gis import admin
from django.contrib.auth import get_user_model
from cuser.forms import UserCreationForm
from .forms import CustomUserChangeForm
class CustomUserAdmin(admin.OSMGeoAdmin):
model = get_user_model()
add_form = UserCreationForm
form = CustomUserChangeForm
list_display = ['email', 'last_name', 'first_name']
readonly_fields = ['last_login', 'date_joined']
def get_form(self, request, obj=None, **kwargs):
"""
Use special form during user creation.
Override get_form method in the same manner as django.contrib.auth.admin.UserAdmin does.
"""
defaults = {}
if obj is None:
defaults['form'] = self.add_form
defaults.update(kwargs)
return super().get_form(request, obj, **defaults)
admin.site.register(get_user_model(), CustomUserAdmin)