diff --git a/allianceauth/authentication/admin.py b/allianceauth/authentication/admin.py
index 12ec14fa..a3df70b2 100644
--- a/allianceauth/authentication/admin.py
+++ b/allianceauth/authentication/admin.py
@@ -100,63 +100,153 @@ class UserProfileInline(admin.StackedInline):
return False
-class UserAdmin(BaseUserAdmin):
+def user_profile_pic(obj):
+ """profile pic column data for user objects
+
+ works for both User objects and objects with `user` as FK to User
+ To be used for all user based admin lists (requires CSS)
"""
- Extending Django's UserAdmin model
+ user_obj = obj.user if hasattr(obj, 'user') else obj
+ if user_obj.profile.main_character:
+ return format_html(
+ '
',
+ user_obj.profile.main_character.portrait_url(size=32)
+ )
+ else:
+ return ''
+user_profile_pic.short_description = ''
+
+
+def user_username(obj):
+ """user column data for user objects
+
+ works for both User objects and objects with `user` as FK to User
+ To be used for all user based admin lists
+ """
+ link = reverse(
+ 'admin:{}_{}_change'.format(
+ obj._meta.app_label,
+ type(obj).__name__.lower()
+ ),
+ args=(obj.pk,)
+ )
+ user_obj = obj.user if hasattr(obj, 'user') else obj
+ return format_html(
+ '{}
{}',
+ link,
+ user_obj.username,
+ user_obj.profile.main_character.character_name \
+ if user_obj.profile.main_character else ''
+ )
+
+user_username.short_description = 'user / main'
+user_username.admin_order_field = 'username'
+
+
+def user_main_organization(obj):
+ """main organization column data for user objects
+
+ works for both User objects and objects with `user` as FK to User
+ To be used for all user based admin lists
+ """
+ user_obj = obj.user if hasattr(obj, 'user') else obj
+ if user_obj.profile.main_character:
+ corporation = user_obj.profile.main_character.corporation_name
+ else:
+ corporation = ''
+ if (user_obj.profile.main_character
+ and user_obj.profile.main_character.alliance_id
+ ):
+ alliance = user_obj.profile.main_character.alliance_name
+ else:
+ alliance = ''
+ return format_html('{}
{}',
+ corporation,
+ alliance
+ )
+
+user_main_organization.short_description = 'Corporation / Alliance (Main)'
+user_main_organization.admin_order_field = \
+ 'profile__main_character__corporation_name'
+
+
+class MainCorporationsFilter(admin.SimpleListFilter):
+ """Custom filter to filter on corporations from mains only
+
+ works for both User objects and objects with `user` as FK to User
+ To be used for all user based admin lists
+ """
+ title = 'corporation'
+ parameter_name = 'main_corporations'
+
+ def lookups(self, request, model_admin):
+ qs = EveCharacter.objects\
+ .exclude(userprofile=None)\
+ .values('corporation_id', 'corporation_name')\
+ .distinct()\
+ .order_by(Lower('corporation_name'))
+ return tuple(
+ [(x['corporation_id'], x['corporation_name']) for x in qs]
+ )
+
+ def queryset(self, request, qs):
+ if self.value() is None:
+ return qs.all()
+ else:
+ if qs.model == User:
+ return qs\
+ .filter(profile__main_character__corporation_id=\
+ self.value())
+ else:
+ return qs\
+ .filter(user__profile__main_character__corporation_id=\
+ self.value())
+
+
+class MainAllianceFilter(admin.SimpleListFilter):
+ """Custom filter to filter on alliances from mains only
+
+ works for both User objects and objects with `user` as FK to User
+ To be used for all user based admin lists
+ """
+ title = 'alliance'
+ parameter_name = 'main_alliances'
+
+ def lookups(self, request, model_admin):
+ qs = EveCharacter.objects\
+ .exclude(alliance_id=None)\
+ .exclude(userprofile=None)\
+ .values('alliance_id', 'alliance_name')\
+ .distinct()\
+ .order_by(Lower('alliance_name'))
+ return tuple(
+ [(x['alliance_id'], x['alliance_name']) for x in qs]
+ )
+
+ def queryset(self, request, qs):
+ if self.value() is None:
+ return qs.all()
+ else:
+ if qs.model == User:
+ return qs\
+ .filter(profile__main_character__alliance_id=self.value())
+ else:
+ return qs\
+ .filter(user__profile__main_character__alliance_id=\
+ self.value())
+
+
+class UserAdmin(BaseUserAdmin):
+ """Extending Django's UserAdmin model
+
+ Behavior of groups and characters columns can be configured via settings
+
"""
class Media:
css = {
"all": ("authentication/css/admin.css",)
}
-
-
- class MainCorporationsFilter(admin.SimpleListFilter):
- """Custom filter to filter on corporations from mains only"""
- title = 'corporation'
- parameter_name = 'main_corporations'
-
- def lookups(self, request, model_admin):
- qs = EveCharacter.objects\
- .exclude(userprofile=None)\
- .values('corporation_id', 'corporation_name')\
- .distinct()\
- .order_by(Lower('corporation_name'))
- return tuple(
- [(x['corporation_id'], x['corporation_name']) for x in qs]
- )
-
- def queryset(self, request, queryset):
- if self.value() is None:
- return queryset.all()
- else:
- return queryset\
- .filter(profile__main_character__corporation_id=self.value())
-
-
- class MainAllianceFilter(admin.SimpleListFilter):
- """Custom filter to filter on alliances from mains only"""
- title = 'alliance'
- parameter_name = 'main_alliances'
-
- def lookups(self, request, model_admin):
- qs = EveCharacter.objects\
- .exclude(alliance_id=None)\
- .exclude(userprofile=None)\
- .values('alliance_id', 'alliance_name')\
- .distinct()\
- .order_by(Lower('alliance_name'))
- return tuple(
- [(x['alliance_id'], x['alliance_name']) for x in qs]
- )
-
- def queryset(self, request, queryset):
- if self.value() is None:
- return queryset.all()
- else:
- return queryset\
- .filter(profile__main_character__alliance_id=self.value())
-
class RealGroupsFilter(admin.SimpleListFilter):
"""Custom filter to get groups w/o Autogroups"""
@@ -167,8 +257,8 @@ class UserAdmin(BaseUserAdmin):
qs = Group.objects.all().order_by(Lower('name'))
if _has_auto_groups:
qs = qs\
- .filter(managedalliancegroup__exact=None)\
- .filter(managedcorpgroup__exact=None)
+ .filter(managedalliancegroup__isnull=True)\
+ .filter(managedcorpgroup__isnull=True)
return tuple([(x.pk, x.name) for x in qs])
def queryset(self, request, queryset):
@@ -208,20 +298,24 @@ class UserAdmin(BaseUserAdmin):
# Check update_groups is redefined/overloaded
if svc.update_groups.__module__ != ServicesHook.update_groups.__module__:
action = make_service_hooks_update_groups_action(svc)
- actions[action.__name__] = (action,
- action.__name__,
- action.short_description)
+ actions[action.__name__] = (
+ action,
+ action.__name__,
+ action.short_description
+ )
+
# Create sync nickname action if service implements it
if svc.sync_nickname.__module__ != ServicesHook.sync_nickname.__module__:
action = make_service_hooks_sync_nickname_action(svc)
- actions[action.__name__] = (action,
- action.__name__,
- action.short_description)
-
+ actions[action.__name__] = (
+ action, action.__name__,
+ action.short_description
+ )
return actions
+
def _list_2_html_w_tooltips(self, my_items: list, max_items: int) -> str:
- """converts list of strings into HTML with cutoff and tooltip when > max"""
+ """converts list of strings into HTML with cutoff and tooltip"""
items_truncated_str = ', '.join(my_items[:max_items])
if len(my_items) <= max_items:
return items_truncated_str
@@ -242,11 +336,11 @@ class UserAdmin(BaseUserAdmin):
show_full_result_count = True
list_display = (
- '_profile_pic',
- '_user',
+ user_profile_pic,
+ user_username,
'_state',
'_groups',
- '_main_organization',
+ user_main_organization,
'_characters',
'is_active',
'date_joined',
@@ -269,67 +363,13 @@ class UserAdmin(BaseUserAdmin):
'character_ownerships__character__character_name'
)
-
- def _profile_pic(self, obj):
- """profile pic column data for user objects"""
- if obj.profile.main_character:
- return format_html(
- '
',
- obj.profile.main_character.portrait_url(size=32)
- )
- else:
- return ''
- _profile_pic.short_description = ''
-
-
- def _user(self, obj):
- """user column data for user objects"""
- link = reverse(
- 'admin:{}_{}_change'.format(
- obj._meta.app_label,
- type(obj).__name__.lower()
- ),
- args=(obj.pk,)
- )
- return format_html(
- '{}
{}',
- link,
- obj.username,
- obj.profile.main_character.character_name \
- if obj.profile.main_character else ''
- )
-
- _user.short_description = 'user / main'
- _user.admin_order_field = 'username'
-
-
- def _main_organization(self, obj):
- """main organization column data for user objects"""
- if obj.profile.main_character:
- corporation = obj.profile.main_character.corporation_name
- else:
- corporation = ''
- if (obj.profile.main_character
- and obj.profile.main_character.alliance_id
- ):
- alliance = obj.profile.main_character.alliance_name
- else:
- alliance = ''
- return format_html('{}
{}',
- corporation,
- alliance
- )
-
- _main_organization.short_description = 'Corporation / Alliance (Main)'
- _main_organization.admin_order_field = \
- 'profile__main_character__corporation_name'
-
def _characters(self, obj):
my_characters = [
x.character.character_name
for x in CharacterOwnership.objects\
.filter(user=obj)\
- .order_by('character__character_name')
+ .order_by('character__character_name')\
+ .select_related()
]
return self._list_2_html_w_tooltips(
my_characters,
@@ -352,8 +392,8 @@ class UserAdmin(BaseUserAdmin):
else:
my_groups = [
x.name for x in obj.groups\
- .filter(managedalliancegroup=None)\
- .filter(managedcorpgroup=None)\
+ .filter(managedalliancegroup__isnull=True)\
+ .filter(managedcorpgroup__isnull=True)\
.order_by('name')
]
@@ -425,61 +465,12 @@ class BaseOwnershipAdmin(admin.ModelAdmin):
css = {
"all": ("authentication/css/admin.css",)
}
-
- class MainCorporationsFilter(admin.SimpleListFilter):
- """Custom filter to filter on corporations from mains only"""
- title = 'corporation'
- parameter_name = 'main_corporations'
-
- def lookups(self, request, model_admin):
- qs = EveCharacter.objects\
- .exclude(userprofile=None)\
- .values('corporation_id', 'corporation_name')\
- .distinct()\
- .order_by(Lower('corporation_name'))
- return tuple(
- [(x['corporation_id'], x['corporation_name']) for x in qs]
- )
-
- def queryset(self, request, queryset):
- if self.value() is None:
- return queryset.all()
- else:
- return queryset.filter(
- user__profile__main_character__corporation_id=self.value()
- )
-
-
- class MainAllianceFilter(admin.SimpleListFilter):
- """Custom filter to filter on alliances from mains only"""
- title = 'alliance'
- parameter_name = 'main_alliances'
-
- def lookups(self, request, model_admin):
- qs = EveCharacter.objects\
- .exclude(alliance_id=None)\
- .exclude(userprofile=None)\
- .values('alliance_id', 'alliance_name')\
- .distinct()\
- .order_by(Lower('alliance_name'))
- return tuple(
- [(x['alliance_id'], x['alliance_name']) for x in qs]
- )
-
- def queryset(self, request, queryset):
- if self.value() is None:
- return queryset.all()
- else:
- return queryset.filter(
- user__profile__main_character__alliance_id=self.value()
- )
-
-
+
list_select_related = True
list_display = (
- '_profile_pic',
- '_user',
- '_main_organization',
+ user_profile_pic,
+ user_username,
+ user_main_organization,
'character',
)
search_fields = (
@@ -498,61 +489,6 @@ class BaseOwnershipAdmin(admin.ModelAdmin):
return 'owner_hash', 'character'
return tuple()
-
- def _profile_pic(self, obj):
- """profile pic column data for user objects"""
- if obj.user.profile.main_character:
- return format_html(
- '
',
- obj.user.profile.main_character.portrait_url(size=32)
- )
- else:
- return ''
- _profile_pic.short_description = ''
-
-
- def _user(self, obj):
- """user column data for user objects"""
- link = reverse(
- 'admin:{}_{}_change'.format(
- obj._meta.app_label,
- type(obj).__name__.lower()
- ),
- args=(obj.pk,)
- )
- return format_html(
- '{}
{}',
- link,
- obj.user.username,
- obj.user.profile.main_character.character_name \
- if obj.user.profile.main_character else ''
- )
-
- _user.short_description = 'user / main'
- _user.admin_order_field = 'user__username'
-
-
- def _main_organization(self, obj):
- """main organization column data for user objects"""
- if obj.user.profile.main_character:
- corporation = obj.user.profile.main_character.corporation_name
- else:
- corporation = ''
- if (obj.user.profile.main_character
- and obj.user.profile.main_character.alliance_id
- ):
- alliance = obj.user.profile.main_character.alliance_name
- else:
- alliance = ''
- return format_html('{}
{}',
- corporation,
- alliance
- )
-
- _main_organization.short_description = 'Corporation / Alliance (Main)'
- _main_organization.admin_order_field = \
- 'user__profile__main_character__corporation_name'
-
@admin.register(OwnershipRecord)
class OwnershipRecordAdmin(BaseOwnershipAdmin):
diff --git a/allianceauth/authentication/static/authentication/css/admin.css b/allianceauth/authentication/static/authentication/css/admin.css
index b3b2a8f0..5fe8a4d8 100644
--- a/allianceauth/authentication/static/authentication/css/admin.css
+++ b/allianceauth/authentication/static/authentication/css/admin.css
@@ -4,7 +4,7 @@ CSS for allianceauth admin site
/* styling for profile pic */
.img-circle { border-radius: 50%; }
-.column-_profile_pic { width: 50px; }
+.column-user_profile_pic { width: 50px; }
/* tooltip */
.tooltip {
diff --git a/allianceauth/groupmanagement/admin.py b/allianceauth/groupmanagement/admin.py
index 5a8cf5e6..6d1a7ef0 100644
--- a/allianceauth/groupmanagement/admin.py
+++ b/allianceauth/groupmanagement/admin.py
@@ -50,11 +50,14 @@ if _has_auto_groups:
value = self.value()
if value == 'Yes':
return queryset.exclude(
- managedalliancegroup__exact=None,
- managedcorpgroup__exact=None
+ managedalliancegroup__isnull=True,
+ managedcorpgroup__isnull=True
)
elif value == 'No':
- return queryset.filter(managedalliancegroup__exact=None).filter(managedcorpgroup__exact=None)
+ return queryset.filter(
+ managedalliancegroup__isnull=True,
+ managedcorpgroup__isnull=True
+ )
else:
return queryset
diff --git a/allianceauth/services/admin.py b/allianceauth/services/admin.py
index 97e6f1d6..061b97e1 100644
--- a/allianceauth/services/admin.py
+++ b/allianceauth/services/admin.py
@@ -6,61 +6,13 @@ from django.utils.html import format_html
from allianceauth import hooks
from allianceauth.eveonline.models import EveCharacter
+from allianceauth.authentication.admin import user_profile_pic, \
+ user_username, user_main_organization, MainCorporationsFilter,\
+ MainAllianceFilter
from .models import NameFormatConfig
-class MainCorporationsFilter(admin.SimpleListFilter):
- """Custom filter to show corporations from service users only
- To be used together with ServicesUserAdmin class
- """
- title = 'corporation'
- parameter_name = 'main_corporations'
-
- def lookups(self, request, model_admin):
- qs = EveCharacter.objects\
- .exclude(userprofile=None)\
- .values('corporation_id', 'corporation_name')\
- .distinct()\
- .order_by(Lower('corporation_name'))
- return tuple(
- [(x['corporation_id'], x['corporation_name']) for x in qs]
- )
-
- def queryset(self, request, queryset):
- if self.value() is None:
- return queryset.all()
- else:
- return queryset\
- .filter(user__profile__main_character__corporation_id=self.value())
-
-
-class MainAllianceFilter(admin.SimpleListFilter):
- """Custom filter to show alliances from service users only
- To be used together with ServicesUserAdmin class
- """
- title = 'alliance'
- parameter_name = 'main_alliances'
-
- def lookups(self, request, model_admin):
- qs = EveCharacter.objects\
- .exclude(alliance_id=None)\
- .exclude(userprofile=None)\
- .values('alliance_id', 'alliance_name')\
- .distinct()\
- .order_by(Lower('alliance_name'))
- return tuple(
- [(x['alliance_id'], x['alliance_name']) for x in qs]
- )
-
- def queryset(self, request, queryset):
- if self.value() is None:
- return queryset.all()
- else:
- return queryset\
- .filter(user__profile__main_character__alliance_id=self.value())
-
-
class ServicesUserAdmin(admin.ModelAdmin):
"""Parent class for UserAdmin classes for all services"""
class Media:
@@ -75,9 +27,9 @@ class ServicesUserAdmin(admin.ModelAdmin):
ordering = ('user__username', )
list_select_related = True
list_display = (
- '_profile_pic',
- '_user',
- '_main_organization',
+ user_profile_pic,
+ user_username,
+ user_main_organization,
'_date_joined'
)
list_filter = (
@@ -86,58 +38,6 @@ class ServicesUserAdmin(admin.ModelAdmin):
'user__date_joined'
)
- def _profile_pic(self, obj):
- if obj.user.profile.main_character:
- return format_html(
- '
',
- obj.user.profile.main_character.portrait_url(size=32)
- )
- else:
- return ''
- _profile_pic.short_description = ''
-
-
- def _user(self, obj):
- link = reverse(
- 'admin:{}_{}_change'.format(
- obj._meta.app_label,
- type(obj).__name__.lower()
- ),
- args=(obj.pk,)
- )
- return format_html(
- '{}
{}',
- link,
- obj.user.username,
- obj.user.profile.main_character.character_name \
- if obj.user.profile.main_character else ''
- )
-
- _user.short_description = 'user / main'
- _user.admin_order_field = 'user__username'
-
-
- def _main_organization(self, obj):
- if obj.user.profile.main_character:
- corporation = obj.user.profile.main_character.corporation_name
- else:
- corporation = ''
- if (obj.user.profile.main_character
- and obj.user.profile.main_character.alliance_id
- ):
- alliance = obj.user.profile.main_character.alliance_name
- else:
- alliance = ''
- return format_html('{}
{}',
- corporation,
- alliance
- )
-
- _main_organization.short_description = 'Corporation / Alliance (Main)'
- _main_organization.admin_order_field = \
- 'profile__main_character__corporation_name'
-
-
def _date_joined(self, obj):
return obj.user.date_joined
diff --git a/allianceauth/services/static/services/admin.css b/allianceauth/services/static/services/admin.css
index 72fedd99..46796c5f 100644
--- a/allianceauth/services/static/services/admin.css
+++ b/allianceauth/services/static/services/admin.css
@@ -3,4 +3,4 @@ CSS for allianceauth admin site
*/
.img-circle { border-radius: 50%; }
-.column-_profile_pic { width: 50px; }
\ No newline at end of file
+.column-user_profile_pic { width: 50px; }
\ No newline at end of file