Использовать пользовательскую UserCreationForm с администратором GeoDjango (OSMGeoAdmin) - PullRequest
0 голосов
/ 20 мая 2019
Django==2.2.1
GDAL==2.3.2
django-username-email==2.2.4

У меня есть простое приложение Django с пользовательской моделью на основе django-username-email 'AbstractCUser, которое удаляет username из пользовательской модели, используя e-адрес электронной почты вместо.В модели пользователя я определил поле 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, обязательные поля отображаются в соответствии с назначением, а текущее местоположение отображается на карте.Тем не менее, эта же форма, по-видимому, используется и для создания пользователей (т. Е. add_form не имеет никакого эффекта), что делает невозможным добавление новых пользователей через администратора, поскольку функция настройки пароля не внедрена правильно (см. Снимок экрана),django admin

Проблема заключается в том, что OSMGeoAdmin наследуется от ModelAdmin , который в отличие от стандартного UserAdmin не имеет add_formимущество.

Можно ли в этом случае указать пользовательскую форму создания пользователя (в идеале UserCreationForm, предоставляемую django-username-email при сохранении возможности отображать точечные поля на карте в форме изменения пользователя?

Ответы [ 2 ]

1 голос
/ 21 мая 2019

Вам нужно переопределить 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)
0 голосов
/ 21 мая 2019

Следуя совету Шиллингта, вот код, который я использовал в итоге:

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)
...