Просмотр исходного кода

Enhance integration of misago User with django admin

Change log:

 - allow to view some base info about a user: email, rank,
   last login date, register date

 - add link to misago admin panel in django-admin edit view of a user
   (allows quick jump to misago user edit view)
1905410 9 лет назад
Родитель
Сommit
76962e1a15
3 измененных файлов с 185 добавлено и 21 удалено
  1. 4 21
      misago/users/admin.py
  2. 131 0
      misago/users/djangoadmin.py
  3. 50 0
      misago/users/tests/test_djangoadmin_user.py

+ 4 - 21
misago/users/admin.py

@@ -1,6 +1,5 @@
 from django.conf.urls import url
 from django.contrib import admin as djadmin
-from django.contrib.auth import get_user_model
 from django.utils.translation import ugettext_lazy as _
 
 from misago.users.views.admin.bans import BansList, NewBan, EditBan, DeleteBan
@@ -13,28 +12,12 @@ from misago.users.views.admin.users import (
 from misago.users.views.admin.warnings import (
     WarningsList, NewWarning, EditWarning, MoveDownWarning, MoveUpWarning,
     DeleteWarning)
+from misago.users.djangoadmin import User
+from misago.users.djangoadmin import UserAdminModel
 
 
-class UserAdmin(djadmin.ModelAdmin):
-    actions = None
-    list_display = ('username', 'email', 'is_staff', 'is_superuser')
-    search_fields = ('username', 'email')
-    list_filter = ('groups', 'is_staff', 'is_superuser')
-    readonly_fields = ('username', 'email', 'is_staff', 'is_superuser')
-    fieldsets = (
-        (_('User data'),
-         {'fields': ('username', 'email', 'is_staff', 'is_superuser')}),
-        (_('Change Django Permissions'),
-         {'fields': ('groups', 'user_permissions')}),
-    )
-
-    def has_add_permission(self, request):
-        return False
-
-    def has_delete_permission(self, request, obj=None):
-        return False
-
-djadmin.site.register(get_user_model(), UserAdmin)
+# register misago user model in django admin panel
+djadmin.site.register(model_or_iterable=User, admin_class=UserAdminModel)
 
 
 class MisagoAdminExtension(object):

+ 131 - 0
misago/users/djangoadmin.py

@@ -0,0 +1,131 @@
+"""
+Defines `UserAdminModel` for registration of Misago `User` model in django 
+admin panel.
+
+The model supposed to be used for interaction of third party django apps with
+Misago `User` model, i.e. assignment to a `User` permissions or groups.
+
+Registration call is placed in :mod:`misago.users.admin`.
+
+Test for the model is placed in :mod:`misago.users.tests.test_djangoadmin_user`.
+"""
+from django.contrib import admin
+from django.contrib.auth import get_user_model
+from django.core.urlresolvers import reverse
+from django.utils.html import format_html
+from django.utils.translation import ugettext as _
+
+from misago.core import forms
+
+
+# Misago user model
+User = get_user_model()
+
+
+class UserAdminForm(forms.ModelForm):
+    """
+    This form adds `edit_from_misago_link` pseudo-field, that renders 
+    itself like an html hyperlink to a user edit page in misago admin panel.
+
+    This could be done with `User` edit template overwrite, but
+    it is kind of overkill - overwrite the whole template just to add one 
+    button - isn't it?
+    """
+    #: pseudo-field
+    edit_from_misago_link = forms.Field()
+    
+    def __init__(self, *args, **kwargs):
+        # noinspection PyArgumentList
+        super(UserAdminForm, self).__init__(*args, **kwargs)
+        self.init_edit_from_misago_link_field()
+
+    def init_edit_from_misago_link_field(self):
+        """
+        Init for the pseudo-field, and replace it's widget `render`.
+        """
+        field = self.fields['edit_from_misago_link']
+        field.required = False
+        field.label = ''
+        field.widget.render = self.render_edit_from_misago_link
+
+    # noinspection PyUnusedLocal
+    def render_edit_from_misago_link(self, *args, **kwargs):
+        """
+        Composes an html hyperlink for the pseudo-field render.
+
+        `*args` and `**kwargs` arguments need to mimic widget `render()`
+        signature.
+
+        :rtype: str
+        """
+        text = _('Edit this user in Misago admin panel')
+        link_html_template = ('<a href="{}" target="blank">' + text + '</a>')
+        link_url = reverse(
+            viewname='misago:admin:users:accounts:edit',
+            kwargs={'pk': self.instance.pk},
+        )
+        link_html = format_html(link_html_template, link_url)
+
+        return link_html
+    
+    class Meta:
+        model = User
+        fields = ['edit_from_misago_link']
+
+
+class UserAdminModel(admin.ModelAdmin):
+    """
+    Redeclare most of the model fields like read-only. 
+    Prevents new/delete actions (users should use misago admin panel for 
+    that).
+    Replaces default form with custom `UserAdminForm`.
+    """
+
+    list_display = (
+        'username',
+        'email',
+        'is_staff',
+        'is_superuser',
+    )
+    search_fields = ('username', 'email')
+    list_filter = ('groups', 'is_staff', 'is_superuser')
+
+    form = UserAdminForm
+    actions = None
+    readonly_fields = (
+        'username',
+        'email',
+        'rank',
+        'last_login',
+        'joined_on',
+        'is_staff',
+        'is_superuser',
+    )
+    fieldsets = (
+        (
+            _('Misago user data'),
+            {'fields': (
+                'username',
+                'email',
+                'rank',
+                'last_login',
+                'joined_on',
+                'is_staff',
+                'is_superuser',
+                'edit_from_misago_link',
+            )},
+        ),
+        (
+            _('Edit permissions and groups'),
+            {'fields': (
+                'groups',
+                'user_permissions',
+            )},
+        ),
+    )
+
+    def has_add_permission(self, request):
+        return False
+
+    def has_delete_permission(self, request, obj=None):
+        return False

+ 50 - 0
misago/users/tests/test_djangoadmin_user.py

@@ -0,0 +1,50 @@
+from django.contrib.auth.models import Permission
+from django.contrib.auth import get_user_model
+from django.core.urlresolvers import reverse
+from django.utils import formats
+
+from misago.admin.testutils import AdminTestCase
+
+
+User = get_user_model()
+
+
+class TestDjangoAdminUserForm(AdminTestCase):
+    urls = 'misago.core.testproject.urls'
+
+    def test_edit_page_content(self):
+        """
+        Assert that edit-view of `test_user` contains expected content.
+        """
+        test_user = User.objects.create_user(
+            username='Bob',
+            email='bob@test.com',
+            password='Pass.123',
+        )
+
+        test_user_edit_view = reverse(
+            viewname='admin:misago_users_user_change',
+            args=[test_user.id],
+        )
+        response = self.client.get(test_user_edit_view)
+
+        self.assertEqual(response.status_code, 200)
+
+        self.assertContains(response, test_user.username)
+        self.assertContains(response, test_user.email)
+        self.assertContains(response, test_user.rank)
+
+        last_login_date = formats.date_format(test_user.last_login)
+        register_date = formats.date_format(test_user.joined_on)
+        self.assertContains(response, last_login_date)
+        self.assertContains(response, register_date)
+
+        edit_from_misago_admin_link = reverse(
+            viewname='misago:admin:users:accounts:edit',
+            kwargs={'pk': test_user.pk},
+        )
+        self.assertContains(response, edit_from_misago_admin_link)
+
+        user_perms_form_data = Permission.objects.all()
+        for permission in user_perms_form_data:
+            self.assertContains(response, permission)