mirror of
https://github.com/jazzband/django-admin2.git
synced 2026-03-16 22:20:24 +00:00
Merge pull request #475 from jazzband/master-to-main
Rename Django's dev branch to main.
This commit is contained in:
commit
8cee4de75d
16 changed files with 197 additions and 168 deletions
10
README.rst
10
README.rst
|
|
@ -8,7 +8,7 @@ django-admin2
|
|||
.. image:: https://github.com/jazzband/django-admin2/workflows/Test/badge.svg
|
||||
:target: https://github.com/jazzband/django-admin2/actions
|
||||
:alt: GitHub Actions
|
||||
.. image:: https://codecov.io/gh/jazzband/django-admin2/branch/develop/graph/badge.svg?token=PcC594rhI4
|
||||
.. image:: https://codecov.io/gh/jazzband/django-admin2/branch/main/graph/badge.svg?token=PcC594rhI4
|
||||
:target: https://codecov.io/gh/jazzband/django-admin2
|
||||
:alt: Code coverage
|
||||
|
||||
|
|
@ -30,17 +30,17 @@ Features
|
|||
Screenshots
|
||||
===========
|
||||
|
||||
.. image:: https://github.com/jazzband/django-admin2/raw/develop/screenshots/Site_administration.png
|
||||
.. image:: https://github.com/jazzband/django-admin2/raw/main/screenshots/Site_administration.png
|
||||
:width: 722px
|
||||
:alt: Site administration
|
||||
:align: center
|
||||
:target: https://github.com/jazzband/django-admin2/raw/develop/screenshots/Site_administration.png
|
||||
:target: https://github.com/jazzband/django-admin2/raw/main/screenshots/Site_administration.png
|
||||
|
||||
.. image:: https://github.com/jazzband/django-admin2/raw/develop/screenshots/Select_user.png
|
||||
.. image:: https://github.com/jazzband/django-admin2/raw/main/screenshots/Select_user.png
|
||||
:width: 722px
|
||||
:alt: Select user
|
||||
:align: center
|
||||
:target: https://github.com/jazzband/django-admin2/raw/develop/screenshots/Select_user.png
|
||||
:target: https://github.com/jazzband/django-admin2/raw/main/screenshots/Select_user.png
|
||||
|
||||
Requirements
|
||||
============
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from django.contrib import messages
|
|||
from django.db import router
|
||||
from django.utils.encoding import force_str
|
||||
from django.utils.text import capfirst
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.utils.translation import gettext as _
|
||||
from django.utils.translation import gettext_lazy, ngettext, pgettext_lazy
|
||||
from django.views.generic import TemplateView
|
||||
|
||||
|
|
|
|||
108
djadmin2/core.py
108
djadmin2/core.py
|
|
@ -5,7 +5,7 @@ Issue #99.
|
|||
from importlib import import_module
|
||||
|
||||
from django.conf import settings
|
||||
from django.conf.urls import url
|
||||
from django.urls import re_path
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
|
||||
from . import apiviews
|
||||
|
|
@ -23,12 +23,13 @@ class Admin2(object):
|
|||
It also provides an index view that serves as an entry point to the
|
||||
admin site.
|
||||
"""
|
||||
|
||||
index_view = views.IndexView
|
||||
login_view = views.LoginView
|
||||
app_index_view = views.AppIndexView
|
||||
api_index_view = apiviews.IndexAPIView
|
||||
|
||||
def __init__(self, name='admin2'):
|
||||
def __init__(self, name="admin2"):
|
||||
self.registry = {}
|
||||
self.apps = {}
|
||||
self.app_verbose_names = {}
|
||||
|
|
@ -48,7 +49,8 @@ class Admin2(object):
|
|||
"""
|
||||
if model in self.registry:
|
||||
raise ImproperlyConfigured(
|
||||
'%s is already registered in django-admin2' % model)
|
||||
"%s is already registered in django-admin2" % model
|
||||
)
|
||||
if not model_admin:
|
||||
model_admin = types.ModelAdmin2
|
||||
self.registry[model] = model_admin(model, admin=self, **kwargs)
|
||||
|
|
@ -71,7 +73,8 @@ class Admin2(object):
|
|||
del self.registry[model]
|
||||
except KeyError:
|
||||
raise ImproperlyConfigured(
|
||||
'%s was never registered in django-admin2' % model)
|
||||
"%s was never registered in django-admin2" % model
|
||||
)
|
||||
|
||||
# Remove the model from the apps registry
|
||||
# Get the app label
|
||||
|
|
@ -93,7 +96,8 @@ class Admin2(object):
|
|||
"""
|
||||
if app_label in self.app_verbose_names:
|
||||
raise ImproperlyConfigured(
|
||||
'%s is already registered in django-admin2' % app_label)
|
||||
"%s is already registered in django-admin2" % app_label
|
||||
)
|
||||
|
||||
self.app_verbose_names[app_label] = app_verbose_name
|
||||
|
||||
|
|
@ -109,7 +113,8 @@ class Admin2(object):
|
|||
del self.app_verbose_names[app_label]
|
||||
except KeyError:
|
||||
raise ImproperlyConfigured(
|
||||
'%s app label was never registered in django-admin2' % app_label)
|
||||
"%s app label was never registered in django-admin2" % app_label
|
||||
)
|
||||
|
||||
def autodiscover(self):
|
||||
"""
|
||||
|
|
@ -120,7 +125,7 @@ class Admin2(object):
|
|||
try:
|
||||
import_module("%s.admin2" % app_name)
|
||||
except ImportError as e:
|
||||
if str(e).startswith("No module named") and 'admin2' in str(e):
|
||||
if str(e).startswith("No module named") and "admin2" in str(e):
|
||||
continue
|
||||
raise e
|
||||
|
||||
|
|
@ -132,71 +137,74 @@ class Admin2(object):
|
|||
for object_admin in self.registry.values():
|
||||
if object_admin.name == name:
|
||||
return object_admin
|
||||
raise ValueError(
|
||||
u'No object admin found with name {}'.format(repr(name)))
|
||||
raise ValueError(u"No object admin found with name {}".format(repr(name)))
|
||||
|
||||
def get_index_kwargs(self):
|
||||
return {
|
||||
'registry': self.registry,
|
||||
'app_verbose_names': self.app_verbose_names,
|
||||
'apps': self.apps,
|
||||
'login_view': self.login_view,
|
||||
"registry": self.registry,
|
||||
"app_verbose_names": self.app_verbose_names,
|
||||
"apps": self.apps,
|
||||
"login_view": self.login_view,
|
||||
}
|
||||
|
||||
def get_app_index_kwargs(self):
|
||||
return {
|
||||
'registry': self.registry,
|
||||
'app_verbose_names': self.app_verbose_names,
|
||||
'apps': self.apps,
|
||||
"registry": self.registry,
|
||||
"app_verbose_names": self.app_verbose_names,
|
||||
"apps": self.apps,
|
||||
}
|
||||
|
||||
def get_api_index_kwargs(self):
|
||||
return {
|
||||
'registry': self.registry,
|
||||
'app_verbose_names': self.app_verbose_names,
|
||||
'apps': self.apps,
|
||||
"registry": self.registry,
|
||||
"app_verbose_names": self.app_verbose_names,
|
||||
"apps": self.apps,
|
||||
}
|
||||
|
||||
def get_urls(self):
|
||||
urlpatterns = [
|
||||
url(regex=r'^$',
|
||||
re_path(
|
||||
r"^$",
|
||||
view=self.index_view.as_view(**self.get_index_kwargs()),
|
||||
name='dashboard'
|
||||
),
|
||||
url(regex=r'^auth/user/(?P<pk>\d+)/update/password/$',
|
||||
name="dashboard",
|
||||
),
|
||||
re_path(
|
||||
r"^auth/user/(?P<pk>\d+)/update/password/$",
|
||||
view=views.PasswordChangeView.as_view(),
|
||||
name='password_change'
|
||||
),
|
||||
url(regex='^password_change_done/$',
|
||||
name="password_change",
|
||||
),
|
||||
re_path(
|
||||
"^password_change_done/$",
|
||||
view=views.PasswordChangeDoneView.as_view(),
|
||||
name='password_change_done'
|
||||
),
|
||||
url(regex='^logout/$',
|
||||
view=views.LogoutView.as_view(),
|
||||
name='logout'
|
||||
),
|
||||
url(regex=r'^(?P<app_label>\w+)/$',
|
||||
view=self.app_index_view.as_view(
|
||||
**self.get_app_index_kwargs()),
|
||||
name='app_index'
|
||||
),
|
||||
url(regex=r'^api/v0/$',
|
||||
view=self.api_index_view.as_view(
|
||||
**self.get_api_index_kwargs()),
|
||||
name='api_index'
|
||||
),
|
||||
name="password_change_done",
|
||||
),
|
||||
re_path("^logout/$", view=views.LogoutView.as_view(), name="logout"),
|
||||
re_path(
|
||||
r"^(?P<app_label>\w+)/$",
|
||||
view=self.app_index_view.as_view(**self.get_app_index_kwargs()),
|
||||
name="app_index",
|
||||
),
|
||||
re_path(
|
||||
r"^api/v0/$",
|
||||
view=self.api_index_view.as_view(**self.get_api_index_kwargs()),
|
||||
name="api_index",
|
||||
),
|
||||
]
|
||||
for model, model_admin in self.registry.items():
|
||||
model_options = utils.model_options(model)
|
||||
urlpatterns += [
|
||||
url('^{}/{}/'.format(
|
||||
model_options.app_label,
|
||||
model_options.object_name.lower()),
|
||||
model_admin.urls),
|
||||
url('^api/v0/{}/{}/'.format(
|
||||
model_options.app_label,
|
||||
model_options.object_name.lower()),
|
||||
model_admin.api_urls),
|
||||
re_path(
|
||||
"^{}/{}/".format(
|
||||
model_options.app_label, model_options.object_name.lower()
|
||||
),
|
||||
model_admin.urls,
|
||||
),
|
||||
re_path(
|
||||
"^api/v0/{}/{}/".format(
|
||||
model_options.app_label, model_options.object_name.lower()
|
||||
),
|
||||
model_admin.api_urls,
|
||||
),
|
||||
]
|
||||
return urlpatterns
|
||||
|
||||
|
|
|
|||
|
|
@ -3,8 +3,7 @@ from django.conf import settings
|
|||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.db import models
|
||||
from django.utils.encoding import force_str
|
||||
from django.utils.encoding import smart_text
|
||||
from django.utils.translation import ugettext, gettext_lazy as _
|
||||
from django.utils.translation import gettext, gettext_lazy as _
|
||||
|
||||
from .utils import quote
|
||||
|
||||
|
|
@ -13,7 +12,7 @@ class LogEntryManager(models.Manager):
|
|||
def log_action(self, user_id, obj, action_flag, change_message=''):
|
||||
content_type_id = ContentType.objects.get_for_model(obj).id
|
||||
e = self.model(None, None, user_id, content_type_id,
|
||||
smart_text(obj.id), force_str(obj)[:200],
|
||||
force_str(obj.id), force_str(obj)[:200],
|
||||
action_flag, change_message)
|
||||
e.save()
|
||||
|
||||
|
|
@ -43,22 +42,22 @@ class LogEntry(models.Model):
|
|||
ordering = ('-action_time',)
|
||||
|
||||
def __repr__(self):
|
||||
return smart_text(self.action_time)
|
||||
return force_str(self.action_time)
|
||||
|
||||
def __str__(self):
|
||||
if self.action_flag == self.ADDITION:
|
||||
return ugettext('Added "%(object)s".') % {
|
||||
return gettext('Added "%(object)s".') % {
|
||||
'object': self.object_repr}
|
||||
elif self.action_flag == self.CHANGE:
|
||||
return ugettext('Changed "%(object)s" - %(changes)s') % {
|
||||
return gettext('Changed "%(object)s" - %(changes)s') % {
|
||||
'object': self.object_repr,
|
||||
'changes': self.change_message,
|
||||
}
|
||||
elif self.action_flag == self.DELETION:
|
||||
return ugettext('Deleted "%(object)s."') % {
|
||||
return gettext('Deleted "%(object)s."') % {
|
||||
'object': self.object_repr}
|
||||
|
||||
return ugettext('LogEntry Object')
|
||||
return gettext('LogEntry Object')
|
||||
|
||||
def is_addition(self):
|
||||
return self.action_flag == self.ADDITION
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from django.conf import settings
|
||||
from django.conf.urls import url
|
||||
from django.conf.urls.static import static
|
||||
from django.urls import re_path
|
||||
|
||||
from djadmin2.site import djadmin2_site
|
||||
|
||||
|
|
@ -15,5 +15,5 @@ djadmin2_site.login_view = CustomLoginView
|
|||
djadmin2_site.autodiscover()
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^admin2/', djadmin2_site.urls),
|
||||
re_path(r'^admin2/', djadmin2_site.urls),
|
||||
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
</li>
|
||||
{% endif %}
|
||||
{% for link, date in dates %}
|
||||
<li class="{% ifequal active_day date %}active{% endifequal %}">
|
||||
<li class="{% if active_day == date %}active{% endif %}">
|
||||
<a href="{{ link|safe }}">{{ date }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
|
|
|
|||
|
|
@ -4,9 +4,8 @@ import sys
|
|||
from collections import namedtuple
|
||||
|
||||
import extra_views
|
||||
from django.conf.urls import url
|
||||
from django.forms import modelform_factory
|
||||
from django.urls import reverse
|
||||
from django.urls import re_path, reverse
|
||||
|
||||
from . import actions
|
||||
from . import apiviews
|
||||
|
|
@ -15,14 +14,12 @@ from . import utils
|
|||
from . import views
|
||||
|
||||
|
||||
logger = logging.getLogger('djadmin2')
|
||||
logger = logging.getLogger("djadmin2")
|
||||
|
||||
|
||||
class ModelAdminBase2(type):
|
||||
|
||||
def __new__(cls, name, bases, attrs):
|
||||
new_class = super(ModelAdminBase2, cls).__new__(cls, name,
|
||||
bases, attrs)
|
||||
new_class = super(ModelAdminBase2, cls).__new__(cls, name, bases, attrs)
|
||||
view_list = []
|
||||
for key, value in attrs.items():
|
||||
if isinstance(value, views.AdminView):
|
||||
|
|
@ -30,7 +27,7 @@ class ModelAdminBase2(type):
|
|||
value.name = key
|
||||
view_list.append(value)
|
||||
|
||||
view_list.extend(getattr(new_class, 'views', []))
|
||||
view_list.extend(getattr(new_class, "views", []))
|
||||
new_class.views = view_list
|
||||
return new_class
|
||||
|
||||
|
|
@ -54,9 +51,10 @@ class ModelAdmin2(metaclass=ModelAdminBase2):
|
|||
This prevents us from easily implementing methods/setters which
|
||||
bypass the blocking features of the ImmutableAdmin.
|
||||
"""
|
||||
|
||||
actions_selection_counter = True
|
||||
date_hierarchy = False
|
||||
list_display = ('__str__',)
|
||||
list_display = ("__str__",)
|
||||
list_display_links = ()
|
||||
list_filter = ()
|
||||
list_select_related = False
|
||||
|
|
@ -113,12 +111,20 @@ class ModelAdmin2(metaclass=ModelAdminBase2):
|
|||
inlines = []
|
||||
|
||||
# Views
|
||||
index_view = views.AdminView(r'^$', views.ModelListView, name='index')
|
||||
create_view = views.AdminView(r'^create/$', views.ModelAddFormView, name='create')
|
||||
update_view = views.AdminView(r'^(?P<pk>[0-9]+)/$', views.ModelEditFormView, name='update')
|
||||
detail_view = views.AdminView(r'^(?P<pk>[0-9]+)/update/$', views.ModelDetailView, name='detail')
|
||||
delete_view = views.AdminView(r'^(?P<pk>[0-9]+)/delete/$', views.ModelDeleteView, name='delete')
|
||||
history_view = views.AdminView(r'^(?P<pk>[0-9]+)/history/$', views.ModelHistoryView, name='history')
|
||||
index_view = views.AdminView(r"^$", views.ModelListView, name="index")
|
||||
create_view = views.AdminView(r"^create/$", views.ModelAddFormView, name="create")
|
||||
update_view = views.AdminView(
|
||||
r"^(?P<pk>[0-9]+)/$", views.ModelEditFormView, name="update"
|
||||
)
|
||||
detail_view = views.AdminView(
|
||||
r"^(?P<pk>[0-9]+)/update/$", views.ModelDetailView, name="detail"
|
||||
)
|
||||
delete_view = views.AdminView(
|
||||
r"^(?P<pk>[0-9]+)/delete/$", views.ModelDeleteView, name="delete"
|
||||
)
|
||||
history_view = views.AdminView(
|
||||
r"^(?P<pk>[0-9]+)/history/$", views.ModelHistoryView, name="history"
|
||||
)
|
||||
views = []
|
||||
|
||||
# API configuration
|
||||
|
|
@ -137,7 +143,7 @@ class ModelAdmin2(metaclass=ModelAdminBase2):
|
|||
self.model_name = model_options.object_name.lower()
|
||||
|
||||
if self.name is None:
|
||||
self.name = '{}_{}'.format(self.app_label, self.model_name)
|
||||
self.name = "{}_{}".format(self.app_label, self.model_name)
|
||||
|
||||
if self.verbose_name is None:
|
||||
self.verbose_name = model_options.verbose_name
|
||||
|
|
@ -146,60 +152,73 @@ class ModelAdmin2(metaclass=ModelAdminBase2):
|
|||
|
||||
def get_default_view_kwargs(self):
|
||||
return {
|
||||
'app_label': self.app_label,
|
||||
'model': self.model,
|
||||
'model_name': self.model_name,
|
||||
'model_admin': immutable_admin_factory(self),
|
||||
"app_label": self.app_label,
|
||||
"model": self.model,
|
||||
"model_name": self.model_name,
|
||||
"model_admin": immutable_admin_factory(self),
|
||||
}
|
||||
|
||||
def get_index_kwargs(self):
|
||||
kwargs = self.get_default_view_kwargs()
|
||||
kwargs.update({
|
||||
'paginate_by': self.list_per_page,
|
||||
})
|
||||
kwargs.update(
|
||||
{
|
||||
"paginate_by": self.list_per_page,
|
||||
}
|
||||
)
|
||||
return kwargs
|
||||
|
||||
def get_default_api_view_kwargs(self):
|
||||
kwargs = self.get_default_view_kwargs()
|
||||
kwargs.update({
|
||||
'serializer_class': self.api_serializer_class,
|
||||
})
|
||||
kwargs.update(
|
||||
{
|
||||
"serializer_class": self.api_serializer_class,
|
||||
}
|
||||
)
|
||||
return kwargs
|
||||
|
||||
def get_prefixed_view_name(self, view_name):
|
||||
return '{}_{}'.format(self.name, view_name)
|
||||
return "{}_{}".format(self.name, view_name)
|
||||
|
||||
def get_create_kwargs(self):
|
||||
kwargs = self.get_default_view_kwargs()
|
||||
kwargs.update({
|
||||
'inlines': self.inlines,
|
||||
'form_class': (self.create_form_class if
|
||||
self.create_form_class else self.form_class),
|
||||
})
|
||||
kwargs.update(
|
||||
{
|
||||
"inlines": self.inlines,
|
||||
"form_class": (
|
||||
self.create_form_class
|
||||
if self.create_form_class
|
||||
else self.form_class
|
||||
),
|
||||
}
|
||||
)
|
||||
return kwargs
|
||||
|
||||
def get_update_kwargs(self):
|
||||
kwargs = self.get_default_view_kwargs()
|
||||
form_class = (self.update_form_class if
|
||||
self.update_form_class else self.form_class)
|
||||
form_class = (
|
||||
self.update_form_class if self.update_form_class else self.form_class
|
||||
)
|
||||
if form_class is None:
|
||||
form_class = modelform_factory(self.model, fields='__all__')
|
||||
kwargs.update({
|
||||
'inlines': self.inlines,
|
||||
'form_class': form_class,
|
||||
})
|
||||
form_class = modelform_factory(self.model, fields="__all__")
|
||||
kwargs.update(
|
||||
{
|
||||
"inlines": self.inlines,
|
||||
"form_class": form_class,
|
||||
}
|
||||
)
|
||||
return kwargs
|
||||
|
||||
def get_index_url(self):
|
||||
return reverse('admin2:{}'.format(
|
||||
self.get_prefixed_view_name('index')))
|
||||
return reverse("admin2:{}".format(self.get_prefixed_view_name("index")))
|
||||
|
||||
def get_api_list_kwargs(self):
|
||||
kwargs = self.get_default_api_view_kwargs()
|
||||
kwargs.update({
|
||||
'queryset': self.model.objects.all(),
|
||||
# 'paginate_by': self.list_per_page,
|
||||
})
|
||||
kwargs.update(
|
||||
{
|
||||
"queryset": self.model.objects.all(),
|
||||
# 'paginate_by': self.list_per_page,
|
||||
}
|
||||
)
|
||||
return kwargs
|
||||
|
||||
def get_api_detail_kwargs(self):
|
||||
|
|
@ -218,34 +237,35 @@ class ModelAdmin2(metaclass=ModelAdminBase2):
|
|||
trace = sys.exc_info()[2]
|
||||
new_exception = TypeError(
|
||||
'Cannot instantiate admin view "{}.{}". '
|
||||
'The error that got raised was: {}'.format(
|
||||
self.__class__.__name__, admin_view.name, e))
|
||||
"The error that got raised was: {}".format(
|
||||
self.__class__.__name__, admin_view.name, e
|
||||
)
|
||||
)
|
||||
try:
|
||||
raise new_exception.with_traceback(trace)
|
||||
except AttributeError:
|
||||
raise (new_exception, None, trace)
|
||||
|
||||
pattern_list.append(
|
||||
url(
|
||||
regex=admin_view.url,
|
||||
re_path(
|
||||
admin_view.url,
|
||||
view=view_instance,
|
||||
name=self.get_prefixed_view_name(admin_view.name)
|
||||
name=self.get_prefixed_view_name(admin_view.name),
|
||||
)
|
||||
)
|
||||
return pattern_list
|
||||
|
||||
def get_api_urls(self):
|
||||
return [
|
||||
url(
|
||||
regex=r'^$',
|
||||
re_path(
|
||||
r"^$",
|
||||
view=self.api_list_view.as_view(**self.get_api_list_kwargs()),
|
||||
name=self.get_prefixed_view_name('api_list'),
|
||||
name=self.get_prefixed_view_name("api_list"),
|
||||
),
|
||||
url(
|
||||
regex=r'^(?P<pk>[0-9]+)/$',
|
||||
view=self.api_detail_view.as_view(
|
||||
**self.get_api_detail_kwargs()),
|
||||
name=self.get_prefixed_view_name('api_detail'),
|
||||
re_path(
|
||||
r"^(?P<pk>[0-9]+)/$",
|
||||
view=self.api_detail_view.as_view(**self.get_api_detail_kwargs()),
|
||||
name=self.get_prefixed_view_name("api_detail"),
|
||||
),
|
||||
]
|
||||
|
||||
|
|
@ -262,12 +282,12 @@ class ModelAdmin2(metaclass=ModelAdminBase2):
|
|||
actions_dict = {}
|
||||
|
||||
for cls in type(self).mro()[::-1]:
|
||||
class_actions = getattr(cls, 'list_actions', [])
|
||||
class_actions = getattr(cls, "list_actions", [])
|
||||
for action in class_actions:
|
||||
actions_dict[action.__name__] = {
|
||||
'name': action.__name__,
|
||||
'description': actions.get_description(action),
|
||||
'action_callable': action
|
||||
"name": action.__name__,
|
||||
"description": actions.get_description(action),
|
||||
"action_callable": action,
|
||||
}
|
||||
return actions_dict
|
||||
|
||||
|
|
@ -280,8 +300,9 @@ class Admin2Inline(extra_views.InlineFormSetFactory):
|
|||
A simple extension of django-extra-view's InlineFormSet that
|
||||
adds some useful functionality.
|
||||
"""
|
||||
|
||||
template = None
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
def construct_formset(self):
|
||||
"""
|
||||
|
|
@ -296,12 +317,14 @@ class Admin2Inline(extra_views.InlineFormSetFactory):
|
|||
|
||||
class Admin2TabularInline(Admin2Inline):
|
||||
template = os.path.join(
|
||||
settings.ADMIN2_THEME_DIRECTORY, 'edit_inlines/tabular.html')
|
||||
settings.ADMIN2_THEME_DIRECTORY, "edit_inlines/tabular.html"
|
||||
)
|
||||
|
||||
|
||||
class Admin2StackedInline(Admin2Inline):
|
||||
template = os.path.join(
|
||||
settings.ADMIN2_THEME_DIRECTORY, 'edit_inlines/stacked.html')
|
||||
settings.ADMIN2_THEME_DIRECTORY, "edit_inlines/stacked.html"
|
||||
)
|
||||
|
||||
|
||||
def immutable_admin_factory(model_admin):
|
||||
|
|
@ -315,7 +338,7 @@ def immutable_admin_factory(model_admin):
|
|||
the result, but hopefully developers attempting that
|
||||
'workaround/hack' will read our documentation.
|
||||
"""
|
||||
ImmutableAdmin = namedtuple('ImmutableAdmin',
|
||||
model_admin.model_admin_attributes)
|
||||
return ImmutableAdmin(*[getattr(
|
||||
model_admin, x) for x in model_admin.model_admin_attributes])
|
||||
ImmutableAdmin = namedtuple("ImmutableAdmin", model_admin.model_admin_attributes)
|
||||
return ImmutableAdmin(
|
||||
*[getattr(model_admin, x) for x in model_admin.model_admin_attributes]
|
||||
)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from django.http import HttpResponseRedirect
|
|||
from django.urls import reverse, reverse_lazy
|
||||
from django.utils.encoding import force_str
|
||||
from django.utils.text import get_text_list
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
# braces 1.3 views exported AccessMixin
|
||||
# in braces 1.4 this was moved views._access and not exported in views
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Taken from https://github.com/django/django/blob/master/docs/_ext/djangodocs.py
|
||||
# Taken from https://github.com/django/django/blob/main/docs/_ext/djangodocs.py
|
||||
|
||||
import re
|
||||
from sphinx import addnodes
|
||||
|
|
|
|||
|
|
@ -109,8 +109,7 @@ Now when you go to your fork on GitHub, you will see this branch listed under
|
|||
the "Source" tab where it says "Switch Branches". Go ahead and select your
|
||||
topic branch from this list, and then click the "Pull request" button.
|
||||
|
||||
Your pull request should be applied to the **develop** branch of django-admin2.
|
||||
Be sure to change from the default of ``master`` to ``develop``.
|
||||
Your pull request should be applied to the **main** branch of django-admin2.
|
||||
|
||||
Next, you can add a comment about your branch. If this in response to
|
||||
a submitted issue, it is good to put a link to that issue in this initial
|
||||
|
|
@ -133,7 +132,7 @@ Pull upstream changes into your fork regularly
|
|||
To pull in upstream changes::
|
||||
|
||||
git remote add upstream https://github.com/jazzband/django-admin2.git
|
||||
git pull upstream develop
|
||||
git pull upstream main
|
||||
|
||||
For more info, see http://help.github.com/fork-a-repo/
|
||||
|
||||
|
|
@ -145,7 +144,7 @@ Advanced git users: Pull with rebase
|
|||
|
||||
This will pull and then reapply your work on top of the upcoming changes::
|
||||
|
||||
git pull --rebase upstream develop
|
||||
git pull --rebase upstream main
|
||||
|
||||
It saves you from an extra merge, keeping the history cleaner, but it's potentially dangerous because you're rewriting history. For more info, see http://gitready.com/advanced/2009/02/11/pull-with-rebase.html
|
||||
|
||||
|
|
@ -262,8 +261,8 @@ How pull requests are checked, tested, and done
|
|||
|
||||
First we pull the code into a local branch::
|
||||
|
||||
git checkout develop
|
||||
git checkout -b <submitter-github-name>-<submitter-branch> develop
|
||||
git checkout main
|
||||
git checkout -b <submitter-github-name>-<submitter-branch> main
|
||||
git pull git://github.com/<submitter-github-name>/django-admin2.git <submitter-branch> <branch-name>
|
||||
|
||||
Then we run the tests::
|
||||
|
|
@ -279,9 +278,9 @@ We do the following:
|
|||
|
||||
We finish with a merge and push to GitHub::
|
||||
|
||||
git checkout develop
|
||||
git checkout main
|
||||
git merge <branch-name>
|
||||
git push origin develop
|
||||
git push origin main
|
||||
|
||||
.. _installation: install.html
|
||||
.. _GitHub project: https://github.com/jazzband/django-admin2
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ Marking strings for translation
|
|||
|
||||
**Python code**
|
||||
|
||||
Make sure to use ugettext or gettext_lazy on strings that will be shown to the users,
|
||||
Make sure to use gettext or gettext_lazy on strings that will be shown to the users,
|
||||
with string interpolation ( "%(name_of_variable)s" instead of "%s" ) where needed.
|
||||
|
||||
Remember that all languages do not use the same word order, so try to provide flexible strings to translate !
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
from blog.views import BlogListView, BlogDetailView
|
||||
from django.conf import settings
|
||||
from django.conf.urls import url
|
||||
from django.conf.urls.static import static
|
||||
from django.contrib import admin
|
||||
from django.urls import re_path
|
||||
|
||||
from djadmin2.site import djadmin2_site
|
||||
|
||||
|
|
@ -10,13 +10,17 @@ from djadmin2.site import djadmin2_site
|
|||
djadmin2_site.autodiscover()
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^admin2/', djadmin2_site.urls),
|
||||
url(r'^admin/', admin.site.urls),
|
||||
url(r'^blog/', BlogListView.as_view(template_name="blog/blog_list.html"),
|
||||
name='blog_list'),
|
||||
url(r'^blog/detail(?P<pk>\d+)/$',
|
||||
re_path(r"^admin2/", djadmin2_site.urls),
|
||||
re_path(r"^admin/", admin.site.urls),
|
||||
re_path(
|
||||
r"^blog/",
|
||||
BlogListView.as_view(template_name="blog/blog_list.html"),
|
||||
name="blog_list",
|
||||
),
|
||||
re_path(
|
||||
r"^blog/detail(?P<pk>\d+)/$",
|
||||
BlogDetailView.as_view(template_name="blog/blog_detail.html"),
|
||||
name='blog_detail'),
|
||||
url(r'^$', BlogListView.as_view(template_name="blog/home.html"),
|
||||
name='home'),
|
||||
name="blog_detail",
|
||||
),
|
||||
re_path(r"^$", BlogListView.as_view(template_name="blog/home.html"), name="home"),
|
||||
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import division, absolute_import, unicode_literals
|
||||
|
||||
from djadmin2.site import djadmin2_site
|
||||
from .models import CaptionedFile, UncaptionedFile
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
django-extra-views==0.12.0
|
||||
django-braces==1.14.0
|
||||
djangorestframework==3.11.1
|
||||
django-filter==2.3.0
|
||||
django-debug-toolbar>=1.10.1
|
||||
future>=0.15.2
|
||||
pytz>=2016.4
|
||||
django-extra-views
|
||||
django-braces
|
||||
djangorestframework
|
||||
django-filter
|
||||
django-debug-toolbar
|
||||
pytz
|
||||
|
|
|
|||
1
setup.py
1
setup.py
|
|
@ -136,7 +136,6 @@ setup(
|
|||
'djangorestframework>=3.11.1',
|
||||
'django-filter==2.3.0',
|
||||
'pytz>=2016.4',
|
||||
'future>=0.15.2',
|
||||
],
|
||||
extras_require={
|
||||
'testing': ['pytest', 'pytest-django', 'pytest-ipdb'],
|
||||
|
|
|
|||
6
tox.ini
6
tox.ini
|
|
@ -8,8 +8,8 @@ exclude = migrations/*,docs/*
|
|||
envlist =
|
||||
py35-{2.2},
|
||||
py36-{2.2,3.0,3.1},
|
||||
py37-{2.2,3.0,3.1,master},
|
||||
py38-{2.2,3.0,3.1,master},
|
||||
py37-{2.2,3.0,3.1},
|
||||
py38-{2.2,3.0,3.1,main},
|
||||
|
||||
[gh-actions]
|
||||
python =
|
||||
|
|
@ -26,7 +26,7 @@ deps =
|
|||
3.1: Django>=3.1,<3.2
|
||||
3.0: Django>=3.0,<3.1
|
||||
2.2: Django>=2.2,<2.3
|
||||
master: https://github.com/django/django/tarball/master
|
||||
main: https://github.com/django/django/tarball/main
|
||||
setenv=
|
||||
DJANGO_SETTINGS_MODULE = example.settings
|
||||
PYTHONPATH = {toxinidir}/example:{toxinidir}
|
||||
|
|
|
|||
Loading…
Reference in a new issue