You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
199 lines
6.8 KiB
199 lines
6.8 KiB
from django import forms
|
|
from django.contrib import admin
|
|
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
|
|
from django.contrib.auth.admin import GroupAdmin as BaseGroupAdmin
|
|
from django.contrib.auth.models import Group
|
|
from django.db import models
|
|
from django.utils.html import format_html
|
|
from django.utils.translation import gettext_lazy as _, ngettext
|
|
|
|
from rest_framework.authtoken.models import TokenProxy
|
|
from unfold.admin import ModelAdmin, StackedInline
|
|
from unfold.decorators import display
|
|
from unfold.forms import AdminPasswordChangeForm, UserChangeForm, UserCreationForm
|
|
from unfold.contrib.filters.admin import RangeDateTimeFilter
|
|
|
|
from apps.account.models import User, ClientUser, LocationHistory
|
|
from utils.admin import project_admin_site
|
|
from apps.account.admin.location import LocationHistoryInline
|
|
from apps.account.admin.verification import VerificationDocumentInline
|
|
|
|
|
|
# =========================================================
|
|
# 1. Base User Admin Form & Admin
|
|
# =========================================================
|
|
|
|
class UserAdminCreationForm(UserCreationForm):
|
|
class Meta(UserCreationForm.Meta):
|
|
model = User
|
|
fields = ("first_name", "last_name", "fullname", "email")
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
if 'email' in self.fields:
|
|
self.fields['email'].required = True
|
|
|
|
def clean_email(self):
|
|
email = self.cleaned_data.get('email')
|
|
if User.objects.filter(email=email).exists():
|
|
raise forms.ValidationError(_("A user with this email already exists."))
|
|
return email
|
|
|
|
|
|
class UserAdminChangeForm(UserChangeForm):
|
|
class Meta(UserChangeForm.Meta):
|
|
model = User
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
if 'email' in self.fields:
|
|
self.fields['email'].required = True
|
|
|
|
|
|
class UserAdmin(ModelAdmin, BaseUserAdmin):
|
|
form = UserAdminChangeForm
|
|
add_form = UserAdminCreationForm
|
|
change_password_form = AdminPasswordChangeForm
|
|
compressed_fields = False
|
|
list_display = ('first_name', 'last_name', 'fullname', 'email', 'role', 'user_type', 'is_staff', 'is_active', 'display_date_joined',)
|
|
list_display_links = ('first_name', 'last_name', 'fullname', 'email')
|
|
ordering = ("-id",)
|
|
search_fields = ('email', 'first_name', 'last_name', 'fullname', 'username',)
|
|
filter_horizontal = ('groups', 'user_permissions')
|
|
list_filter = [
|
|
"role",
|
|
"user_type",
|
|
"is_active",
|
|
"is_staff",
|
|
("last_login", RangeDateTimeFilter),
|
|
("date_joined", RangeDateTimeFilter),
|
|
]
|
|
inlines = [LocationHistoryInline, VerificationDocumentInline]
|
|
|
|
add_fieldsets = (
|
|
(None, {
|
|
'classes': ('wide',),
|
|
'fields': (
|
|
('first_name', 'last_name'),
|
|
('fullname', 'email'),
|
|
'role',
|
|
'phone_number',
|
|
('title', 'rank'),
|
|
('institution_name', 'website'),
|
|
'address',
|
|
'birthdate',
|
|
'gender',
|
|
'avatar',
|
|
'skill',
|
|
'info'
|
|
),
|
|
}),
|
|
)
|
|
|
|
fieldsets = (
|
|
(None, {
|
|
"fields": (
|
|
("first_name", "last_name"),
|
|
("fullname", "email"),
|
|
("password",),
|
|
),
|
|
}),
|
|
(_("Profile Details"), {
|
|
"classes": ["tab"],
|
|
"fields": (
|
|
("avatar",),
|
|
("phone_number", "gender"),
|
|
("title", "rank"),
|
|
("institution_name", "website"),
|
|
("address",),
|
|
("birthdate", "language"),
|
|
("skill",),
|
|
("info",),
|
|
),
|
|
}),
|
|
(_("Access & Role"), {
|
|
"classes": ["tab"],
|
|
"fields": (
|
|
("role", "user_type"),
|
|
("is_active", "is_staff", "is_superuser"),
|
|
"groups",
|
|
),
|
|
}),
|
|
(_("Granular Permissions"), {
|
|
"classes": ["tab"],
|
|
"description": _("Low-level Django database permissions assigned directly to this user. Recommended to manage permissions via Roles or Groups instead."),
|
|
"fields": (
|
|
"user_permissions",
|
|
),
|
|
}),
|
|
(_("Custom Permissions"), {
|
|
"classes": ["tab"],
|
|
"description": _("Override specific permissions for this individual user (JSON dictionary of {permission_name: True/False}). Overrides take precedence over the role defaults."),
|
|
"fields": (
|
|
"custom_permissions",
|
|
),
|
|
}),
|
|
(_("Timestamps & Metadata"), {
|
|
"classes": ["tab"],
|
|
"fields": (
|
|
("date_joined", "last_login"),
|
|
("deleted_at",),
|
|
),
|
|
}),
|
|
)
|
|
|
|
readonly_fields = ('date_joined', 'last_login')
|
|
|
|
@display(description=_("Date Joined"))
|
|
def display_date_joined(self, instance: User):
|
|
return instance.date_joined.strftime("%Y-%m-%d %H:%M") if instance.date_joined else "-"
|
|
|
|
|
|
class GroupAdmin(BaseGroupAdmin, ModelAdmin):
|
|
list_display = ('name', 'permissions_count')
|
|
list_display_links = ('name',)
|
|
search_fields = ('name',)
|
|
ordering = ('name',)
|
|
filter_horizontal = ('permissions',)
|
|
|
|
fieldsets = (
|
|
(None, {'fields': ('name',)}),
|
|
(_('Permissions'), {'fields': ('permissions',), 'classes': ['tab']}),
|
|
)
|
|
|
|
@display(description=_("Permissions"))
|
|
def permissions_count(self, obj):
|
|
count = obj.permissions.count()
|
|
return ngettext("{count} permission", "{count} permissions", count).format(count=count) if count > 0 else "-"
|
|
|
|
def has_add_permission(self, request):
|
|
return bool(request.user and request.user.is_authenticated and (request.user.is_staff or request.user.is_superuser or request.user.can_access_admin_panel()))
|
|
|
|
def has_change_permission(self, request, obj=None):
|
|
return bool(request.user and request.user.is_authenticated and (request.user.is_staff or request.user.is_superuser or request.user.can_access_admin_panel()))
|
|
|
|
def has_delete_permission(self, request, obj=None):
|
|
return bool(request.user and request.user.is_authenticated and (request.user.is_staff or request.user.is_superuser or request.user.can_access_admin_panel()))
|
|
|
|
|
|
# =========================================================
|
|
# 2. Registrations
|
|
# =========================================================
|
|
|
|
try:
|
|
admin.site.unregister(User)
|
|
except admin.sites.NotRegistered:
|
|
pass
|
|
|
|
try:
|
|
admin.site.register(User, UserAdmin)
|
|
except admin.sites.AlreadyRegistered:
|
|
pass
|
|
|
|
project_admin_site.register(User, UserAdmin)
|
|
project_admin_site.register(Group, GroupAdmin)
|
|
|
|
try:
|
|
admin.site.unregister(TokenProxy)
|
|
except admin.sites.NotRegistered:
|
|
pass
|