265 lines
7.1 KiB
Python
265 lines
7.1 KiB
Python
from django.contrib import admin, messages
|
|
from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME
|
|
from django.contrib.auth import get_user_model
|
|
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
|
|
from django.contrib.auth.forms import SetPasswordForm
|
|
from django.db import transaction
|
|
from django.shortcuts import redirect
|
|
from django.template.response import TemplateResponse
|
|
from django.urls import reverse_lazy
|
|
from import_export import resources
|
|
from unfold.decorators import action as unfold_action
|
|
|
|
from core.admins.base import BaseAdmin, SoftDeleteListFilter
|
|
|
|
from apps.users.models import UserSocialAccount
|
|
from apps.users.services.forms import CustomUserChangeForm, CustomUserCreationForm
|
|
|
|
User = get_user_model()
|
|
|
|
|
|
class UserResource(resources.ModelResource):
|
|
class Meta:
|
|
model = User
|
|
|
|
|
|
class UserSocialAccountInline(admin.TabularInline):
|
|
model = UserSocialAccount
|
|
fk_name = "user"
|
|
extra = 0
|
|
autocomplete_fields = ("user",)
|
|
fields = (
|
|
"provider",
|
|
"provider_user_id",
|
|
"email",
|
|
"email_verified",
|
|
"avatar_url",
|
|
"is_deleted",
|
|
"created_at",
|
|
"updated_at",
|
|
)
|
|
readonly_fields = (
|
|
"provider",
|
|
"provider_user_id",
|
|
"email",
|
|
"email_verified",
|
|
"avatar_url",
|
|
"is_deleted",
|
|
"created_at",
|
|
"updated_at",
|
|
)
|
|
show_change_link = True
|
|
|
|
|
|
@admin.register(User)
|
|
class CustomUserAdmin(BaseUserAdmin, BaseAdmin):
|
|
model = User
|
|
resource_class = UserResource
|
|
form = CustomUserChangeForm
|
|
add_form = CustomUserCreationForm
|
|
list_display = (
|
|
"full_name",
|
|
"mobile",
|
|
"is_verified",
|
|
"is_staff",
|
|
"created_at",
|
|
"updated_at",
|
|
"is_active",
|
|
"is_deleted",
|
|
)
|
|
list_editable = ("mobile",)
|
|
search_fields = (
|
|
"first_name",
|
|
"last_name",
|
|
"mobile",
|
|
"email",
|
|
)
|
|
list_filter = (
|
|
SoftDeleteListFilter,
|
|
"is_verified",
|
|
"is_active",
|
|
"is_staff",
|
|
"is_superuser",
|
|
"is_deleted",
|
|
"created_at",
|
|
)
|
|
ordering = ("-created_at",)
|
|
readonly_fields = (
|
|
"id",
|
|
"created_at",
|
|
"updated_at",
|
|
"deleted_at",
|
|
"last_login",
|
|
"date_joined",
|
|
)
|
|
date_hierarchy = "created_at"
|
|
actions = (
|
|
"hard_delete_selected",
|
|
"restore_selected",
|
|
"mark_verified",
|
|
"mark_unverified",
|
|
"activate_users",
|
|
"deactivate_users",
|
|
)
|
|
|
|
fieldsets = (
|
|
(None, {"fields": ("id", "mobile", "password")}),
|
|
(
|
|
"Personal Info",
|
|
{
|
|
"fields": (
|
|
"first_name",
|
|
"last_name",
|
|
"email",
|
|
"profile_picture",
|
|
"birth_date",
|
|
"description",
|
|
)
|
|
},
|
|
),
|
|
(
|
|
"Permissions",
|
|
{
|
|
"fields": (
|
|
"is_verified",
|
|
"is_active",
|
|
"is_staff",
|
|
"is_superuser",
|
|
"groups",
|
|
"user_permissions",
|
|
)
|
|
},
|
|
),
|
|
("Audit", {"fields": ("created_by", "updated_by")}),
|
|
(
|
|
"Important Dates",
|
|
{
|
|
"fields": (
|
|
"last_login",
|
|
"date_joined",
|
|
"created_at",
|
|
"updated_at",
|
|
"deleted_at",
|
|
"is_deleted",
|
|
"password_updated_at",
|
|
)
|
|
},
|
|
),
|
|
)
|
|
add_fieldsets = (
|
|
(
|
|
None,
|
|
{
|
|
"classes": ("wide",),
|
|
"fields": (
|
|
"mobile",
|
|
"password1",
|
|
"password2",
|
|
"first_name",
|
|
"last_name",
|
|
"email",
|
|
"profile_picture",
|
|
"is_verified",
|
|
"is_active",
|
|
),
|
|
},
|
|
),
|
|
)
|
|
filter_horizontal = ("groups", "user_permissions")
|
|
inlines = (UserSocialAccountInline,)
|
|
|
|
actions_row = [
|
|
"reset_password_action",
|
|
]
|
|
|
|
@unfold_action(description="Reset user password")
|
|
def reset_password_action(self, request, object_id):
|
|
user = User.objects.get(pk=object_id)
|
|
form = SetPasswordForm(user=user, data=request.POST or None)
|
|
|
|
if request.method == "POST" and form.is_valid():
|
|
password = form.cleaned_data["new_password1"]
|
|
user.set_password(password)
|
|
user.save()
|
|
messages.success(request, f"User '{user}' - password reset.")
|
|
changelist_url = reverse_lazy(
|
|
f"admin:{self.model._meta.app_label}_{self.model._meta.model_name}_changelist"
|
|
)
|
|
return redirect(changelist_url)
|
|
|
|
context = {
|
|
**self.admin_site.each_context(request),
|
|
"title": "Reset User Password",
|
|
"opts": self.model._meta,
|
|
"form": form,
|
|
"action_name": "reset_password",
|
|
"action_checkbox_name": ACTION_CHECKBOX_NAME,
|
|
}
|
|
return TemplateResponse(request, "forms/admin_reset_password.html", context)
|
|
|
|
@admin.action(description="Mark selected users as verified")
|
|
def mark_verified(self, request, queryset):
|
|
queryset.update(is_verified=True)
|
|
|
|
@admin.action(description="Mark selected users as unverified")
|
|
def mark_unverified(self, request, queryset):
|
|
queryset.update(is_verified=False)
|
|
|
|
@admin.action(description="Activate selected users")
|
|
def activate_users(self, request, queryset):
|
|
queryset.update(is_active=True)
|
|
|
|
@admin.action(description="Deactivate selected users")
|
|
def deactivate_users(self, request, queryset):
|
|
queryset.update(is_active=False)
|
|
|
|
|
|
@admin.register(UserSocialAccount)
|
|
class UserSocialAccountAdmin(BaseAdmin):
|
|
list_display = (
|
|
"provider",
|
|
"provider_user_id",
|
|
"user",
|
|
"email",
|
|
"email_verified",
|
|
"created_at",
|
|
"is_deleted",
|
|
)
|
|
search_fields = (
|
|
"provider_user_id",
|
|
"email",
|
|
"user__mobile",
|
|
"user__first_name",
|
|
"user__last_name",
|
|
)
|
|
list_filter = (
|
|
SoftDeleteListFilter,
|
|
"provider",
|
|
"email_verified",
|
|
"is_deleted",
|
|
"created_at",
|
|
)
|
|
readonly_fields = (
|
|
"id",
|
|
"created_at",
|
|
"updated_at",
|
|
"deleted_at",
|
|
)
|
|
autocomplete_fields = ("user",)
|
|
actions = (
|
|
"unlink_selected",
|
|
"hard_delete_selected",
|
|
"restore_selected",
|
|
)
|
|
|
|
@admin.action(description="Unlink selected social accounts")
|
|
def unlink_selected(self, request, queryset):
|
|
count = queryset.count()
|
|
with transaction.atomic():
|
|
queryset.hard_delete()
|
|
self.message_user(
|
|
request,
|
|
f"{count} social account link(s) permanently removed.",
|
|
level=messages.SUCCESS,
|
|
)
|