create a djadmin2_site in djadmin2/site.py to make it work in django 1.9

This commit is contained in:
arthur 2016-05-08 01:29:17 +02:00
parent 754f5dab56
commit 23f7f9479a
19 changed files with 160 additions and 209 deletions

View file

@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
from __future__ import division, absolute_import, unicode_literals
from . import core
from . import types
__version__ = '0.6.1'
@ -11,14 +10,3 @@ VERSION = __version__ # synonym
# Default datetime input and output formats
ISO_8601 = 'iso-8601'
default = core.Admin2()
ModelAdmin2 = types.ModelAdmin2
Admin2TabularInline = types.Admin2TabularInline
Admin2StackedInline = types.Admin2StackedInline
# Utility to make migration between versions easier
sites = default
ModelAdmin = ModelAdmin2
AdminInline = Admin2TabularInline
Admin2Inline = Admin2TabularInline

View file

@ -7,9 +7,10 @@ from django.contrib.sites.models import Site
from rest_framework.relations import PrimaryKeyRelatedField
import djadmin2
from djadmin2.forms import UserCreationForm, UserChangeForm
from djadmin2.apiviews import Admin2APISerializer
from djadmin2.site import djadmin2_site
from djadmin2.types import ModelAdmin2
class GroupSerializer(Admin2APISerializer):
@ -19,7 +20,7 @@ class GroupSerializer(Admin2APISerializer):
model = Group
class GroupAdmin2(djadmin2.ModelAdmin2):
class GroupAdmin2(ModelAdmin2):
api_serializer_class = GroupSerializer
@ -31,7 +32,7 @@ class UserSerializer(Admin2APISerializer):
exclude = ('password',)
class UserAdmin2(djadmin2.ModelAdmin2):
class UserAdmin2(ModelAdmin2):
create_form_class = UserCreationForm
update_form_class = UserChangeForm
search_fields = ('username', 'groups__name', 'first_name', 'last_name',
@ -43,15 +44,15 @@ class UserAdmin2(djadmin2.ModelAdmin2):
# Register each model with the admin
djadmin2.default.register(User, UserAdmin2)
djadmin2.default.register(Group, GroupAdmin2)
djadmin2_site.register(User, UserAdmin2)
djadmin2_site.register(Group, GroupAdmin2)
# Register the sites app if it's been activated in INSTALLED_APPS
if "django.contrib.sites" in settings.INSTALLED_APPS:
class SiteAdmin2(djadmin2.ModelAdmin2):
class SiteAdmin2(ModelAdmin2):
list_display = ('domain', 'name')
search_fields = ('domain', 'name')
djadmin2.default.register(Site, SiteAdmin2)
djadmin2_site.register(Site, SiteAdmin2)

View file

@ -182,8 +182,8 @@ _django_field_to_floppyform_widget = {
_create_widget(floppyforms.widgets.URLInput),
django.forms.fields.SlugField:
_create_widget(floppyforms.widgets.SlugInput),
django.forms.fields.IPAddressField:
_create_widget(floppyforms.widgets.IPAddressInput),
#django.forms.fields.IPAddressField:
# _create_widget(floppyforms.widgets.IPAddressInput),
django.forms.fields.SplitDateTimeField:
_create_splitdatetimewidget(floppyforms.widgets.SplitDateTimeWidget),
}

View file

@ -7,8 +7,8 @@ from django.contrib.contenttypes.models import ContentType
from django.db import models
from django.db.models import signals
from django.utils.encoding import force_text
from django.utils.encoding import smart_text
from django.utils.encoding import python_2_unicode_compatible
from django.utils.encoding import smart_text
from django.utils.translation import ugettext, ugettext_lazy as _
from . import permissions

3
djadmin2/site.py Normal file
View file

@ -0,0 +1,3 @@
from . import core
djadmin2_site = core.Admin2()

View file

@ -5,7 +5,7 @@ from django.test.client import RequestFactory
import floppyforms
import djadmin2
from djadmin2.site import djadmin2_site
from ..admin2 import UserAdmin2
@ -27,7 +27,7 @@ class UserAdminTest(TestCase):
request = self.factory.get(reverse('admin2:auth_user_create'))
request.user = self.user
model_admin = UserAdmin2(User, djadmin2.default)
model_admin = UserAdmin2(User, djadmin2_site)
view = model_admin.create_view.view.as_view(
**model_admin.get_create_kwargs())
response = view(request)
@ -48,7 +48,7 @@ class UserAdminTest(TestCase):
request = self.factory.get(
reverse('admin2:auth_user_update', args=(self.user.pk,)))
request.user = self.user
model_admin = UserAdmin2(User, djadmin2.default)
model_admin = UserAdmin2(User, djadmin2_site)
view = model_admin.update_view.view.as_view(
**model_admin.get_update_kwargs())
response = view(request, pk=self.user.pk)

View file

@ -4,7 +4,7 @@ from django.test import TestCase
from django.contrib.auth.models import Group, User
from django.contrib.sites.models import Site
import djadmin2
from djadmin2.site import djadmin2_site
from ..types import ModelAdmin2
from ..core import Admin2
@ -71,4 +71,4 @@ class Admin2Test(TestCase):
def test_default_entries(self):
expected_default_models = (User, Group, Site)
for model in expected_default_models:
self.assertTrue(isinstance(djadmin2.default.registry[model], ModelAdmin2))
self.assertTrue(isinstance(djadmin2_site.registry[model], ModelAdmin2))

View file

@ -3,21 +3,22 @@ from __future__ import division, absolute_import, unicode_literals
from django.utils.translation import ugettext_lazy
import djadmin2
from djadmin2 import renderers
from djadmin2.actions import DeleteSelectedAction
# Import your custom models
from djadmin2.site import djadmin2_site
from djadmin2.types import Admin2TabularInline, ModelAdmin2
from .actions import (CustomPublishAction, PublishAllItemsAction,
unpublish_items, unpublish_all_items)
from .models import Post, Comment
class CommentInline(djadmin2.Admin2TabularInline):
class CommentInline(Admin2TabularInline):
model = Comment
class PostAdmin(djadmin2.ModelAdmin2):
class PostAdmin(ModelAdmin2):
list_actions = [
DeleteSelectedAction, CustomPublishAction,
PublishAllItemsAction, unpublish_items,
@ -34,7 +35,7 @@ class PostAdmin(djadmin2.ModelAdmin2):
ordering = ["-published_date", "title",]
class CommentAdmin(djadmin2.ModelAdmin2):
class CommentAdmin(ModelAdmin2):
search_fields = ('body', '=post__title')
list_filter = ['post', ]
actions_on_top = True
@ -42,12 +43,12 @@ class CommentAdmin(djadmin2.ModelAdmin2):
actions_selection_counter = False
# Register the blog app with a verbose name
djadmin2.default.register_app_verbose_name(
djadmin2_site.register_app_verbose_name(
'blog',
ugettext_lazy('My Blog')
)
# Register each model with the admin
djadmin2.default.register(Post, PostAdmin)
djadmin2.default.register(Comment, CommentAdmin)
djadmin2_site.register(Post, PostAdmin)
djadmin2_site.register(Comment, CommentAdmin)

View file

@ -1,4 +1,4 @@
{% load i18n static %}<!DOCTYPE html>
{% load i18n staticfiles %}<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
@ -7,8 +7,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Bootstrap -->
{% block css %}
<link href="{{ STATIC_URL }}themes/bootstrap/css/bootstrap.min.css" rel="stylesheet" media="screen">
<link href="{{ STATIC_URL }}themes/bootstrap/css/bootstrap-custom.css" rel="stylesheet" media="screen">
<link href="{% static "themes/bootstrap/css/bootstrap.min.css" %}" rel="stylesheet" media="screen">
<link href="{% static "themes/bootstrap/css/bootstrap-custom.css" %}" rel="stylesheet" media="screen">
{% endblock css %}
</head>
<body>
@ -19,8 +19,8 @@
{% block javascript %}
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="{{ STATIC_URL }}themes/bootstrap/js/jquery.min.js">\x3C/script>')</script>
<script src="{{ STATIC_URL }}themes/bootstrap/js/bootstrap.min.js"></script>
<script>window.jQuery || document.write('<script src="{% static "themes/bootstrap/js/jquery.min.js" %}">\x3C/script>')</script>
<script src="{% static "themes/bootstrap/js/bootstrap.min.js" %}"></script>
{% endblock javascript %}
</body>
</html>

View file

@ -5,9 +5,9 @@ from django.test import TestCase
from django.test.client import RequestFactory
from django.core.urlresolvers import reverse
from djadmin2.types import ModelAdmin2
from ..models import Post
import djadmin2
import djadmin2.filters as djadmin2_filters
import django_filters
@ -18,11 +18,11 @@ class ListFilterBuilderTest(TestCase):
self.rf = RequestFactory()
def test_filter_building(self):
class PostAdminSimple(djadmin2.ModelAdmin2):
class PostAdminSimple(ModelAdmin2):
list_filter = ['published', ]
class PostAdminWithFilterInstances(djadmin2.ModelAdmin2):
class PostAdminWithFilterInstances(ModelAdmin2):
list_filter = [
django_filters.BooleanFilter(name='published'),
]
@ -33,7 +33,7 @@ class ListFilterBuilderTest(TestCase):
fields = ['published']
class PostAdminWithFilterSetInst(djadmin2.ModelAdmin2):
class PostAdminWithFilterSetInst(ModelAdmin2):
list_filter = FS
Post.objects.create(title="post_1_title", body="body")

View file

@ -4,12 +4,13 @@ from django.template import Template, Context
from django.test import TestCase
from django.test.client import RequestFactory
import djadmin2
from djadmin2 import ModelAdmin2
from djadmin2.permissions import TemplatePermissionChecker
from blog.models import Post
from djadmin2.site import djadmin2_site
from djadmin2.types import ModelAdmin2
class TemplatePermissionTest(TestCase):
def setUp(self):
@ -26,7 +27,7 @@ class TemplatePermissionTest(TestCase):
return template.render(context)
def test_permission_wrapper(self):
model_admin = ModelAdmin2(Post, djadmin2.default)
model_admin = ModelAdmin2(Post, djadmin2_site)
request = self.factory.get(reverse('admin2:blog_post_index'))
request.user = self.user
permissions = TemplatePermissionChecker(request, model_admin)
@ -61,7 +62,7 @@ class TemplatePermissionTest(TestCase):
codename='add_post')
self.user.user_permissions.add(post_add_permission)
model_admin = ModelAdmin2(Post, djadmin2.default)
model_admin = ModelAdmin2(Post, djadmin2_site)
request = self.factory.get(reverse('admin2:blog_post_index'))
request.user = self.user
permissions = TemplatePermissionChecker(request, model_admin)
@ -89,8 +90,8 @@ class TemplatePermissionTest(TestCase):
self.assertEqual(result, '')
def test_admin_binding(self):
user_admin = djadmin2.default.get_admin_by_name('auth_user')
post_admin = djadmin2.default.get_admin_by_name('blog_post')
user_admin = djadmin2_site.get_admin_by_name('auth_user')
post_admin = djadmin2_site.get_admin_by_name('blog_post')
request = self.factory.get(reverse('admin2:auth_user_index'))
request.user = self.user
permissions = TemplatePermissionChecker(request, user_admin)
@ -155,8 +156,8 @@ class TemplatePermissionTest(TestCase):
self.assertEqual(result, '')
def test_view_binding(self):
user_admin = djadmin2.default.get_admin_by_name('auth_user')
post_admin = djadmin2.default.get_admin_by_name('blog_post')
user_admin = djadmin2_site.get_admin_by_name('auth_user')
post_admin = djadmin2_site.get_admin_by_name('blog_post')
request = self.factory.get(reverse('admin2:auth_user_index'))
request.user = self.user
permissions = TemplatePermissionChecker(request, user_admin)
@ -235,7 +236,7 @@ class TemplatePermissionTest(TestCase):
self.assertEqual(result, '1True2False34True')
def test_object_level_permission(self):
model_admin = ModelAdmin2(Post, djadmin2.default)
model_admin = ModelAdmin2(Post, djadmin2_site)
request = self.factory.get(reverse('admin2:blog_post_index'))
request.user = self.user
permissions = TemplatePermissionChecker(request, model_admin)

BIN
example/db.sqlite3 Normal file

Binary file not shown.

View file

@ -1,117 +1,20 @@
# Django settings for example project.
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
DEBUG = True
TEMPLATE_DEBUG = DEBUG
ADMINS = (
# ('Your Name', 'your_email@example.com'),
)
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/
MANAGERS = ADMINS
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'example.db',
}
}
# Hosts/domain names that are valid for this site; required if DEBUG is False
# See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts
ALLOWED_HOSTS = []
# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# In a Windows environment this must be set to your system time zone.
TIME_ZONE = 'America/Chicago'
# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'
SITE_ID = 1
# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True
# If you set this to False, Django will not format dates, numbers and
# calendars according to the current locale.
USE_L10N = True
# If you set this to False, Django will not use timezone-aware datetimes.
USE_TZ = True
# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/var/www/example.com/media/"
MEDIA_ROOT = ''
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://example.com/media/", "http://media.example.com/"
MEDIA_URL = ''
# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/var/www/example.com/static/"
STATIC_ROOT = ''
# URL prefix for static files.
# Example: "http://example.com/static/", "http://static.example.com/"
STATIC_URL = '/static/'
# Additional locations of static files
STATICFILES_DIRS = (
# Put strings here, like "/home/html/static" or "C:/www/django/static".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
os.path.join(BASE_DIR, "static"),
)
# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
)
# Make this unique, and don't share it with anybody.
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '*ymubzn8p_s7vrm%jsqvr6$qnea_5mcp(ao0z-yh1q0gro!0g1'
# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
# 'django.template.loaders.eggs.Loader',
)
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
# Uncomment the next line for simple clickjacking protection:
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
ROOT_URLCONF = 'example.urls'
# Python dotted path to the WSGI application used by Django's runserver.
WSGI_APPLICATION = 'example.wsgi.application'
TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
)
ALLOWED_HOSTS = []
INSTALLED_APPS = (
'django.contrib.auth',
@ -133,34 +36,91 @@ INSTALLED_APPS = (
'polls'
)
# A sample logging configuration. The only tangible logging
# performed by this configuration is to send an email to
# the site admins on every HTTP 500 error when DEBUG=False.
# See http://docs.djangoproject.com/en/dev/topics/logging for
# more details on how to customize your logging configuration.
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
'handlers': {
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
}
},
'loggers': {
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': True,
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
# Uncomment the next line for simple clickjacking protection:
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
ROOT_URLCONF = 'example.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'example.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.9/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Password validation
# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/1.9/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
SITE_ID = 1
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.9/howto/static-files/
STATIC_URL = '/static/'
# Additional locations of static files
STATICFILES_DIRS = (
# Put strings here, like "/home/html/static" or "C:/www/django/static".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
os.path.join(BASE_DIR, "static"),
)
ADMIN2_THEME_DIRECTORY = "djadmin2theme_default"

View file

@ -1,18 +1,15 @@
from django.conf.urls import patterns, include, url
from django.conf.urls import include, url
from django.contrib import admin
from djadmin2.site import djadmin2_site
from blog.views import BlogListView, BlogDetailView
admin.autodiscover()
djadmin2_site.autodiscover()
import djadmin2
djadmin2.default.autodiscover()
urlpatterns = patterns('',
url(r'^admin2/', include(djadmin2.default.urls)),
urlpatterns = [
url(r'^admin2/', include(djadmin2_site.urls)),
url(r'^admin/', include(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+)/$', BlogDetailView.as_view(template_name="blog/blog_detail.html"), name='blog_detail'),
url(r'^$', BlogListView.as_view(template_name="blog/home.html"), name='home'),
)
]

View file

@ -2,9 +2,10 @@
from __future__ import division, absolute_import, unicode_literals
import djadmin2
from djadmin2.site import djadmin2_site
from .models import CaptionedFile, UncaptionedFile
djadmin2.default.register(CaptionedFile)
djadmin2.default.register(UncaptionedFile)
djadmin2_site.register(CaptionedFile)
djadmin2_site.register(UncaptionedFile)

View file

@ -9,8 +9,7 @@ from django.utils.translation import ugettext_lazy as _
@python_2_unicode_compatible
class CaptionedFile(models.Model):
caption = models.CharField(max_length=200, verbose_name=_('caption'))
publication = models.FileField(
upload_to='media', verbose_name=_('Uploaded File'))
publication = models.FileField(upload_to='media', verbose_name=_('Uploaded File'))
def __str__(self):
return self.caption
@ -22,11 +21,10 @@ class CaptionedFile(models.Model):
@python_2_unicode_compatible
class UncaptionedFile(models.Model):
publication = models.FileField(
upload_to='media', verbose_name=_('Uploaded File'))
publication = models.FileField(upload_to='media', verbose_name=_('Uploaded File'))
def __str__(self):
return self.publication
return self.publication.name
class Meta:
verbose_name = _('Uncaptioned File')

View file

@ -1,17 +1,17 @@
# -*- coding: utf-8 -*-
from __future__ import division, absolute_import, unicode_literals
import djadmin2
from djadmin2.site import djadmin2_site
from djadmin2.types import Admin2TabularInline, ModelAdmin2
from .models import Poll, Choice
class ChoiceInline(djadmin2.Admin2TabularInline):
class ChoiceInline(Admin2TabularInline):
model = Choice
extra = 3
class PollAdmin(djadmin2.ModelAdmin2):
class PollAdmin(ModelAdmin2):
fieldsets = [
(None, {'fields': ['question']}),
('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
@ -23,4 +23,4 @@ class PollAdmin(djadmin2.ModelAdmin2):
date_hierarchy = 'pub_date'
djadmin2.default.register(Poll, PollAdmin)
djadmin2_site.register(Poll, PollAdmin)

View file

@ -5,4 +5,4 @@ django-floppyforms>=1.6.2
django-filter>=0.13.0
django-crispy-forms>=1.3.2
django-debug-toolbar>=0.9.4
pytz==2014.7
pytz==2016.4

View file

@ -6,10 +6,11 @@ exclude = migrations/*,docs/*
[tox]
envlist =
py27-{1.8,1.9,master},
py33-{1.8},
py34-{1.8,1.9,master},
py35-{1.8,1.9,master},
#py27-{1.8,1.9,master},
#py33-{1.8},
#py34-{1.8,1.9,master},
#py35-{1.8,1.9,master},
py35-{1.8},
[testenv]
commands =