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