Skip to content

Commit 0783603

Browse files
committed
adding admin register example code for django
1 parent 2fba64c commit 0783603

File tree

2 files changed

+378
-1
lines changed

2 files changed

+378
-1
lines changed
Lines changed: 377 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,377 @@
1+
title: django.contrib.admin.sites register Example Code
2+
category: page
3+
slug: django-contrib-admin-sites-register-examples
4+
sortorder: 50016
5+
toc: False
6+
sidebartitle: django.contrib.admin.sites register
7+
meta: Python code examples for the admin module within django.contrib of the Django project.
8+
9+
10+
The [Django admin](https://docs.djangoproject.com/en/stable/ref/contrib/admin/)
11+
is an automatically-generated user interface for
12+
[Django models](/django-orm.html). The
13+
[register function](https://github.com/django/django/blob/master/django/contrib/admin/sites.py)
14+
is used to add models to the Django admin so that data for those models
15+
can be created, deleted, updated and queried through the user interface.
16+
17+
18+
## Example 1 from AuditLog
19+
[Auditlog](https://github.com/jjkester/django-auditlog)
20+
([project documentation](https://django-auditlog.readthedocs.io/en/latest/))
21+
is a [Django](/django.html) app that logs changes to Python objects,
22+
similar to the Django admin's logs but with more details and
23+
output formats. Auditlog's source code is provided as open source under the
24+
[MIT license](https://github.com/jjkester/django-auditlog/blob/master/LICENSE).
25+
26+
[**AuditLog / src / auditlog / admin.py**](https://github.com/jjkester/django-auditlog/blob/master/src/auditlog/admin.py)
27+
28+
```python
29+
~~from django.contrib import admin
30+
from .models import LogEntry
31+
from .mixins import LogEntryAdminMixin
32+
from .filters import ResourceTypeFilter
33+
34+
35+
class LogEntryAdmin(admin.ModelAdmin, LogEntryAdminMixin):
36+
list_display = ['created', 'resource_url', 'action',
37+
'msg_short', 'user_url']
38+
search_fields = ['timestamp', 'object_repr', 'changes',
39+
'actor__first_name', 'actor__last_name']
40+
list_filter = ['action', ResourceTypeFilter]
41+
readonly_fields = ['created', 'resource_url', 'action',
42+
'user_url', 'msg']
43+
fieldsets = [
44+
(None, {'fields': ['created', 'user_url',
45+
'resource_url']}),
46+
('Changes', {'fields': ['action', 'msg']}),
47+
]
48+
49+
50+
~~admin.site.register(LogEntry, LogEntryAdmin)
51+
```
52+
53+
54+
## Example 2 from django-allauth
55+
[django-allauth](https://github.com/pennersr/django-allauth)
56+
([project website](https://www.intenct.nl/projects/django-allauth/)) is a
57+
[Django](/django.html) library for easily adding local and social authentication
58+
flows to Django projects. It is open source under the
59+
[MIT License](https://github.com/pennersr/django-allauth/blob/master/LICENSE).
60+
61+
62+
[**django-allauth / allauth / socialaccount / admin.py**](https://github.com/pennersr/django-allauth/blob/master/allauth/socialaccount/admin.py)
63+
64+
```python
65+
from django import forms
66+
~~from django.contrib import admin
67+
68+
from allauth.account.adapter import get_adapter
69+
70+
from .models import SocialAccount, SocialApp, SocialToken
71+
72+
73+
class SocialAppForm(forms.ModelForm):
74+
class Meta:
75+
model = SocialApp
76+
exclude = []
77+
widgets = {
78+
'client_id': forms.TextInput(attrs={'size': '100'}),
79+
'key': forms.TextInput(attrs={'size': '100'}),
80+
'secret': forms.TextInput(attrs={'size': '100'})
81+
}
82+
83+
84+
class SocialAppAdmin(admin.ModelAdmin):
85+
form = SocialAppForm
86+
list_display = ('name', 'provider',)
87+
filter_horizontal = ('sites',)
88+
89+
90+
class SocialAccountAdmin(admin.ModelAdmin):
91+
search_fields = []
92+
raw_id_fields = ('user',)
93+
list_display = ('user', 'uid', 'provider')
94+
list_filter = ('provider',)
95+
96+
def get_search_fields(self, request):
97+
base_fields = get_adapter().get_user_search_fields()
98+
return list(map(lambda a: 'user__' + a, base_fields))
99+
100+
101+
class SocialTokenAdmin(admin.ModelAdmin):
102+
raw_id_fields = ('app', 'account',)
103+
list_display = ('app', 'account', 'truncated_token',
104+
'expires_at')
105+
list_filter = ('app', 'app__provider', 'expires_at')
106+
107+
def truncated_token(self, token):
108+
max_chars = 40
109+
ret = token.token
110+
if len(ret) > max_chars:
111+
ret = ret[0:max_chars] + '...(truncated)'
112+
return ret
113+
truncated_token.short_description = 'Token'
114+
115+
116+
~~admin.site.register(SocialApp, SocialAppAdmin)
117+
~~admin.site.register(SocialToken, SocialTokenAdmin)
118+
~~admin.site.register(SocialAccount, SocialAccountAdmin)
119+
```
120+
121+
122+
## Example 3 from django-cms
123+
[django-cms](https://github.com/divio/django-cms)
124+
([project website](https://www.django-cms.org/en/)) is a Python-based
125+
content management system (CMS) [library](https://pypi.org/project/django-cms/)
126+
for use with Django web apps that is open sourced under the
127+
[BSD 3-Clause "New"](https://github.com/divio/django-cms/blob/develop/LICENSE)
128+
license.
129+
130+
[**django-cms / cms / admin / useradmin.py**](https://github.com/divio/django-cms/blob/develop/cms/admin/useradmin.py)
131+
132+
```python
133+
# -*- coding: utf-8 -*-
134+
from copy import deepcopy
135+
136+
from django.contrib import admin
137+
`~from django.contrib.admin import site
138+
from django.contrib.auth import get_user_model
139+
from django.contrib.sites.models import Site
140+
from django.utils.translation import ugettext
141+
142+
from cms.admin.forms import PageUserChangeForm, PageUserGroupForm
143+
from cms.exceptions import NoPermissionsException
144+
from cms.models import Page, PagePermission, PageUser, PageUserGroup
145+
from cms.utils.compat.forms import UserAdmin
146+
from cms.utils.conf import get_cms_setting
147+
from cms.utils.permissions import (
148+
get_model_permission_codename,
149+
get_subordinate_groups,
150+
get_subordinate_users,
151+
get_user_permission_level,
152+
)
153+
154+
155+
user_model = get_user_model()
156+
admin_class = UserAdmin
157+
for model, admin_instance in site._registry.items():
158+
if model == user_model:
159+
admin_class = admin_instance.__class__
160+
161+
162+
class GenericCmsPermissionAdmin(object):
163+
164+
def get_subordinates(self, user, site):
165+
raise NotImplementedError
166+
167+
def _has_change_permissions_permission(self, request):
168+
"""
169+
User is able to add/change objects only if he haves
170+
can change permission on some page.
171+
"""
172+
site = Site.objects.get_current(request)
173+
174+
try:
175+
get_user_permission_level(request.user, site)
176+
except NoPermissionsException:
177+
return False
178+
return True
179+
180+
def get_form(self, request, obj=None, **kwargs):
181+
form_class = super(GenericCmsPermissionAdmin,
182+
self).get_form(request, obj, **kwargs)
183+
form_class._current_user = request.user
184+
return form_class
185+
186+
def get_queryset(self, request):
187+
queryset = super(GenericCmsPermissionAdmin, self).\
188+
get_queryset(request)
189+
site = Site.objects.get_current(request)
190+
user_ids = self.get_subordinates(request.user, site).\
191+
values_list('pk', flat=True)
192+
return queryset.filter(pk__in=user_ids)
193+
194+
def has_add_permission(self, request):
195+
has_model_perm = super(GenericCmsPermissionAdmin,
196+
self).has_add_permission(request)
197+
198+
if not has_model_perm:
199+
return False
200+
return self._has_change_permissions_permission(request)
201+
202+
def has_change_permission(self, request, obj=None):
203+
has_model_perm = super(GenericCmsPermissionAdmin,
204+
self).has_change_permission(request,
205+
obj)
206+
207+
if not has_model_perm:
208+
return False
209+
return self._has_change_permissions_permission(request)
210+
211+
def has_delete_permission(self, request, obj=None):
212+
has_model_perm = super(GenericCmsPermissionAdmin,
213+
self).has_delete_permission(request,
214+
obj)
215+
216+
if not has_model_perm:
217+
return False
218+
return self._has_change_permissions_permission(request)
219+
220+
def has_view_permission(self, request, obj=None):
221+
# For django 2.1
222+
# Default is to return True if user got `change` perm, but
223+
# we have to get in consideration also cms permission system
224+
return self.has_change_permission(request, obj)
225+
226+
227+
class PageUserAdmin(GenericCmsPermissionAdmin, admin_class):
228+
form = PageUserChangeForm
229+
model = PageUser
230+
231+
def get_subordinates(self, user, site):
232+
return get_subordinate_users(user, site).\
233+
values_list('pk', flat=True)
234+
235+
def get_readonly_fields(self, request, obj=None):
236+
fields = super(PageUserAdmin,
237+
self).get_readonly_fields(request, obj)
238+
239+
if not request.user.is_superuser:
240+
# Non superusers can't set superuser status on
241+
# their subordinates.
242+
fields = list(fields) + ['is_superuser']
243+
return fields
244+
245+
def save_model(self, request, obj, form, change):
246+
if not change:
247+
# By default set the staff flag to True
248+
# when a PageUser is first created
249+
obj.is_staff = True
250+
# Set the created_by field to the current user
251+
obj.created_by = request.user
252+
super(PageUserAdmin, self).save_model(request, obj,
253+
form, change)
254+
255+
256+
class PageUserGroupAdmin(GenericCmsPermissionAdmin,
257+
admin.ModelAdmin):
258+
form = PageUserGroupForm
259+
list_display = ('name', 'created_by')
260+
261+
fieldsets = [
262+
(None, {'fields': ('name',)}),
263+
]
264+
265+
def get_fieldsets(self, request, obj=None):
266+
"""
267+
Nobody can grant more than he haves, so check for
268+
user permissions to Page and User model and render
269+
fieldset depending on them.
270+
"""
271+
fieldsets = deepcopy(self.fieldsets)
272+
perm_models = (
273+
(Page, ugettext('Page permissions')),
274+
(PageUser, ugettext('User & Group permissions')),
275+
(PagePermission,
276+
ugettext('Page permissions management')),
277+
)
278+
for i, perm_model in enumerate(perm_models):
279+
fields = []
280+
model, title = perm_model
281+
name = model.__name__.lower()
282+
for key in ('add', 'change', 'delete'):
283+
perm_code = get_model_permission_codename(\
284+
model, action=key)
285+
if request.user.has_perm(perm_code):
286+
fields.append('can_%s_%s' % (key, name))
287+
if fields:
288+
fieldsets.insert(2 + i, (title,
289+
{'fields': (fields,)}))
290+
return fieldsets
291+
292+
def get_subordinates(self, user, site):
293+
return get_subordinate_groups(user,
294+
site).values_list('pk',
295+
flat=True)
296+
297+
298+
if get_cms_setting('PERMISSION'):
299+
~~ admin.site.register(PageUser, PageUserAdmin)
300+
~~ admin.site.register(PageUserGroup, PageUserGroupAdmin)
301+
```
302+
303+
304+
## Example 4 from django-filer
305+
[django-filer](https://github.com/divio/django-filer)
306+
([project documentation](https://django-filer.readthedocs.io/en/latest/))
307+
is a file management library for uploading and organizing files and images
308+
in Django's admin interface. The project's code is available under the
309+
[BSD 3-Clause "New" or "Revised" open source license](https://github.com/divio/django-filer/blob/develop/LICENSE.txt).
310+
311+
[**django-filer / filer / admin / __init__.py**](https://github.com/divio/django-filer/blob/develop/filer/admin/__init__.py)
312+
313+
```python
314+
# -*- coding: utf-8 -*-
315+
~~from django.contrib import admin
316+
317+
from ..models import (Clipboard, File, Folder,
318+
FolderPermission, ThumbnailOption)
319+
from ..settings import FILER_IMAGE_MODEL
320+
from ..utils.loader import load_model
321+
from .clipboardadmin import ClipboardAdmin
322+
from .fileadmin import FileAdmin
323+
from .folderadmin import FolderAdmin
324+
from .imageadmin import ImageAdmin
325+
from .permissionadmin import PermissionAdmin
326+
from .thumbnailoptionadmin import ThumbnailOptionAdmin
327+
328+
329+
Image = load_model(FILER_IMAGE_MODEL)
330+
331+
332+
~~admin.site.register(Folder, FolderAdmin)
333+
~~admin.site.register(File, FileAdmin)
334+
~~admin.site.register(Clipboard, ClipboardAdmin)
335+
~~admin.site.register(Image, ImageAdmin)
336+
~~admin.site.register(FolderPermission, PermissionAdmin)
337+
~~admin.site.register(ThumbnailOption, ThumbnailOptionAdmin)
338+
```
339+
340+
341+
## Example 5 from wagtail
342+
[wagtail](https://github.com/wagtail/wagtail)
343+
([project website](https://wagtail.io/)) is a fantastic
344+
[Django](/django.html)-based CMS with code that is open source
345+
under the
346+
[BSD 3-Clause "New" or "Revised" License](https://github.com/wagtail/wagtail/blob/master/LICENSE).
347+
348+
[**wagtail / wagtail / core / admin.py**](https://github.com/wagtail/wagtail/blob/master/wagtail/core/admin.py)
349+
350+
```python
351+
~~from django.contrib import admin
352+
from django.contrib.auth.admin import GroupAdmin
353+
from django.contrib.auth.models import Group
354+
355+
from wagtail.core.models import GroupPagePermission, Page, Site
356+
357+
~~admin.site.register(Site)
358+
~~admin.site.register(Page)
359+
360+
361+
# Extend GroupAdmin to include page permissions as an inline
362+
class GroupPagePermissionInline(admin.TabularInline):
363+
model = GroupPagePermission
364+
raw_id_fields = ['page']
365+
verbose_name = 'page permission'
366+
verbose_name_plural = 'page permissions'
367+
368+
369+
class GroupAdminWithPagePermissions(GroupAdmin):
370+
inlines = GroupAdmin.inlines + [GroupPagePermissionInline]
371+
372+
373+
~~if admin.site.is_registered(Group):
374+
~~ admin.site.unregister(Group)
375+
~~admin.site.register(Group, GroupAdminWithPagePermissions)
376+
```
377+

content/pages/examples/django/django-contrib-admin.markdown

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ sidebartitle: django.contrib.admin
77
meta: Python code examples for the admin module within django.contrib of the Django project.
88

99

10-
The [Django admin](https://docs.djangoproject.com/en/2.2/ref/contrib/admin/)
10+
The [Django admin](https://docs.djangoproject.com/en/stable/ref/contrib/admin/)
1111
is an automatically-generated user interface for [Django models](/django-orm.html).
1212
The admin interface can be heavily customized and the code examples below can
1313
help you understand how to implement some of the trickier parts of customization.

0 commit comments

Comments
 (0)