BlogVenv\Lib\site-packages\django\contrib\auth\admin.py
from allauth.socialaccount.models import SocialAccount # 추가
...
@admin.register(User)
class UserAdmin(admin.ModelAdmin):
add_form_template = 'admin/auth/user/add_form.html'
change_user_password_template = None
fieldsets = (
(None, {'fields': ('username', 'password')}),
(_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}),
(_('Permissions'), {
'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions'),
}),
(_('Important dates'), {'fields': ('last_login', 'date_joined')}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('username', 'password1', 'password2'),
}),
)
form = UserChangeForm
add_form = UserCreationForm
change_password_form = AdminPasswordChangeForm
list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff', 'getSocialAccount') # getSocialAccount 추가
list_filter = ('is_staff', 'is_superuser', 'is_active', 'groups')
search_fields = ('username', 'first_name', 'last_name', 'email')
ordering = ('username',)
filter_horizontal = ('groups', 'user_permissions',)
# 추가
def getSocialAccount(self, user):
try:
sa = SocialAccount.objects.get(user=user)
except SocialAccount.DoesNotExist as e:
sa = None
return sa.provider if sa else ""
getSocialAccount.short_description = "Social Account"
...
각 User별로 건건이 Query한다. 비효율적이다.
admin mode에서 queryset을 join문으로 override하는 방법 찾아봐야한다.
개선된 소스
@admin.register(User)
class UserAdmin(admin.ModelAdmin):
add_form_template = 'admin/auth/user/add_form.html'
change_user_password_template = None
fieldsets = (
(None, {'fields': ('username', 'password')}),
(_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}),
(_('Permissions'), {
'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions'),
}),
(_('Important dates'), {'fields': ('last_login', 'date_joined')}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('username', 'password1', 'password2'),
}),
)
form = UserChangeForm
add_form = UserCreationForm
change_password_form = AdminPasswordChangeForm
list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff', 'getSocialAccount')
list_filter = ('is_staff', 'is_superuser', 'is_active', 'groups')
search_fields = ('username', 'first_name', 'last_name', 'email')
ordering = ('username',)
filter_horizontal = ('groups', 'user_permissions',)
'''
https://docs.djangoproject.com/en/3.0/ref/models/querysets/#filteredrelation-object
get_queryset method를 override하여 left outer join을 한다.
그리고 list_display에서 바로 queryset에서 지정한 provider alias를 바로 호출할 수는 없기때문에 기존처럼 getSocialAccount를 통하여 조회한다.
'''
def get_queryset(self, request):
qs = admin.ModelAdmin.get_queryset(self, request)
qs = qs.annotate(SocalAccount=FilteredRelation("socialaccount"))
qs = qs.annotate(provider=F("socialaccount__provider"))
return qs
def getSocialAccount(self, user):
return user.provider
getSocialAccount.short_description = "Social Account"
User가 속한 Group도 표시해보자. (최종버전)
prefetch_related를 활용하여 -> http://blog.daonelab.com/post/12/1653/
from django.conf import settings
from django.contrib import admin, messages
from django.contrib.admin.options import IS_POPUP_VAR
from django.contrib.admin.utils import unquote
from django.contrib.auth import update_session_auth_hash
from django.contrib.auth.forms import (
AdminPasswordChangeForm, UserChangeForm, UserCreationForm,
)
from django.contrib.auth.models import Group, User
from django.core.exceptions import PermissionDenied
from django.db import router, transaction
from django.db.models import F, FilteredRelation # 추가
from django.http import Http404, HttpResponseRedirect
from django.template.response import TemplateResponse
from django.urls import path, reverse
from django.utils.decorators import method_decorator
from django.utils.html import escape
from django.utils.translation import gettext, gettext_lazy as _
from django.views.decorators.csrf import csrf_protect
from django.views.decorators.debug import sensitive_post_parameters
...
@admin.register(User)
class UserAdmin(admin.ModelAdmin):
add_form_template = 'admin/auth/user/add_form.html'
change_user_password_template = None
fieldsets = (
(None, {'fields': ('username', 'password')}),
(_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}),
(_('Permissions'), {
'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions'),
}),
(_('Important dates'), {'fields': ('last_login', 'date_joined')}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('username', 'password1', 'password2'),
}),
)
form = UserChangeForm
add_form = UserCreationForm
change_password_form = AdminPasswordChangeForm
list_display = ('username', 'email', 'first_name', 'last_name', 'is_active', 'is_staff', 'is_superuser', 'getSocialAccount', 'getGroups')
list_filter = ('is_staff', 'is_superuser', 'is_active', 'groups')
search_fields = ('username', 'first_name', 'last_name', 'email')
ordering = ('username',)
filter_horizontal = ('groups', 'user_permissions',)
'''
https://docs.djangoproject.com/en/3.0/ref/models/querysets/#filteredrelation-object
https://docs.djangoproject.com/en/3.0/ref/models/querysets/#prefetch-related
Override the get_queryset method to perform a left outer join.
Also, provider alias specified in queryset cannot be called directly in list_display,
so retrieve through getSocialAccount as before.
'''
def get_queryset(self, request):
qs = admin.ModelAdmin.get_queryset(self, request)
qs = qs.annotate(SocalAccount=FilteredRelation("socialaccount"))
qs = qs.annotate(provider=F("socialaccount__provider"))
qs = qs.prefetch_related("groups")
return qs
def getSocialAccount(self, user):
return user.provider
getSocialAccount.short_description = "Social Account"
def getGroups(self, user):
return ", ".join(group.name for group in user.groups.all())
getGroups.short_description = "Groups"
...
um.. 완벽해