Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Made a few more fixes to be compatible with all versions of Django fr…

…om 1.0 to 1.4. Refs #13.
  • Loading branch information...
commit 007593f70541f14c36ce99e3e5efcc996cba9d20 1 parent 329f841
@jphalip jphalip authored
View
5 docs/MANUAL.txt
@@ -8,10 +8,7 @@ tree-structured menus and should be enough for a lot of projects.
It is also easily extendable if you need to add some special behaviour to
your menu items.
-**Please note: django-treemenus requires to have the latest trunk of django
-installed to work properly. It should work with Python 2.3 and above, but
-has mostly been tested under Python 2.5, so please log an issue at
-http://code.google.com/p/django-treemenus/ if you find any bug.**
+django-treemenus works with Django 1.0 and above and with python 2.5 and above.
.. _Django: http://www.djangoproject.com/
View
36 treemenus/admin.py
@@ -1,15 +1,14 @@
import re
+import django
from django.conf.urls.defaults import patterns, url
from django.contrib import admin
from django.contrib.admin.util import unquote
from django.core.exceptions import PermissionDenied
-from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect, Http404
from django.utils.html import escape
from django.utils.translation import ugettext as _
from django.utils.encoding import force_unicode
-from django.views.generic import RedirectView
from treemenus.models import Menu, MenuItem
from treemenus.utils import get_parent_choices, MenuItemChoiceField, move_item_or_clean_ranks
@@ -101,12 +100,18 @@ def get_urls(self):
(r'^(?P<menu_pk>[-\w]+)/items/(?P<menu_item_pk>[-\w]+)/history/$', self.admin_site.admin_view(self.history_menu_item)),
(r'^(?P<menu_pk>[-\w]+)/items/(?P<menu_item_pk>[-\w]+)/move_up/$', self.admin_site.admin_view(self.move_up_item)),
(r'^(?P<menu_pk>[-\w]+)/items/(?P<menu_item_pk>[-\w]+)/move_down/$', self.admin_site.admin_view(self.move_down_item)),
+ )
- # A dummy named URL to satisfy reversing the reversing requirements
+ if django.VERSION >= (1, 4):
+ # Dummy named URLs to satisfy reversing the reversing requirements
# of the menuitem add/change views. It shouldn't ever be used; it
- # just needs to be exist so that it resolves internally.
- url(r'^item_changelist/$', RedirectView.as_view(url='/'), name='treemenus_menuitem_changelist'),
- )
+ # just needs to exist so that it get resolved internally by the
+ # django admin.
+ from django.views.generic import RedirectView
+ my_urls += patterns('',
+ url(r'^item_changelist/$', RedirectView.as_view(url='/'), name='treemenus_menuitem_changelist'),
+ url(r'^item_add/$', RedirectView.as_view(url='/'), name='treemenus_menuitem_add'),
+ )
return my_urls + urls
def get_object_with_change_permissions(self, request, model, obj_pk):
@@ -157,7 +162,12 @@ def move_down_item(self, request, menu_pk, menu_item_pk):
msg = _('The menu item "%s" was moved successfully.') % force_unicode(menu_item)
else:
msg = _('The menu item "%s" is not allowed to move down.') % force_unicode(menu_item)
- request.user.message_set.create(message=msg)
+
+ if django.VERSION >= (1, 4):
+ self.message_user(request, message=msg)
+ else:
+ request.user.message_set.create(message=msg)
+
return HttpResponseRedirect('../../../')
def move_up_item(self, request, menu_pk, menu_item_pk):
@@ -169,8 +179,18 @@ def move_up_item(self, request, menu_pk, menu_item_pk):
msg = _('The menu item "%s" was moved successfully.') % force_unicode(menu_item)
else:
msg = _('The menu item "%s" is not allowed to move up.') % force_unicode(menu_item)
- request.user.message_set.create(message=msg)
+
+ if django.VERSION >= (1, 4):
+ self.message_user(request, message=msg)
+ else:
+ request.user.message_set.create(message=msg)
+
return HttpResponseRedirect('../../../')
+if django.VERSION >= (1, 3):
+ MenuAdmin.change_form_template = 'admin/treemenus/menu/change_form_django1.3_and_above.html'
+else:
+ MenuAdmin.change_form_template = 'admin/treemenus/menu/change_form_django1.2_and_below.html'
+
admin.site.register(Menu, MenuAdmin)
View
72 treemenus/templates/admin/treemenus/menu/change_form_django1.2_and_below.html
@@ -0,0 +1,72 @@
+{% extends "admin/change_form.html" %}
+{% load i18n adminmedia %}
+
+{% block after_related_objects %}
+{% if change %}
+ <fieldset class="module aligned">
+ <h2>{% trans "Menu Items" %}</h2>
+
+ <div class="form-row" >
+ <img src="{% admin_media_prefix %}img/admin/icon_addlink.gif" width="10" height="10"/> <a href="items/add/">{% trans "Add an item" %}</a>
+ </div>
+
+ <style type="text/css">
+ .form-row tbody tr:hover{
+ background-color: #ffffbe;
+ }
+ </style>
+
+ <div class="form-row" >
+ <table cellspacing="0" width="100%">
+ <thead>
+ <tr>
+ <th>{% trans "Caption" %}</th>
+ <th>{% trans "Url" %}</th>
+ <th>{% trans "Named url" %}</th>
+ <th colspan="2">{% trans "Move" %}</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {% for menu_item in original.root_item.get_flattened %}
+ <tr class="{% cycle 'row1' 'row2' %}">
+
+ {% if forloop.first %}
+ <td colspan="3">
+ {% trans "[Root]" %}
+ </td>
+ {% else %}
+ <td width="35%">
+ <a href="items/{{ menu_item.pk }}/">{{ menu_item.caption_with_spacer|safe }}</a>
+ </td>
+ <td width="25%">
+ {{ menu_item.url }}
+ </td>
+ <td width="25%">
+ {{ menu_item.named_url }}
+ </td>
+ {% endif %}
+
+ {% if menu_item.has_siblings %}
+ {% ifnotequal menu_item.rank menu_item.siblings.count %}
+ <td width="20" align="center"><a href="items/{{ menu_item.pk }}/move_down/"><img src="{% admin_media_prefix %}img/admin/arrow-down.gif" border="0" alt="{% trans 'Down' %}"/></b></td>
+ {% else %}
+ <td width="20">&nbsp;</td>
+ {% endifnotequal %}
+
+ {% ifnotequal menu_item.rank 0 %}
+ <td width="20" align="center"><a href="items/{{ menu_item.pk }}/move_up/"><img src="{% admin_media_prefix %}img/admin/arrow-up.gif" border="0" alt="{% trans 'Up' %}"/></a></td>
+ {% else %}
+ <td width="20">&nbsp;</td>
+ {% endifnotequal %}
+ {% else %}
+ <td width="20">&nbsp;</td><td width="20">&nbsp;</td>
+ {% endif %}
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+ </fieldset>
+{% endif %}
+{% endblock %}
View
1  ...s/templates/admin/treemenus/menu/change_form.html → ...eemenus/menu/change_form_django1.3_and_above.html
@@ -2,7 +2,6 @@
{% load i18n adminmedia %}
{% load static %}
-
{% block after_related_objects %}
{% if change %}
<fieldset class="module aligned">
View
97 treemenus/tests/__init__.py
@@ -17,14 +17,13 @@ def setUp(self):
self.old_INSTALLED_APPS = settings.INSTALLED_APPS
settings.INSTALLED_APPS += ['treemenus.tests.fake_menu_extension']
load_app('treemenus.tests.fake_menu_extension')
- call_command('flush', verbosity=0, interactive=False)
call_command('syncdb', verbosity=0, interactive=False)
# since django's r11862 templatags_modules and app_template_dirs are cached
# the cache is not emptied between tests
# clear out the cache of modules to load templatetags from so it gets refreshed
template.templatetags_modules = []
-
+
# clear out the cache of app_directories to load templates from so it gets refreshed
app_directories.app_template_dirs = []
# reload the module to refresh the cache
@@ -37,7 +36,7 @@ def setUp(self):
def tearDown(self):
# Restore settings
settings.INSTALLED_APPS = self.old_INSTALLED_APPS
-
+
def test_view_add_item(self):
menu_data = {
"name": u"menu12387640",
@@ -54,7 +53,7 @@ def test_view_add_item(self):
}
response = self.client.post('/test_treemenus_admin/treemenus/menu/%s/items/add/' % menu.pk, menu_item_data)
self.assertRedirects(response, '/test_treemenus_admin/treemenus/menu/%s/' % menu.pk)
-
+
# Make sure the 'menu' attribute has been set correctly
menu_item = menu.root_item.children()[0]
self.assertEqual(menu_item.menu, menu)
@@ -126,12 +125,12 @@ def test_view_delete_item(self):
# Delete item confirmation
response = self.client.get('/test_treemenus_admin/treemenus/menu/%s/items/%s/delete/' % (menu.pk, menu_item.pk))
self.assertEquals(response.request['PATH_INFO'], '/test_treemenus_admin/treemenus/menu/%s/items/%s/delete/' % (menu.pk, menu_item.pk))
-
+
# Delete item for good
response = self.client.post('/test_treemenus_admin/treemenus/menu/%s/items/%s/delete/' % (menu.pk, menu_item.pk), {'post': 'yes'})
self.assertRedirects(response, '/test_treemenus_admin/treemenus/menu/%s/' % menu.pk)
self.assertRaises(MenuItem.DoesNotExist, lambda: MenuItem.objects.get(pk=menu_item.pk))
-
+
def test_view_change_item(self):
# Add the menu
@@ -151,10 +150,10 @@ def test_view_change_item(self):
}
response = self.client.post('/test_treemenus_admin/treemenus/menu/%s/items/add/' % menu.pk, menu_item_data)
self.assertRedirects(response, '/test_treemenus_admin/treemenus/menu/%s/' % menu.pk)
-
+
menu_item = menu.root_item.children()[0]
menu_item.menu = None # Corrupt it!
-
+
# Change the item
menu_item_data = {
"parent": menu.root_item.pk,
@@ -167,7 +166,7 @@ def test_view_change_item(self):
# Make sure the 'menu' attribute has been restored correctly
menu_item = menu.root_item.children()[0]
self.assertEqual(menu_item.menu, menu)
-
+
# Save and continue editing
menu_item_data = {
"parent": menu.root_item.pk,
@@ -201,7 +200,7 @@ def test_delete(self):
menu_item8 = MenuItem.objects.create(caption='menu_item8', parent=menu_item4)
menu_item9 = MenuItem.objects.create(caption='menu_item9', parent=menu_item1)
menu_item10 = MenuItem.objects.create(caption='menu_item10', parent=menu_item4)
-
+
# menu
# ri
# mi1
@@ -214,7 +213,7 @@ def test_delete(self):
# mi9
# mi2
# mi6
-
+
# Check initial ranks
self.assertEquals(menu_item1.rank, 0)
self.assertEquals(menu_item2.rank, 1)
@@ -226,7 +225,7 @@ def test_delete(self):
self.assertEquals(menu_item8.rank, 1)
self.assertEquals(menu_item9.rank, 3)
self.assertEquals(menu_item10.rank, 2)
-
+
# Check initial levels
self.assertEquals(menu_item1.level, 1)
self.assertEquals(menu_item2.level, 1)
@@ -273,7 +272,7 @@ def test_delete(self):
self.assertEquals(menu_item7.rank, 0)
self.assertEquals(menu_item9.rank, 2)
self.assertEquals(menu_item10.rank, 1)
-
+
# Check levels
self.assertEquals(menu_item1.level, 1)
self.assertEquals(menu_item2.level, 1)
@@ -306,7 +305,7 @@ def test_delete(self):
self.assertEquals(menu_item2.rank, 1)
self.assertEquals(menu_item6.rank, 0)
self.assertEquals(menu_item9.rank, 0)
-
+
# Check levels
self.assertEquals(menu_item1.level, 1)
self.assertEquals(menu_item2.level, 1)
@@ -329,7 +328,7 @@ def test_change_parents(self):
menu_item3 = MenuItem.objects.create(caption='menu_item3', parent=menu_item1)
menu_item4 = MenuItem.objects.create(caption='menu_item4', parent=menu_item1)
menu_item5 = MenuItem.objects.create(caption='menu_item5', parent=menu_item1)
-
+
# menu
# ri
# mi1
@@ -337,14 +336,14 @@ def test_change_parents(self):
# mi4
# mi5
# mi2
-
+
# Check initial ranks
self.assertEquals(menu_item1.rank, 0)
self.assertEquals(menu_item2.rank, 1)
self.assertEquals(menu_item3.rank, 0)
self.assertEquals(menu_item4.rank, 1)
self.assertEquals(menu_item5.rank, 2)
-
+
# Check initial levels
self.assertEquals(menu_item1.level, 1)
self.assertEquals(menu_item2.level, 1)
@@ -357,7 +356,7 @@ def test_change_parents(self):
menu_item4.save()
menu_item5.parent = menu_item2
menu_item5.save()
-
+
# menu
# ri
# mi1
@@ -365,21 +364,21 @@ def test_change_parents(self):
# mi2
# mi5
# mi4
-
+
# Refetch items from db
menu_item1 = MenuItem.objects.get(pk=menu_item1.pk)
menu_item2 = MenuItem.objects.get(pk=menu_item2.pk)
menu_item3 = MenuItem.objects.get(pk=menu_item3.pk)
menu_item4 = MenuItem.objects.get(pk=menu_item4.pk)
menu_item5 = MenuItem.objects.get(pk=menu_item5.pk)
-
+
# Check ranks
self.assertEquals(menu_item1.rank, 0)
self.assertEquals(menu_item2.rank, 1)
self.assertEquals(menu_item3.rank, 0)
self.assertEquals(menu_item4.rank, 2)
self.assertEquals(menu_item5.rank, 0)
-
+
# Check levels
self.assertEquals(menu_item1.level, 1)
self.assertEquals(menu_item2.level, 1)
@@ -396,7 +395,7 @@ def test_change_parents(self):
menu_item3.save()
menu_item1.parent = menu_item4
menu_item1.save()
-
+
# menu
# ri
# mi4
@@ -411,14 +410,14 @@ def test_change_parents(self):
menu_item3 = MenuItem.objects.get(pk=menu_item3.pk)
menu_item4 = MenuItem.objects.get(pk=menu_item4.pk)
menu_item5 = MenuItem.objects.get(pk=menu_item5.pk)
-
+
# Check ranks
self.assertEquals(menu_item1.rank, 0)
self.assertEquals(menu_item2.rank, 0)
self.assertEquals(menu_item3.rank, 1)
self.assertEquals(menu_item4.rank, 0)
self.assertEquals(menu_item5.rank, 1)
-
+
# Check levels
self.assertEquals(menu_item1.level, 2)
self.assertEquals(menu_item2.level, 3)
@@ -435,7 +434,7 @@ def test_change_parents(self):
menu_item1.save()
menu_item5.parent = menu_item4
menu_item5.save()
-
+
# menu
# ri
# mi3
@@ -450,14 +449,14 @@ def test_change_parents(self):
menu_item3 = MenuItem.objects.get(pk=menu_item3.pk)
menu_item4 = MenuItem.objects.get(pk=menu_item4.pk)
menu_item5 = MenuItem.objects.get(pk=menu_item5.pk)
-
+
# Check ranks
self.assertEquals(menu_item1.rank, 1)
self.assertEquals(menu_item2.rank, 0)
self.assertEquals(menu_item3.rank, 0)
self.assertEquals(menu_item4.rank, 0)
self.assertEquals(menu_item5.rank, 1)
-
+
# Check levels
self.assertEquals(menu_item1.level, 1)
self.assertEquals(menu_item2.level, 3)
@@ -473,7 +472,7 @@ def test_move_up(self):
menu_item2 = MenuItem.objects.create(caption='menu_item2', parent=menu.root_item)
menu_item3 = MenuItem.objects.create(caption='menu_item3', parent=menu.root_item)
menu_item4 = MenuItem.objects.create(caption='menu_item4', parent=menu.root_item)
-
+
self.assertEquals(menu_item1.rank, 0)
self.assertEquals(menu_item2.rank, 1)
self.assertEquals(menu_item3.rank, 2)
@@ -481,18 +480,18 @@ def test_move_up(self):
response = self.client.post('/test_treemenus_admin/treemenus/menu/%s/items/%s/move_up/' % (menu.pk, menu_item3.pk))
self.assertRedirects(response, '/test_treemenus_admin/treemenus/menu/%s/' % menu.pk)
-
+
# Retrieve objects from db
menu_item1 = MenuItem.objects.get(caption='menu_item1', parent=menu.root_item)
menu_item2 = MenuItem.objects.get(caption='menu_item2', parent=menu.root_item)
menu_item3 = MenuItem.objects.get(caption='menu_item3', parent=menu.root_item)
menu_item4 = MenuItem.objects.get(caption='menu_item4', parent=menu.root_item)
-
+
self.assertEquals(menu_item1.rank, 0)
self.assertEquals(menu_item2.rank, 2)
self.assertEquals(menu_item3.rank, 1)
self.assertEquals(menu_item4.rank, 3)
-
+
# Test forbidden move up
self.assertRaises(MenuItem.DoesNotExist, lambda: move_item(menu_item1, -1))
@@ -503,7 +502,7 @@ def test_move_down(self):
menu_item2 = MenuItem.objects.create(caption='menu_item2', parent=menu.root_item)
menu_item3 = MenuItem.objects.create(caption='menu_item3', parent=menu.root_item)
menu_item4 = MenuItem.objects.create(caption='menu_item4', parent=menu.root_item)
-
+
self.assertEquals(menu_item1.rank, 0)
self.assertEquals(menu_item2.rank, 1)
self.assertEquals(menu_item3.rank, 2)
@@ -511,21 +510,21 @@ def test_move_down(self):
response = self.client.post('/test_treemenus_admin/treemenus/menu/%s/items/%s/move_down/' % (menu.pk, menu_item3.pk))
self.assertRedirects(response, '/test_treemenus_admin/treemenus/menu/%s/' % menu.pk)
-
+
# Retrieve objects from db
menu_item1 = MenuItem.objects.get(caption='menu_item1', parent=menu.root_item)
menu_item2 = MenuItem.objects.get(caption='menu_item2', parent=menu.root_item)
menu_item3 = MenuItem.objects.get(caption='menu_item3', parent=menu.root_item)
menu_item4 = MenuItem.objects.get(caption='menu_item4', parent=menu.root_item)
-
+
self.assertEquals(menu_item1.rank, 0)
self.assertEquals(menu_item2.rank, 1)
self.assertEquals(menu_item3.rank, 3)
self.assertEquals(menu_item4.rank, 2)
-
+
# Test forbidden move up
self.assertRaises(MenuItem.DoesNotExist, lambda: move_item(menu_item3, 1))
-
+
def test_clean_children_ranks(self):
menu = Menu(name='menu_clean_children_ranks')
menu.save()
@@ -533,13 +532,13 @@ def test_clean_children_ranks(self):
menu_item2 = MenuItem.objects.create(caption='menu_item2', parent=menu.root_item)
menu_item3 = MenuItem.objects.create(caption='menu_item3', parent=menu.root_item)
menu_item4 = MenuItem.objects.create(caption='menu_item4', parent=menu.root_item)
-
+
# Initial check
self.assertEquals(menu_item1.rank, 0)
self.assertEquals(menu_item2.rank, 1)
self.assertEquals(menu_item3.rank, 2)
self.assertEquals(menu_item4.rank, 3)
-
+
# Mess up ranks
menu_item1.rank = 99
menu_item1.save()
@@ -551,20 +550,20 @@ def test_clean_children_ranks(self):
menu_item4.save()
clean_ranks(menu.root_item.children())
-
+
# Retrieve objects from db
menu_item1 = MenuItem.objects.get(caption='menu_item1', parent=menu.root_item)
menu_item2 = MenuItem.objects.get(caption='menu_item2', parent=menu.root_item)
menu_item3 = MenuItem.objects.get(caption='menu_item3', parent=menu.root_item)
menu_item4 = MenuItem.objects.get(caption='menu_item4', parent=menu.root_item)
-
+
self.assertEquals(menu_item1.rank, 3)
self.assertEquals(menu_item2.rank, 0)
self.assertEquals(menu_item3.rank, 1)
self.assertEquals(menu_item4.rank, 2)
-
-
-
+
+
+
def test_move_item_or_clean_ranks(self):
menu = Menu(name='menu_move_item_or_clean_ranks')
menu.save()
@@ -572,12 +571,12 @@ def test_move_item_or_clean_ranks(self):
menu_item2 = MenuItem.objects.create(caption='menu_item2', parent=menu.root_item)
menu_item3 = MenuItem.objects.create(caption='menu_item3', parent=menu.root_item)
menu_item4 = MenuItem.objects.create(caption='menu_item4', parent=menu.root_item)
-
+
self.assertEquals(menu_item1.rank, 0)
self.assertEquals(menu_item2.rank, 1)
self.assertEquals(menu_item3.rank, 2)
self.assertEquals(menu_item4.rank, 3)
-
+
# Corrupt ranks
menu_item1.rank = 0
menu_item1.save()
@@ -589,13 +588,13 @@ def test_move_item_or_clean_ranks(self):
menu_item4.save()
move_item_or_clean_ranks(menu_item3, -1) # Move up
-
+
# Retrieve objects from db
menu_item1 = MenuItem.objects.get(caption='menu_item1', parent=menu.root_item)
menu_item2 = MenuItem.objects.get(caption='menu_item2', parent=menu.root_item)
menu_item3 = MenuItem.objects.get(caption='menu_item3', parent=menu.root_item)
menu_item4 = MenuItem.objects.get(caption='menu_item4', parent=menu.root_item)
-
+
self.assertEquals(menu_item1.rank, 0)
self.assertEquals(menu_item2.rank, 2)
self.assertEquals(menu_item3.rank, 1)
@@ -612,13 +611,13 @@ def test_move_item_or_clean_ranks(self):
menu_item4.save()
move_item_or_clean_ranks(menu_item1, 1) # Try to move down
-
+
# Retrieve objects from db
menu_item1 = MenuItem.objects.get(caption='menu_item1', parent=menu.root_item)
menu_item2 = MenuItem.objects.get(caption='menu_item2', parent=menu.root_item)
menu_item3 = MenuItem.objects.get(caption='menu_item3', parent=menu.root_item)
menu_item4 = MenuItem.objects.get(caption='menu_item4', parent=menu.root_item)
-
+
self.assertEquals(menu_item1.rank, 3)
self.assertEquals(menu_item2.rank, 0)
self.assertEquals(menu_item3.rank, 1)
View
13 treemenus/tests/urls.py
@@ -1,9 +1,14 @@
+import django
from django.conf.urls.defaults import *
from django.contrib import admin
admin.autodiscover()
-urlpatterns = patterns('',
- #(r'^test_treemenus_admin/(.*)', admin.site.root), # For older versions of Django (see deprecated MenuAdmin.__call__() method)
- (r'^test_treemenus_admin/', include(admin.site.urls)),
-)
+if django.VERSION >= (1, 1):
+ urlpatterns = patterns('',
+ (r'^test_treemenus_admin/', include(admin.site.urls)),
+ )
+else:
+ urlpatterns = patterns('',
+ (r'^test_treemenus_admin/(.*)', admin.site.root),
+ )
Please sign in to comment.
Something went wrong with that request. Please try again.