与GeoDjango管理员(OSMGeoAdmin)一起使用自定义UserCreationForm

时间:2019-05-20 17:05:40

标签: django django-forms django-admin geodjango

Django==2.2.1
GDAL==2.3.2
django-username-email==2.2.4

我有一个简单的Django应用程序,该应用程序具有基于django-username-emailAbstractCUser的自定义用户模型,该模型将电子邮件地址从用户模型中删除了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 admin中注册该模型,以便我可以注册新用户并使用地图小部件查看/设置他们的位置。如果我将基于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 admin中打开现有用户记录时,必填字段将按预期显示,并且当前位置将显示在地图上。但是,似乎也可以使用相同的形式来创建用户(即add_form无效),这使得无法通过管理员添加新用户,因为密码设置功能未正确嵌入(请参见屏幕)。射击)。 django admin

问题似乎是OSMGeoAdmin inherits from ModelAdmin,与标准UserAdmin相比,它没有add_form属性。

在这种情况下,有什么方法可以指定自定义用户创建表单(理想情况下是UserCreationForm提供的django-username-email,同时保持在用户更改表单上在地图上显示点字段的功能?< / p>

2 个答案:

答案 0 :(得分:1)

您需要像get_form那样覆盖django.contrib.auth.admin.UserAdmin

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)

答案 1 :(得分:0)

按照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)