diff --git a/.gitignore b/.gitignore index 8898535..755de35 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,19 @@ -*.swp +*.egg-info *.pyc -venv +*.*~ +*.orig +*.old +.*.swp +build +dist +MANIFEST +_build +_static +.project +.pydevproject +.settings +.DS_Store +.svn +.tox +.venv +*.sqlite diff --git a/.hgtags b/.hgtags new file mode 100644 index 0000000..16b6cdb --- /dev/null +++ b/.hgtags @@ -0,0 +1,14 @@ +e9ddbaa0124060da683f2caf04afd5651d5a5234 v0.1.0 +a84159693fb8741aaef00330fcc9cd25895ef4e8 v0.1.1 +27726e15f341209ab72719fceca8752e37b6fe32 v0.1.2 +253b2464507e9cb426f866c1f2561e859233ea69 v0.2.0 +4ebbf2cf39b5cd8cd7f470726ac72f8516895804 v0.4.0 +3e822763bab3c567e003c957786397e0fb781929 v0.3.0 +628450a80e701ee4ea749d2a2e28b6023f52b64a v0.4.1 +a9828ad2cef5b6961325c27cf16d4e0122a3d1f5 v0.5.0 +a9828ad2cef5b6961325c27cf16d4e0122a3d1f5 v0.5.0 +0000000000000000000000000000000000000000 v0.5.0 +0000000000000000000000000000000000000000 v0.5.0 +e03894e9208e3420fad2059e5922bc5cf9e136fc v0.5.0 +615712ac8519e6a89c6d26e1febf168d0dfb50d5 v0.5.1 +746357689a8db7dcf011291e717ad1328c41a29c 0.5.2 diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..a57811d --- /dev/null +++ b/.travis.yml @@ -0,0 +1,11 @@ +language: python +sudo: false +env: + matrix: + - TOXENV=py27-dj17 + - TOXENV=py27-dj18 + - TOXENV=py33-dj17 + - TOXENV=py33-dj18 +install: + - pip install tox +script: tox diff --git a/.tx/config b/.tx/config new file mode 100644 index 0000000..fe17fb6 --- /dev/null +++ b/.tx/config @@ -0,0 +1,7 @@ +[main] +host = https://www.transifex.com + +[django-admin-tools.admin_tools] +file_filter = admin_tools/locale//LC_MESSAGES/.po +source_file = admin_tools/locale/en/LC_MESSAGES/django.po +source_lang = en diff --git a/CHANGELOG b/CHANGELOG index 9360c9b..e02b8c8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,10 +2,28 @@ django-admin-tools changelog ============================ -Version 0.5.2.1 (Entr'ouvert fork) ----------------------------------- -* Django 1.7 support: rename migrations to south_migrations -* source code : http://repos.entrouvert.org/debian/django-admin-tools.git/ +Version 0.6.0, 7 July 2015: +--------------------------- + +* VERY IMPORTANT INFORMATION, PLEASE READ: * + +Starting from this version (0.6.0) django-admin-tools is no longer compatible with Django 1.6 or lower. + +Users of older django version should use the 0.5.2 version available on pypi. + +If you are already using django-admin-tools with django <= 1.6, be sure to pin your requirements file to a specific version, eg: +django-admin-tools==0.5.2 +If you don't do this, a "pip install --upgrade" will break your admin site. +You have been warned ! + +Now for the actual change log: + +* Dropped support for django 1.6 or lower +* Added support for django 1.8 +* Cleaned up old compatibility code +* Use django builtin staticfiles +* Various improvements and bug fixes + Version 0.5.2, 11 August 2014: ------------------------------ diff --git a/INSTALL b/INSTALL index c554519..4ef78df 100644 --- a/INSTALL +++ b/INSTALL @@ -1,7 +1,13 @@ Thanks for downloading django-admin-tools. -This application requires Python 2.4 or later and Django 1.1.0 or newer. -It is also recommended that you install the FeedParser module +This application requires Python 2.7 or later and Django 1.7 or newer. +django-admin-tools is fully compatible with Python 3. + +Important note to users of django 1.6 or below: starting from 0.6.0, +django-admin-tools is *NOT* compatible with Django <= 1.6. If you want, +you can still use the 0.5.2 version. + +It is recommended that you install the FeedParser module (http://www.feedparser.org/) if you want to use the feed dashboard module. To install django-admin-tools, run the following command inside this directory:: diff --git a/MANIFEST.in b/MANIFEST.in index 26cd11d..1ab53ac 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,4 @@ -include CHANGELOG INSTALL LICENSE MANIFEST.in README AUTHORS +include CHANGELOG INSTALL LICENSE MANIFEST.in README.rst AUTHORS recursive-include docs * recursive-include admin_tools/locale * recursive-include admin_tools/static * diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..2a44f65 --- /dev/null +++ b/README.rst @@ -0,0 +1,108 @@ +django-admin-tools +================== + +.. image:: https://travis-ci.org/django-admin-tools/django-admin-tools.svg?branch=master + :target: https://travis-ci.org/django-admin-tools/django-admin-tools + +.. image:: https://img.shields.io/pypi/l/django-admin-tools.svg + +.. image:: https://img.shields.io/pypi/pyversions/django-admin-tools.svg + +.. image:: https://img.shields.io/badge/django-1.7%20or%20newer-green.svg + +.. image:: https://img.shields.io/pypi/dm/django-admin-tools.svg + + +django-admin-tools is a collection of extensions/tools for the default django +administration interface, it includes: + +* a full featured and customizable dashboard; +* a customizable menu bar; +* tools to make admin theming easier. + +The code is hosted on `Github `_. + +Django-admin-tools is generously documented, you can +`browse the documentation online +`_. +a good start is to read `the quickstart guide +`_. + +The project was created by `David Jean Louis `_ and was previously hosted on `Bitbucket `_. + +Please join the `mailing list `_ if you want to discuss of the future of django-admin-tools. + +************ +Requirements +************ + +django-admin-tools requires Python 2.7 or Python 3.3 or newer and Django 1.7 or newer. + +For older python and django versions please use the 0.5.2 version of django-admin-tools which is available on Pypi. + +************ +Installation +************ + +To install django-admin-tools, run the following command inside this directory: + + python setup.py install + +If you have the Python **easy_install** utility available, you can also type +the following to download and install in one step:: + + easy_install django-admin-tools + +Or if you're using **pip**:: + + pip install django-admin-tools + +Or if you'd prefer you can simply place the included "admin_tools" directory +somewhere on your python path, or symlink to it from somewhere on your Python +path; this is useful if you're working from a Mercurial checkout. + +An `installation guide `_ is available in the documentation. + +************* +Documentation +************* + +`Extensive documentation `_ is available, it was made with the excellent `Sphinx program `_ + +************ +Translations +************ + +There is a `a transifex project `_ for django-admin-tools. + +************ +Screenshots +************ + +The django admin login screen: + +.. image:: http://www.izimobil.org/django-admin-tools/images/capture-1.png + :alt: The django admin login screen + + +The admin index dashboard: + +.. image:: http://www.izimobil.org/django-admin-tools/images/capture-2.png + :alt: The admin index dashboard + + +The admin menu: + +.. image:: http://www.izimobil.org/django-admin-tools/images/capture-3.png + :alt: The admin menu + +Dashboard modules can be dragged, collapsed, closed etc.: + +.. image:: http://www.izimobil.org/django-admin-tools/images/capture-4.png + :alt: Dashboard modules can be dragged, collapsed, closed etc. + +The app index dashboard: + +.. image:: http://www.izimobil.org/django-admin-tools/images/capture-5.png + :alt: The app index dashboard + diff --git a/admin_tools/__init__.py b/admin_tools/__init__.py index 7b6528f..42d15a6 100644 --- a/admin_tools/__init__.py +++ b/admin_tools/__init__.py @@ -6,4 +6,4 @@ administration interface, it includes: * a customizable menu bar, * tools to make admin theming easier. """ -VERSION = '0.5.2.1' +VERSION = '0.6.0' diff --git a/admin_tools/dashboard/dashboards.py b/admin_tools/dashboard/dashboards.py index e2f8922..d5242c8 100644 --- a/admin_tools/dashboard/dashboards.py +++ b/admin_tools/dashboard/dashboards.py @@ -3,15 +3,15 @@ Module where admin tools dashboard classes are defined. """ from django.template.defaultfilters import slugify -from django.utils.importlib import import_module +try: + from importlib import import_module +except ImportError: + # Django < 1.9 and Python < 2.7 + from django.utils.importlib import import_module from django.utils.translation import ugettext_lazy as _ from django.core.urlresolvers import reverse from django.contrib.contenttypes.models import ContentType -try: - from django.utils.encoding import force_text -except ImportError: - # Django < 1.5 - from django.utils.encoding import force_unicode as force_text +from django.utils.encoding import force_text from admin_tools.dashboard import modules from admin_tools.utils import get_admin_site_name, uniquify diff --git a/admin_tools/dashboard/migrations/0001_initial.py b/admin_tools/dashboard/migrations/0001_initial.py new file mode 100644 index 0000000..97fad07 --- /dev/null +++ b/admin_tools/dashboard/migrations/0001_initial.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +from django.conf import settings + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='DashboardPreferences', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('data', models.TextField()), + ('dashboard_id', models.CharField(max_length=100)), + ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ], + options={ + 'ordering': ('user',), + 'db_table': 'admin_tools_dashboard_preferences', + }, + bases=(models.Model,), + ), + migrations.AlterUniqueTogether( + name='dashboardpreferences', + unique_together=set([('user', 'dashboard_id')]), + ), + ] diff --git a/admin_tools/dashboard/migrations/__init__.py b/admin_tools/dashboard/migrations/__init__.py new file mode 100644 index 0000000..33a7eba --- /dev/null +++ b/admin_tools/dashboard/migrations/__init__.py @@ -0,0 +1 @@ +__author__ = 'andybaker' diff --git a/admin_tools/dashboard/modules.py b/admin_tools/dashboard/modules.py index d740376..eaad20b 100644 --- a/admin_tools/dashboard/modules.py +++ b/admin_tools/dashboard/modules.py @@ -5,7 +5,7 @@ Module where admin tools dashboard modules classes are defined. from django.utils.text import capfirst from django.core.urlresolvers import reverse from django.contrib.contenttypes.models import ContentType -from django.forms.util import flatatt +from django.forms.utils import flatatt from django.utils.translation import ugettext_lazy as _ from django.utils.itercompat import is_iterable diff --git a/admin_tools/dashboard/registry.py b/admin_tools/dashboard/registry.py index e117352..a5eb766 100644 --- a/admin_tools/dashboard/registry.py +++ b/admin_tools/dashboard/registry.py @@ -32,7 +32,11 @@ def autodiscover(blacklist=[]): """ import imp from django.conf import settings - from django.utils.importlib import import_module + try: + from importlib import import_module + except ImportError: + # Django < 1.9 and Python < 2.7 + from django.utils.importlib import import_module blacklist.append('admin_tools.dashboard') blacklist.append('admin_tools.menu') diff --git a/admin_tools/dashboard/south_migrations/0001_initial.py b/admin_tools/dashboard/south_migrations/0001_initial.py index bfb233a..5c128f2 100644 --- a/admin_tools/dashboard/south_migrations/0001_initial.py +++ b/admin_tools/dashboard/south_migrations/0001_initial.py @@ -4,6 +4,14 @@ from south.db import db from south.v2 import SchemaMigration from django.db import models from django.conf import settings +from south import modelsinspector + +try: + from django.contrib.auth import get_user_model + UserModel = get_user_model() +except ImportError: + from django.contrib.auth.models import User as UserModel + user_model = getattr(settings, 'AUTH_USER_MODEL', 'auth.User') @@ -11,7 +19,7 @@ user_model = getattr(settings, 'AUTH_USER_MODEL', 'auth.User') class Migration(SchemaMigration): def forwards(self, orm): - + # Adding model 'DashboardPreferences' db.create_table('admin_tools_dashboard_preferences', ( ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), @@ -22,7 +30,7 @@ class Migration(SchemaMigration): def backwards(self, orm): - + # Deleting model 'DashboardPreferences' db.delete_table('admin_tools_dashboard_preferences') @@ -42,7 +50,7 @@ class Migration(SchemaMigration): 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, user_model: { - 'Meta': {'object_name': user_model.split('.')[1]}, + 'Meta': modelsinspector.get_model_meta(UserModel), 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), diff --git a/admin_tools/dashboard/templates/admin/index.html b/admin_tools/dashboard/templates/admin/index.html index 688a2d0..9687f6a 100644 --- a/admin_tools/dashboard/templates/admin/index.html +++ b/admin_tools/dashboard/templates/admin/index.html @@ -1,5 +1,5 @@ {% extends "admin/base_site.html" %} -{% load i18n admin_tools_dashboard_tags %} +{% load i18n admin_static admin_tools_dashboard_tags %} {% block extrastyle %} {{ block.super }} diff --git a/admin_tools/dashboard/templates/admin_tools/dashboard/css.html b/admin_tools/dashboard/templates/admin_tools/dashboard/css.html index 8bbd313..4a5d038 100644 --- a/admin_tools/dashboard/templates/admin_tools/dashboard/css.html +++ b/admin_tools/dashboard/templates/admin_tools/dashboard/css.html @@ -1,7 +1,8 @@ - - +{% load staticfiles %} + + -{% for css in css_files %} -{% endfor %} +{% for media_type, files in css_files.items %}{% for css in files %} +{% endfor %}{% endfor %} diff --git a/admin_tools/dashboard/templates/admin_tools/dashboard/dashboard.html b/admin_tools/dashboard/templates/admin_tools/dashboard/dashboard.html index b1c5727..0bacdc2 100644 --- a/admin_tools/dashboard/templates/admin_tools/dashboard/dashboard.html +++ b/admin_tools/dashboard/templates/admin_tools/dashboard/dashboard.html @@ -1,39 +1,38 @@ -{% load i18n admin_tools_dashboard_tags %} -{% load url from future %} +{% load i18n staticfiles admin_tools_dashboard_tags %} {% block dashboard_scripts %} - + + + + {% block extrahead %}{% endblock %} {% block blockbots %}{% endblock %} @@ -28,27 +27,19 @@ {% if user.is_active and user.is_staff %}
- {% trans 'Welcome,' %} - {% filter force_escape %}{% firstof user.get_short_name user.first_name user.get_username user.username %}{% endfilter %}. + {% block welcome-msg %} + {% trans 'Welcome,' %} + {% firstof user.get_short_name user.get_username %}. + {% endblock %} {% block userlinks %} {% url 'django-admindocs-docroot' as docsroot %} {% if docsroot %} {% trans 'Documentation' %} / {% endif %} - {% url 'admin:password_change' as password_change_url %} - {% if password_change_url %} - - {% else %} - + {% if user.has_usable_password %} + {% trans 'Change password' %} / {% endif %} - {% trans 'Change password' %} / - {% url 'admin:logout' as logout_url %} - {% if logout_url %} - - {% else %} - - {% endif %} - {% trans 'Log out' %} + {% trans 'Log out' %} {% endblock %}
{% endif %} @@ -63,11 +54,13 @@ {% endblock %} {% endif %} + {% block messages %} {% if messages %}
    {% for message in messages %} - {{ message }} - {% endfor %}
+ {{ message|capfirst }} + {% endfor %} {% endif %} + {% endblock messages %}
diff --git a/admin_tools/theming/templatetags/theming_tags.py b/admin_tools/theming/templatetags/theming_tags.py index 17f7730..c8cb772 100644 --- a/admin_tools/theming/templatetags/theming_tags.py +++ b/admin_tools/theming/templatetags/theming_tags.py @@ -6,7 +6,7 @@ To load the theming tags just do: ``{% load theming_tags %}``. from django import template from django.conf import settings -from admin_tools.utils import get_media_url +from django.contrib.staticfiles.storage import staticfiles_storage register = template.Library() @@ -15,21 +15,7 @@ def render_theming_css(): Template tag that renders the needed css files for the theming app. """ css = getattr(settings, 'ADMIN_TOOLS_THEMING_CSS', False) - if css: - css = '/'.join([get_media_url(), css]) - else: - css = '/'.join([get_media_url(), 'admin_tools', 'css', 'theming.css']) - return '' % css + if not css: + css = '/'.join(['admin_tools', 'css', 'theming.css']) + return '' % staticfiles_storage.url(css) register.simple_tag(render_theming_css) - - -def get_admin_media(media=''): - """ - Template tag that renders the needed css files for the theming app. - """ - return getattr( - settings, - 'ADMIN_MEDIA_PREFIX', # django 1.3 - '%sadmin/' % getattr(settings, 'STATIC_URL') # django > 1.4 - ) + media -register.simple_tag(get_admin_media) diff --git a/admin_tools/urls.py b/admin_tools/urls.py index 5e2a273..fb1f49e 100644 --- a/admin_tools/urls.py +++ b/admin_tools/urls.py @@ -1,8 +1,5 @@ from django.conf import settings -try: - from django.conf.urls import patterns, url, include -except ImportError: # django < 1.4 - from django.conf.urls.defaults import patterns, url, include +from django.conf.urls import patterns, url, include urls = [] if 'admin_tools.menu' in settings.INSTALLED_APPS: diff --git a/admin_tools/utils.py b/admin_tools/utils.py index 2af2c6c..8ff0412 100644 --- a/admin_tools/utils.py +++ b/admin_tools/utils.py @@ -6,7 +6,11 @@ from fnmatch import fnmatch from django.conf import settings from django.contrib import admin from django.core.urlresolvers import reverse -from django.utils.importlib import import_module +try: + from importlib import import_module +except ImportError: + # Django < 1.9 and Python < 2.7 + from django.utils.importlib import import_module import warnings def uniquify(value, seen_values): @@ -150,14 +154,3 @@ class AppListElementMixin(object): return reverse('%s:%s_%s_add' % (get_admin_site_name(context), app_label, model.__name__.lower())) - -def get_media_url(): - """ - Returns the django admin tools media URL. - """ - media_url = getattr(settings, 'ADMIN_TOOLS_MEDIA_URL', None) - if media_url is None: - media_url = getattr(settings, 'STATIC_URL', None) - if media_url is None: - media_url = getattr(settings, 'MEDIA_URL') - return media_url.rstrip('/') diff --git a/docs/configuration.rst b/docs/configuration.rst index e9938a6..ad94625 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -33,6 +33,12 @@ Required settings First make sure you have the ``django.core.context_processors.request`` template context processor in your ``TEMPLATE_CONTEXT_PROCESSORS``. +.. note:: + Starting from django 1.8, ``TEMPLATE_CONTEXT_PROCESSORS`` is deprecated, + you must add the request context processor in your ``TEMPLATES`` variable + instead, please refer to the + `relevant django documentation `_. + Then, add the django-admin-tools modules to the ``INSTALLED_APPS`` like this:: @@ -69,13 +75,7 @@ Setting up the database To set up the tables that django-admin-tools uses you'll need to type:: - python manage.py syncdb - -django-admin-tools supports `South `_, so if you -have South installed, make sure you run the following commands:: - - python manage.py migrate admin_tools.dashboard - python manage.py migrate admin_tools.menu + python manage.py migrate Adding django-admin-tools to your urls.py file ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/contributing.rst b/docs/contributing.rst index 239e5e3..20bcdd1 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -4,19 +4,17 @@ Contributing to django-admin-tools ================================== You are very welcome to contribute to the project! django-admin-tools is -hosted at `Bitbucket `_, +on `Github `_, which makes collaborating very easy. There are various possibilities to get involved, for example you can: -* `Report bugs `_, +* `Report bugs `_, preferably with patches if you can * `Discuss new features ideas `_ -* `fork the project `_, - implement those features and send a pull request -* Enhance the `documentation - `_ +* Fork the project, implement those features and send a pull request +* Enhance the `documentation `_ * `Translate django-admin-tools `_ in your language diff --git a/docs/dashboard.rst b/docs/dashboard.rst index 8c2dfe8..89517de 100644 --- a/docs/dashboard.rst +++ b/docs/dashboard.rst @@ -11,9 +11,9 @@ custom modules. ..note:: If your layout seems to be broken or you have problems with included javascript files, you should try to reset your dashboard - preferences (assuming a MySQL backend):: + preferences (assuming a MySQL backend, the truncate command also works in postgress):: - python manage dbshell + python manage.py dbshell mysql> truncate admin_tools_dashboard_preferences; For more information see `this issue diff --git a/docs/installation.rst b/docs/installation.rst index 92c8bb8..f65a39e 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -8,7 +8,13 @@ Requirements Before installing django-admin-tools, you'll need to have a copy of `Django `_ already installed. For the -|version| release, Django 1.3 or newer is required. +|version| release, Django 1.7 or newer is required. + +.. note:: + *Important note to users of django 1.6 or below:* + starting from 0.6.0, django-admin-tools is *NOT* compatible with + django <= 1.6. If you want, you can still use the 0.5.2 version + that will always be available on Pypi. For further information, consult the `Django download page `_, which offers convenient @@ -95,19 +101,17 @@ installation script. From a command line in that directory, type:: privileges (e.g., ``sudo python setup.py install``). -Manual installation from a Mercurial checkout -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Manual installation from a git checkout +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If you'd like to try out the latest in-development code, you can -obtain it from the django-admin-tools repository, which is hosted at -`Bitbucket `_ and uses `Mercurial -`_ for version control. To -obtain the latest code and documentation, you'll need to have -Mercurial installed, at which point you can type:: +obtain it from the django-admin-tools repository, which is hosted on +`Github `_. +To obtain the latest code and documentation, you'll need to have +Git installed, at which point you can type:: - hg clone http://bitbucket.org/izi/django-admin-tools/ + git clone https://github.com/django-admin-tools/django-admin-tools.git -This will create a copy of the django-admin-tools Mercurial repository -on your computer; you can then add the ``django-admin-tools`` directory -to your Python import path, or use the ``setup.py`` script to install -as a package. +This will create a copy of the django-admin-tools Git repository on your +computer; you can then add the ``django-admin-tools`` directory to your +Python import path, or use the ``setup.py`` script to install as a package. diff --git a/docs/multiple_admin_sites.rst b/docs/multiple_admin_sites.rst index 9154e48..f13b504 100644 --- a/docs/multiple_admin_sites.rst +++ b/docs/multiple_admin_sites.rst @@ -8,17 +8,10 @@ Introduction Django supports custom admin sites, and of course you can have as many admin sites as you want, django-admin-tools provides basic support for -this, you can setup a custom dashboard for each admin site. +this, you can setup a custom dashboard or menu for each admin site. -.. note:: - Multiple admin site support in django-admin-tools is, at the moment, - limited to dashboards. This means you cannot have different menus or - theming for each instance of admin sites. This will change in the near - near future though. - - -Setting up a different dashboard for each admin site instance -------------------------------------------------------------- +Setting up a different dashboard and menu for each admin site instance +---------------------------------------------------------------------- In the following example we will assume that you have two admin site instances: the default django admin site and a custom admin site of your @@ -51,3 +44,16 @@ settings file:: Note that the same applies for the ``ADMIN_TOOLS_APP_INDEX_DASHBOARD`` settings variable. + +Finally do the same thing for menu:: + + python manage.py custommenu django_admin_menu.py + python manage.py custommenu my_admin_menu.py + +And to tell django-admin-tools to use your custom menu depending on +the admin site being used:: + + ADMIN_TOOLS_MENU = { + 'django.contrib.admin.site': 'yourproject.django_admin_menu.CustomMenu', + 'yourproject.admin.admin_site': 'yourproject.my_admin_menu.CustomMenu', + } diff --git a/docs/quickstart.rst b/docs/quickstart.rst index d08e27e..45fe5a7 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -5,7 +5,13 @@ Quick start guide Before installing django-admin-tools, you'll need to have a copy of `Django `_ already installed. For the -|version| release, Django 1.3 or newer is required. +|version| release, Django 1.7 or newer is required. + +.. note:: + *Important note to users of django 1.6 or below:* + starting from 0.6.0, django-admin-tools is *NOT* compatible with + django <= 1.6. If you want, you can still use the 0.5.2 version + that will always be available on Pypi. Installing django-admin-tools @@ -54,6 +60,12 @@ Configuration First make sure you have the ``django.core.context_processors.request`` template context processor in your ``TEMPLATE_CONTEXT_PROCESSORS``. +.. note:: + Starting from django 1.8, ``TEMPLATE_CONTEXT_PROCESSORS`` is deprecated, + you must add the request context processor in your ``TEMPLATES`` variable + instead, please refer to the + `relevant django documentation `_. + Then, add admin_tools and its modules to the ``INSTALLED_APPS`` like this:: INSTALLED_APPS = ( @@ -82,12 +94,7 @@ Then, just add django-admin-tools to your urls.py file:: Finally simply run:: - python manage.py syncdb - -If you have South installed, make sure you run the following commands:: - - python manage.py migrate admin_tools.dashboard - python manage.py migrate admin_tools.menu + python manage.py migrate Testing your new shiny admin interface -------------------------------------- @@ -99,4 +106,3 @@ changed. django-admin-tools is fully customizable, but this is out of the scope of this quickstart. To learn how to customize django-admin-tools modules please read :ref:`the customization section`. - diff --git a/docs/testing.rst b/docs/testing.rst index 7e65200..f1379e3 100644 --- a/docs/testing.rst +++ b/docs/testing.rst @@ -7,28 +7,14 @@ This is information for developers of django-admin-tools itself. Running tests ------------- -Run the `runtests.sh` script which is situated at the root dir of -django-admin-tools project. -Run all tests:: +First, cd the test_proj directory:: - $ ./runtests.sh + $ cd test_proj -Run only unit tests:: +And to run the tests, just type:: - $ ./runtests.sh unit - -Run only tests for specified app:: - - $ ./runtests.sh dashboard - -Run only one test case:: - - $ ./runtests.sh dashboard.ManagementCommandTest - -Run only one test:: - - $ ./runtests.sh dashboard.ManagementCommandTest.test_customdashboard + $ python manage.py test Code coverage report diff --git a/runtests.sh b/runtests.sh new file mode 100755 index 0000000..7d9c7b7 --- /dev/null +++ b/runtests.sh @@ -0,0 +1,14 @@ +#!/bin/sh +default_unit='admin_tools dashboard theming menu' +default_all="$default_unit test_app" +if [ $# -eq 0 ] +then + test_proj/manage.py test $default_all +else + if [ $1 = 'unit' ] + then + test_proj/manage.py test $default_unit + else + test_proj/manage.py test $* + fi +fi diff --git a/setup.cfg b/setup.cfg index 861a9f5..2a9acf1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,2 @@ -[egg_info] -tag_build = -tag_date = 0 -tag_svn_revision = 0 - +[bdist_wheel] +universal = 1 diff --git a/setup.py b/setup.py index 8bc0263..e25da10 100755 --- a/setup.py +++ b/setup.py @@ -3,12 +3,12 @@ from setuptools import setup, find_packages from admin_tools import VERSION -bitbucket_url = 'http://bitbucket.org/izi/django-admin-tools/' +repo_url = 'https://github.com/django-admin-tools/django-admin-tools' long_desc = ''' %s %s -''' % (open('README').read(), open('CHANGELOG').read()) +''' % (open('README.rst').read(), open('CHANGELOG').read()) setup( name='django-admin-tools', @@ -17,7 +17,7 @@ setup( long_description=long_desc, author='David Jean Louis', author_email='izimobil@gmail.com', - url=bitbucket_url, + url=repo_url, download_url='https://pypi.python.org/packages/source/d/django-admin-tools/django-admin-tools-%s.tar.gz' % VERSION, packages=find_packages(), include_package_data=True, @@ -25,11 +25,16 @@ setup( classifiers=[ 'Development Status :: 4 - Beta', 'Environment :: Web Environment', - 'Framework :: Django', 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', 'Operating System :: OS Independent', - 'Programming Language :: Python', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.3', + 'Programming Language :: Python :: 3.4', + 'Framework :: Django :: 1.7', + 'Framework :: Django :: 1.8', 'Topic :: Software Development :: Libraries :: Python Modules' ], zip_safe=False, diff --git a/test_proj/_coverage/noremove b/test_proj/_coverage/noremove new file mode 100644 index 0000000..e69de29 diff --git a/test_proj/dashboard.py b/test_proj/dashboard.py index 566443f..44d4f56 100644 --- a/test_proj/dashboard.py +++ b/test_proj/dashboard.py @@ -12,6 +12,12 @@ class CustomIndexDashboard(Dashboard): """ Custom index dashboard for test_proj. """ + class Media: + css = { + 'all': ('test_app/dashboard.css',), + } + js = ('test_app/dashboard.js',) + def __init__(self, **kwargs): Dashboard.__init__(self, **kwargs) diff --git a/test_proj/menu.py b/test_proj/menu.py index d92fba5..c0e12fb 100644 --- a/test_proj/menu.py +++ b/test_proj/menu.py @@ -10,6 +10,12 @@ class CustomMenu(Menu): """ Custom Menu for test_proj admin site. """ + class Media: + css = { + 'all': ('test_app/menu.css',), + } + js = ('test_app/menu.js',) + def __init__(self, **kwargs): Menu.__init__(self, **kwargs) self.children += [ diff --git a/test_proj/settings.py b/test_proj/settings.py index 6fb79f0..b702e91 100644 --- a/test_proj/settings.py +++ b/test_proj/settings.py @@ -86,13 +86,6 @@ STATICFILES_FINDERS = ( # Make this unique, and don't share it with anybody. SECRET_KEY = 'django-admin-tools' -# 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', -) - MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', @@ -108,30 +101,63 @@ ROOT_URLCONF = 'test_proj.urls' # Python dotted path to the WSGI application used by Django's runserver. WSGI_APPLICATION = 'test_proj.wsgi.application' -TEMPLATE_CONTEXT_PROCESSORS = ( - 'django.contrib.auth.context_processors.auth', - 'django.core.context_processors.debug', - 'django.core.context_processors.i18n', - 'django.core.context_processors.media', - 'django.core.context_processors.static', - 'django.core.context_processors.request', - 'django.contrib.messages.context_processors.messages', -) +import django +from distutils.version import LooseVersion +version = django.get_version() +use_older_syntax = LooseVersion(django.get_version()) < LooseVersion('1.8') +if use_older_syntax: + 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. + PROJECT_PATH + '/templates', + ) -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. - PROJECT_PATH + '/templates', -) + # 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', + ) + + TEMPLATE_CONTEXT_PROCESSORS = ( + 'django.contrib.auth.context_processors.auth', + 'django.core.context_processors.debug', + 'django.core.context_processors.i18n', + 'django.core.context_processors.media', + 'django.core.context_processors.static', + 'django.core.context_processors.request', + 'django.contrib.messages.context_processors.messages', + ) +else: + TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [ + PROJECT_PATH + '/templates', + # insert your TEMPLATE_DIRS here + ], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.contrib.auth.context_processors.auth', + 'django.template.context_processors.debug', + 'django.template.context_processors.i18n', + 'django.template.context_processors.media', + 'django.template.context_processors.static', + 'django.template.context_processors.request', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, + ] INSTALLED_APPS = [ + 'django.contrib.contenttypes', 'admin_tools', 'admin_tools.dashboard', 'admin_tools.menu', 'admin_tools.theming', 'django.contrib.auth', - 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', @@ -140,7 +166,6 @@ INSTALLED_APPS = [ 'django.contrib.admin', # Uncomment the next line to enable admin documentation: # 'django.contrib.admindocs', - 'south', 'test_app', ] @@ -149,7 +174,7 @@ try: TEST_RUNNER = 'django_coverage.coverage_runner.CoverageRunner' COVERAGE_REPORT_HTML_OUTPUT_DIR = os.path.join(PROJECT_PATH, '_coverage') except ImportError: - TEST_RUNNER = 'django.test.simple.DjangoTestSuiteRunner' + TEST_RUNNER = 'django.test.runner.DiscoverRunner' ADMIN_TOOLS_INDEX_DASHBOARD = 'test_proj.dashboard.CustomIndexDashboard' diff --git a/test_proj/static/do_not_delete.txt b/test_proj/static/do_not_delete.txt new file mode 100644 index 0000000..e69de29 diff --git a/test_proj/templates/404.html b/test_proj/templates/404.html new file mode 100644 index 0000000..57db2e9 --- /dev/null +++ b/test_proj/templates/404.html @@ -0,0 +1 @@ +404 \ No newline at end of file diff --git a/test_proj/templates/500.html b/test_proj/templates/500.html new file mode 100644 index 0000000..eb1f494 --- /dev/null +++ b/test_proj/templates/500.html @@ -0,0 +1 @@ +500 \ No newline at end of file diff --git a/test_proj/test_app/fixtures/users.json b/test_proj/test_app/fixtures/users.json new file mode 100644 index 0000000..8379921 --- /dev/null +++ b/test_proj/test_app/fixtures/users.json @@ -0,0 +1,42 @@ +[ + { + "pk": 1, + "model": "auth.user", + "fields": { + "username": "superuser", + "first_name": "", + "last_name": "", + "is_active": true, + "is_superuser": true, + "is_staff": true, + "last_login": "2010-04-25 17:32:13", + "groups": [], + "user_permissions": [], + "password": "sha1$9efbf$da0bd72857bce1d486bd263b36482fa2fc82336d", + "email": "example@example.com", + "date_joined": "2009-10-30 03:17:26" + } + }, + { + "pk": 2, + "model": "auth.user", + "fields": { + "username": "staff", + "first_name": "", + "last_name": "", + "is_active": true, + "is_superuser": false, + "is_staff": true, + "last_login": "2010-04-25 17:33:01", + "groups": [], + "user_permissions": [ + ["add_bar", "test_app", "bar"], + ["change_bar", "test_app", "bar"], + ["delete_bar", "test_app", "bar"] + ], + "password": "sha1$a7681$6721778bb4a3aff4c7b0b47c20c72afc1adf493d", + "email": "", + "date_joined": "2010-04-25 17:33:01" + } + } +] diff --git a/test_proj/test_app/static/test_app/dashboard.css b/test_proj/test_app/static/test_app/dashboard.css new file mode 100644 index 0000000..f0abad4 --- /dev/null +++ b/test_proj/test_app/static/test_app/dashboard.css @@ -0,0 +1 @@ +/* dummy file for testing purpose */ diff --git a/test_proj/test_app/static/test_app/dashboard.js b/test_proj/test_app/static/test_app/dashboard.js new file mode 100644 index 0000000..c8f5952 --- /dev/null +++ b/test_proj/test_app/static/test_app/dashboard.js @@ -0,0 +1 @@ +// dummy file for testing purpose diff --git a/test_proj/test_app/static/test_app/menu.css b/test_proj/test_app/static/test_app/menu.css new file mode 100644 index 0000000..f0abad4 --- /dev/null +++ b/test_proj/test_app/static/test_app/menu.css @@ -0,0 +1 @@ +/* dummy file for testing purpose */ diff --git a/test_proj/test_app/static/test_app/menu.js b/test_proj/test_app/static/test_app/menu.js new file mode 100644 index 0000000..c8f5952 --- /dev/null +++ b/test_proj/test_app/static/test_app/menu.js @@ -0,0 +1 @@ +// dummy file for testing purpose diff --git a/test_proj/test_app/tests.py b/test_proj/test_app/tests.py index fb826d2..9b98074 100644 --- a/test_proj/test_app/tests.py +++ b/test_proj/test_app/tests.py @@ -3,7 +3,7 @@ import sys class AdminBasicTest(TestCase): - fixtures = ['initial_data.json'] + fixtures = ['users.json'] def test_admin_loads(self): for (username, password) in (('superuser', '123'), ('staff', '123')): @@ -13,6 +13,21 @@ class AdminBasicTest(TestCase): self.assertEqual(response.status_code, 200) self.client.logout() + + def test_custom_menu_media(self): + self.client.login(username='superuser', password='123') + response = self.client.get('/admin/') + self.assertContains(response, '') + self.assertContains(response, '/static/test_app/menu.js') + self.client.logout() + + def test_custom_dashboard_media(self): + self.client.login(username='superuser', password='123') + response = self.client.get('/admin/') + self.assertContains(response, '') + self.assertContains(response, '/static/test_app/dashboard.js') + self.client.logout() + def test_permissions(self): self.client.login(username='staff', password='123') index = self.client.get('/admin/') diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..c4f1288 --- /dev/null +++ b/tox.ini @@ -0,0 +1,27 @@ +[tox] +envlist = py27-dj17, py27-dj18, py33-dj17, py33-dj18 + +[testenv:py27-dj17] +basepython = python2.7 +deps = + django==1.7.8 + +[testenv:py27-dj18] +basepython = python2.7 +deps = + django==1.8.2 + +[testenv:py33-dj17] +basepython = python3.3 +deps = + django==1.7.8 + +[testenv:py33-dj18] +basepython = python3.3 +deps = + django==1.8.2 + +[testenv] +commands = + python -V + python test_proj/manage.py test