from django.contrib import admin from django.contrib.auth.admin import UserAdmin from django.contrib.auth.models import Group from django.core.exceptions import ValidationError from django.forms.models import BaseInlineFormSet from django.utils.translation import gettext_lazy as _ from log_manager.trace_log import trace_log from .models import CustomGroup, CustomUser, EmailAddress class EmailAddressInlineFormSet(BaseInlineFormSet): """メールアドレス用フォームセット。""" @trace_log def clean(self): """メールアドレスの primary 指定が複数ある場合、ValidationErro を投げます。""" super().clean() primary_count = sum(1 for form in self.forms if form.cleaned_data.get("is_primary", False)) if primary_count > 1: raise ValidationError(_("Only one primary email address can be set. ")) class EmailAddressInline(admin.TabularInline): """メールアドレスインライン用""" model = EmailAddress formset = EmailAddressInlineFormSet extra = 1 @admin.register(CustomUser) class CustomUserAdmin(UserAdmin): """カスタムユーザー管理。""" model = CustomUser """ 対象モデル。 """ inlines = [ EmailAddressInline, ] """ インライン表示。 """ list_display = ( "login_id", "username", "get_primary_email", "is_mfa_enabled", "is_staff", "is_superuser", ) """ リスト表示のフィールド。 """ search_fields = ( "login_id", "username", "get_primary_email", "is_mfa_enabled", "is_staff", "is_superuser", ) """ 検索フィールド。 """ ordering = ("login_id",) """ 表示順。 """ fieldsets = ( ( None, { "fields": ( "login_id", "username", "password", "is_mfa_enabled", ) }, ), ( _("Permissions"), { "fields": ( "is_staff", "is_active", "is_superuser", "groups", "user_permissions", ) }, ), ( _("Password"), { "fields": ( "password_changed", "password_changed_date", ) }, ), ) """ ユーザー編集時のフィールドセット。 """ add_fieldsets = ( ( None, { "classes": ("wide",), "fields": ("login_id", "username", "_email", "password1", "password2"), }, ), ) """ ユーザー追加時のフィールドセット。 """ @trace_log def get_primary_email(self, obj): """プライマリのメールアドレスを返します。 Return: プライマリのメールアドレス。 """ primary_email = obj.get_primary_email() return primary_email if primary_email else _("None") get_primary_email.short_description = _("Email") """ プライマリメールアドレスの詳細。 """ @trace_log def save_model(self, request, obj, form, change): """`email` が渡された場合、EmailAddress に保存します。""" super().save_model(request, obj, form, change) email = form.cleaned_data.get("_email") if email and not EmailAddress.objects.filter(user=obj, email=email).exists(): EmailAddress.objects.create(user=obj, email=email, is_primary=True) class CustomGroupInline(admin.TabularInline): """カスタムグループインライン表示用""" model = CustomGroup extra = 1 fk_name = "group" verbose_name = _("Group Information") verbose_name_plural = _("Group Information") class GroupAdmin(admin.ModelAdmin): inlines = [ CustomGroupInline, ] """ インライン表示。 """ admin.site.unregister(Group) admin.site.register(Group, GroupAdmin)