Files
hossein-por-shop/backend/account/admin.py
T

173 lines
7.4 KiB
Python

from rest_framework_simplejwt.token_blacklist.models import BlacklistedToken, OutstandingToken
from django.contrib import admin
from .models import *
from unfold.admin import TabularInline
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from import_export.admin import ImportExportModelAdmin
from unfold.contrib.import_export.forms import ExportForm, ImportForm, SelectableFieldsExportForm
from unfold.contrib.forms.widgets import ArrayWidget, WysiwygWidget
from django.contrib.postgres.fields import ArrayField
from django.contrib.auth.models import Group
from unfold.forms import AdminPasswordChangeForm
from unfold.forms import AdminPasswordChangeForm, UserChangeForm, UserCreationForm
from utils.admin import ModelAdmin
from django.template.loader import render_to_string
from folium import Map, Marker
from unfold.decorators import action, display
from django.utils.html import format_html
from account.models import SpecialDiscountCode
from .permissions import UserAdminPermission, SpecialDiscountCodeAdminPermission
@admin.register(SpecialDiscountCode)
class SpecialDiscountCodeAdmin(SpecialDiscountCodeAdminPermission, ModelAdmin):
pass
class UserAddressInLine(TabularInline):
model = UserAddressModel
extra = 0
tab = True
verbose_name = 'ادرس کاربر'
verbose_name_plural = 'ادرس های کاربر'
@admin.register(User)
class UserAdmin(BaseUserAdmin, UserAdminPermission, ModelAdmin, ImportExportModelAdmin):
form = UserChangeForm
add_form = UserCreationForm
change_password_form = AdminPasswordChangeForm
filter_horizontal = ('groups', 'user_permissions',)
ordering = []
inlines = [UserAddressInLine]
list_filter = ['is_superuser']
search_fields = ['phone', 'first_name', 'last_name', 'email']
list_display = ['full_name_display', 'phone',
'email', 'is_superuser', 'gender', 'birth_date']
# readonly_fields = ['phone', 'email', 'otp_expiry', 'otp_hash', 'date_joined', 'profile_photo']
exclude = ('otp_hash', 'otp_expiry', 'is_active',
'password', 'last_login',)
import_form_class = ImportForm
export_form_class = ExportForm
fieldsets = (
('اطلاعات شخصی', {'fields': ('first_name', 'last_name',
'profile_photo', 'gender', 'birth_date'), }),
('اطلاعات ارتباطی', {'fields': ('phone', 'email'), }),
('دسترسی های وبسایت', {
'fields': ('is_superuser', 'is_staff', 'video_uploader'), }),
('گروه ها و مجوزها', {'fields': ('groups', 'user_permissions',)}),
)
empty_value_display = 'ثبت نشده'
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('phone', 'password1', 'password2'),
}),
('دسترسی ها', {
'fields': ('groups', 'user_permissions', 'is_superuser', 'is_staff', 'video_uploader'),
}),
)
def display_groups(self, obj):
"""Display user's groups in the list view"""
return ", ".join([group.name for group in obj.groups.all()]) or "هیچ گروهی"
display_groups.short_description = 'گروه ها'
compressed_fields = True
warn_unsaved_form = True
formfield_overrides = {
ArrayField: {
"widget": ArrayWidget,
}
}
def full_name_display(self, obj):
return obj.full_name
full_name_display.short_description = 'نام و نام خانوادگی'
# admin.site.unregister(Group)
admin.site.unregister(BlacklistedToken)
admin.site.unregister(OutstandingToken)
@admin.register(UserAddressModel)
class AddressAdmin(ModelAdmin, ImportExportModelAdmin):
import_form_class = ImportForm
export_form_class = ExportForm
search_fields = ['address', 'name', 'city', 'province']
list_display = ['user', 'name', 'address_display',
'postal_code', 'city', 'province', 'for_me', 'is_main']
# readonly_fields = ['user', 'name', 'address', 'postal_code', 'phone', 'city', 'province', 'for_me']
compressed_fields = True
warn_unsaved_form = True
formfield_overrides = {
models.TextField: {
"widget": WysiwygWidget,
},
ArrayField: {
"widget": ArrayWidget,
}
}
def address_display(self, obj):
return obj.address[0:35] + '...'
address_display.short_description = 'ادرس'
@admin.register(PushSubscription)
class PushSubscription(ModelAdmin, ImportExportModelAdmin):
import_form_class = ImportForm
export_form_class = ExportForm
compressed_fields = True
warn_unsaved_form = True
@admin.register(SecurityBreachAttemptModel)
class SecurityBreachAttemptAdmin(ModelAdmin, ImportExportModelAdmin):
import_form_class = ImportForm
export_form_class = ExportForm
compressed_fields = True
warn_unsaved_form = True
change_form_template = 'loction_chagne_form.html'
list_display = ['ip_address', 'country', 'region_name', 'city',
'zip_code', 'isp', 'created_at', 'trys', 'display_viewd']
def change_view(self, request, object_id, form_url='', extra_context=None):
extra_context = extra_context or {}
obj = self.get_object(request, object_id)
if obj and obj.lat and obj.lon:
m = Map(location=[obj.lat, obj.lon], zoom_start=10)
Marker([obj.lat, obj.lon],
popup=f"Location: {obj.ip_address}").add_to(m)
map_html = m._repr_html_()
extra_context['map_html'] = map_html
return super().change_view(request, object_id, form_url, extra_context)
@display(description='دیده شده')
def display_viewd(self, instance):
if instance.viewd:
svg = f'<a href="/accounts/attack/view/{instance.id}"><svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" viewBox="0 0 24 24"><path fill="green" d="M12 16q1.875 0 3.188-1.312T16.5 11.5t-1.312-3.187T12 7T8.813 8.313T7.5 11.5t1.313 3.188T12 16m0-1.8q-1.125 0-1.912-.788T9.3 11.5t.788-1.912T12 8.8t1.913.788t.787 1.912t-.787 1.913T12 14.2m0 4.8q-3.65 0-6.65-2.037T1 11.5q1.35-3.425 4.35-5.462T12 4t6.65 2.038T23 11.5q-1.35 3.425-4.35 5.463T12 19m0-2q2.825 0 5.188-1.487T20.8 11.5q-1.25-2.525-3.613-4.012T12 6T6.813 7.488T3.2 11.5q1.25 2.525 3.613 4.013T12 17"/></svg></a>'
else:
svg = f'<a href="/accounts/attack/view/{instance.id}"><svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" viewBox="0 0 24 24"><path fill="#c30009" d="m19.1 21.9l-3.5-3.45q-.875.275-1.775.413T12 19q-3.35 0-6.125-1.8t-4.35-4.75q-.125-.225-.187-.462t-.063-.488t.063-.488t.187-.462q.55-.975 1.175-1.9T4.15 7L2.075 4.9Q1.8 4.625 1.8 4.213t.3-.713q.275-.275.7-.275t.7.275l17 17q.275.275.288.688t-.288.712q-.275.275-.7.275t-.7-.275M12 16q.275 0 .525-.025t.5-.1l-5.4-5.4q-.075.25-.1.5T7.5 11.5q0 1.875 1.313 3.188T12 16m0-12q3.35 0 6.138 1.813t4.362 4.762q.125.2.188.438t.062.487t-.05.488t-.175.437q-.475.925-1.062 1.75t-1.313 1.55q-.35.35-.825.325t-.825-.375l-2-2q-.175-.175-.225-.413t.025-.487q.1-.325.15-.625t.05-.65q0-1.875-1.312-3.187T12 7q-.35 0-.65.05t-.625.15q-.25.075-.5.025T9.8 7l-.825-.825q-.475-.475-.312-1.1t.787-.8q.625-.125 1.263-.2T12 4m1.975 5.65q.275.325.462.713t.238.812q.025.2-.15.275t-.325-.075l-2.05-2.05Q12 9.175 12.088 9t.287-.175q.475.05.875.263t.725.562"/></svg></a>'
return format_html(
svg
)
@admin.register(NewsModel)
class NewsAdmin(ModelAdmin):
pass
@admin.register(UserNotificationModel)
class UserNotificationAdmin(ModelAdmin):
pass