Merge pull request #475 from jazzband/master-to-main

Rename Django's dev branch to main.
This commit is contained in:
Jannis Leidel 2021-03-09 18:36:51 +01:00 committed by GitHub
commit 8cee4de75d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 197 additions and 168 deletions

View file

@ -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
============

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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 %}

View file

@ -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]
)

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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 !

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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'],

View file

@ -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}