-
Notifications
You must be signed in to change notification settings - Fork 0
/
admin.py
128 lines (79 loc) · 3.82 KB
/
admin.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import json
from typing import Type
from django.contrib import admin
from django.core.exceptions import PermissionDenied
from django.db.models import Model
from django.http import Http404, HttpResponseRedirect
from django.shortcuts import redirect
from django.urls import reverse, path
from django.utils.html import format_html
from cosmogo.utils.gettext import trans
from cosmogo.utils.url import get_absolute_url
DEFAULT_LINK_TEMPLATE = '<a href="{url}">{label}</a>'
def admin_url(model: Type[Model], view: str, *args, site=None, **kwargs) -> str:
"""
Return an url to an admin view.
"""
return reverse(admin_url_name(model, view, site=site), args=args, kwargs=kwargs)
def absolute_admin_url(request, model: Type[Model], view: str, *args, site=None, **kwargs):
return get_absolute_url(request, admin_url_name(model, view, site=site), *args, **kwargs)
def admin_redirect(model: Type[Model], view: str, *args, site=None, **kwargs) -> HttpResponseRedirect:
return redirect(admin_url_name(model, view, site=site), *args, **kwargs)
def admin_url_name(model: Type[Model], view: str, *, site=None) -> str:
namespace = (site or admin.site).name
view_name = admin_view_name(model, view)
return f'{namespace}:{view_name}'
def admin_view_name(model: Type[Model], view: str) -> str:
return f'{model._meta.app_label}_{model._meta.model_name}_{view}'
def admin_path(model_admin: admin.ModelAdmin, route, view, name, kwargs=None):
name = admin_view_name(model_admin.model, name)
view = model_admin.admin_site.admin_view(view)
return path(route, view, kwargs=kwargs, name=name)
def admin_link(obj: Model, view='change', site=None, label=None, template=DEFAULT_LINK_TEMPLATE):
url = admin_url(type(obj), view, obj.pk, site=site)
return format_link(url, label=label or obj, obj=obj, template=template)
def format_link(url, label=None, *, template=DEFAULT_LINK_TEMPLATE, **kwargs):
kwargs.setdefault('label', label or url)
return format_html(template, url=url, **kwargs)
def admin_template_names(model: Type[Model], name: str, *, site=None):
opts = model._meta
app_label = opts.app_label
model_name = opts.model_name
namespace = (site or admin.site).name
return [
f'{namespace}/{app_label}/{model_name}/{name}.html',
f'{namespace}/{app_label}/{name}.html',
f'{namespace}/{name}.html',
]
def json_display(data):
content = json.dumps(data, indent=2)
return format_html('<pre style="padding: 0">{content}</pre>', content=content)
class DefaultTabularInline(admin.TabularInline):
template = 'admin/inline/tabular-without-original.html'
extra = 0
class AdminViewMixin:
def get_object_for(self: admin.ModelAdmin, permission: str, request, object_id):
obj = self.get_object(request, object_id)
if not getattr(self, f'has_{permission}_permission')(request, obj=obj):
raise PermissionDenied
if obj is None:
msg = trans('%(name)s object with primary key %(key)r does not exist.')
context = {'name': self.opts.verbose_name, 'key': object_id}
raise Http404(msg % context)
return obj
def get_object_for_change(self, request, object_id):
return self.get_object_for('change', request, object_id)
def get_object_for_delete(self, request, object_id):
return self.get_object_for('delete', request, object_id)
class ReadOnlyAdminMixin:
def has_add_permission(self, request, obj=None):
# For `InlineModelAdmin` the parent object may be passed via `obj`.
return False
def has_change_permission(self, request, obj=None):
return False
def has_delete_permission(self, request, obj=None):
return False
class ReadOnlyModelAdmin(ReadOnlyAdminMixin, admin.ModelAdmin):
"""
Immutable admin for a given model.
"""