137 lines
6.5 KiB
Python
137 lines
6.5 KiB
Python
from django.contrib import admin
|
|
from .models import *
|
|
from unfold.admin import ModelAdmin, 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
|
|
|
|
|
|
class UserAddressInLine(TabularInline):
|
|
model = UserAddressModel
|
|
extra = 0
|
|
tab = True
|
|
verbose_name = 'ادرس کاربر'
|
|
verbose_name_plural = 'ادرس های کاربر'
|
|
|
|
@admin.register(User)
|
|
class UserAdmin(BaseUserAdmin, ModelAdmin, ImportExportModelAdmin):
|
|
form = UserChangeForm
|
|
add_form = UserCreationForm
|
|
change_password_form = AdminPasswordChangeForm
|
|
filter_horizontal = []
|
|
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', 'is_staff', 'password', 'last_login',)
|
|
import_form_class = ImportForm
|
|
export_form_class = ExportForm
|
|
fieldsets = (
|
|
('اطلاعات شخصی', {'fields': ('first_name', 'last_name', 'profile_photo', 'password', 'gender', 'birth_date'),}),
|
|
('اطلاعات ارتباطی', {'fields': ('phone', 'email'),}),
|
|
('دسترسی های وبسایت', {'fields': ('is_superuser', 'video_uploader'),}),
|
|
)
|
|
empty_value_display = 'ثبت نشده'
|
|
add_fieldsets = (
|
|
(None, {
|
|
'classes': ('wide',),
|
|
'fields': ('phone', 'password1', 'password2'),
|
|
}),
|
|
)
|
|
|
|
|
|
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)
|
|
from django.contrib import admin
|
|
from rest_framework_simplejwt.token_blacklist.models import BlacklistedToken, OutstandingToken
|
|
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
|
|
) |