Merge branch 'order-subset'
commit
95e21eea5e
|
|
@ -28,6 +28,8 @@ STATIC_URL = settings.STATIC_URL
|
|||
|
||||
|
||||
class SortableAdminBase(object):
|
||||
filtered_objects = []
|
||||
|
||||
def changelist_view(self, request, extra_context=None):
|
||||
"""
|
||||
If the model that inherits Sortable has more than one object,
|
||||
|
|
@ -35,7 +37,11 @@ class SortableAdminBase(object):
|
|||
object_tools block to take people to the view to change the sorting.
|
||||
"""
|
||||
|
||||
if get_is_sortable(self.queryset(request)):
|
||||
# Apply any additional filters to create a subset of sortable objects
|
||||
self.filtered_objects = self.queryset(request).filter(
|
||||
**self.model.sorting_filters)
|
||||
|
||||
if get_is_sortable(self.filtered_objects):
|
||||
self.change_list_template = \
|
||||
self.sortable_change_list_with_sort_link_template
|
||||
self.is_sortable = True
|
||||
|
|
@ -61,8 +67,6 @@ class SortableAdmin(SortableAdminBase, ModelAdmin):
|
|||
'adminsortable/change_list_with_sort_link.html'
|
||||
sortable_change_form_template = 'adminsortable/change_form.html'
|
||||
sortable_change_list_template = 'adminsortable/change_list.html'
|
||||
sortable_javascript_includes_template = \
|
||||
'adminsortable/shared/javascript_includes.html'
|
||||
|
||||
change_form_template_extends = 'admin/change_form.html'
|
||||
change_list_template_extends = 'admin/change_list.html'
|
||||
|
|
@ -102,7 +106,7 @@ class SortableAdmin(SortableAdminBase, ModelAdmin):
|
|||
has_perm = request.user.has_perm('{0}.{1}'.format(opts.app_label,
|
||||
opts.get_change_permission()))
|
||||
|
||||
objects = self.queryset(request)
|
||||
objects = self.filtered_objects
|
||||
|
||||
# Determine if we need to regroup objects relative to a
|
||||
# foreign key specified on the model class that is extending Sortable.
|
||||
|
|
@ -161,9 +165,7 @@ class SortableAdmin(SortableAdminBase, ModelAdmin):
|
|||
'group_expression': sortable_by_expression,
|
||||
'sortable_by_class': sortable_by_class,
|
||||
'sortable_by_class_is_sortable': sortable_by_class_is_sortable,
|
||||
'sortable_by_class_display_name': sortable_by_class_display_name,
|
||||
'sortable_javascript_includes_template':
|
||||
self.sortable_javascript_includes_template
|
||||
'sortable_by_class_display_name': sortable_by_class_display_name
|
||||
}
|
||||
return render(request, self.sortable_change_list_template, context)
|
||||
|
||||
|
|
@ -200,8 +202,6 @@ class SortableAdmin(SortableAdminBase, ModelAdmin):
|
|||
self.change_form_template = self.sortable_change_form_template
|
||||
|
||||
extra_context.update({
|
||||
'sortable_javascript_includes_template':
|
||||
self.sortable_javascript_includes_template,
|
||||
'has_sortable_tabular_inlines':
|
||||
self.has_sortable_tabular_inlines,
|
||||
'has_sortable_stacked_inlines':
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ class Sortable(models.Model):
|
|||
order = models.PositiveIntegerField(editable=False, default=1,
|
||||
db_index=True)
|
||||
is_sortable = False
|
||||
sorting_filters = {}
|
||||
|
||||
# legacy support
|
||||
sortable_by = None
|
||||
|
|
@ -53,7 +54,7 @@ class Sortable(models.Model):
|
|||
sortable_foreign_keys.append(field)
|
||||
if len(sortable_foreign_keys) > 1:
|
||||
raise MultipleSortableForeignKeyException(
|
||||
u'%s may only have one SortableForeignKey' % self)
|
||||
u'{} may only have one SortableForeignKey'.format(self))
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.id:
|
||||
|
|
|
|||
|
|
@ -9,11 +9,11 @@
|
|||
|
||||
{% block extrahead %}
|
||||
{{ block.super }}
|
||||
<script type="text/javascript" src="{% static 'admin/js/jquery.js' %}"></script>
|
||||
<script type="text/javascript" src="{% static 'admin/js/jquery.init.js' %}"></script>
|
||||
<script type="text/javascript" src="{% static 'adminsortable/js/jquery-ui-django-admin.min.js' %}"></script>
|
||||
<script type="text/javascript" src="{% static 'adminsortable/js/jquery.django-csrf.js' %}"></script>
|
||||
<script type="text/javascript" src="{% static 'adminsortable/js/admin.sortable.js' %}"></script>
|
||||
<script src="{% static 'admin/js/jquery.js' %}"></script>
|
||||
<script src="{% static 'admin/js/jquery.init.js' %}"></script>
|
||||
<script src="{% static 'adminsortable/js/jquery-ui-django-admin.min.js' %}"></script>
|
||||
<script src="{% static 'adminsortable/js/jquery.django-csrf.js' %}"></script>
|
||||
<script src="{% static 'adminsortable/js/admin.sortable.js' %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block title %}{% blocktrans with opts.verbose_name_plural|capfirst as model %}Drag and drop {{ model }} to change display order{% endblocktrans %} | {% trans 'Django site admin' %}{% endblock %}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
def get_is_sortable(objects):
|
||||
if objects.count() > 1:
|
||||
return True
|
||||
if objects:
|
||||
if objects.count() > 1:
|
||||
return True
|
||||
return False
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from adminsortable.admin import (SortableAdmin, SortableTabularInline,
|
|||
SortableStackedInline, SortableGenericStackedInline)
|
||||
from adminsortable.utils import get_is_sortable
|
||||
from app.models import (Category, Widget, Project, Credit, Note, GenericNote,
|
||||
Component)
|
||||
Component, Person)
|
||||
|
||||
|
||||
admin.site.register(Category, SortableAdmin)
|
||||
|
|
@ -58,3 +58,10 @@ class ProjectAdmin(SortableAdmin):
|
|||
list_display = ['__unicode__', 'category']
|
||||
|
||||
admin.site.register(Project, ProjectAdmin)
|
||||
|
||||
|
||||
class PersonAdmin(SortableAdmin):
|
||||
sortable_change_list_with_sort_link_template = 'app/person/admin/change_list_with_sort_link.html'
|
||||
|
||||
|
||||
admin.site.register(Person, PersonAdmin)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
[{
|
||||
"pk": 1,
|
||||
"model": "app.person",
|
||||
"fields": {
|
||||
"first_name": "Bob",
|
||||
"last_name": "Smith",
|
||||
"order": 1,
|
||||
"is_board_member": true
|
||||
}
|
||||
}, {
|
||||
"pk": 2,
|
||||
"model": "app.person",
|
||||
"fields": {
|
||||
"first_name": "Sally",
|
||||
"last_name": "Sue",
|
||||
"order": 2,
|
||||
"is_board_member": false
|
||||
}
|
||||
}, {
|
||||
"pk": 3,
|
||||
"model": "app.person",
|
||||
"fields": {
|
||||
"first_name": "Mike",
|
||||
"last_name": "Wilson",
|
||||
"order": 3,
|
||||
"is_board_member": true
|
||||
}
|
||||
}, {
|
||||
"pk": 4,
|
||||
"model": "app.person",
|
||||
"fields": {
|
||||
"first_name": "Robert",
|
||||
"last_name": "Roberts",
|
||||
"order": 2,
|
||||
"is_board_member": true
|
||||
}
|
||||
}]
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
# Adding model 'Person'
|
||||
db.create_table(u'app_person', (
|
||||
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('order', self.gf('django.db.models.fields.PositiveIntegerField')(default=1, db_index=True)),
|
||||
('first_name', self.gf('django.db.models.fields.CharField')(max_length=50)),
|
||||
('last_name', self.gf('django.db.models.fields.CharField')(max_length=50)),
|
||||
('is_board_member', self.gf('django.db.models.fields.BooleanField')(default=False)),
|
||||
))
|
||||
db.send_create_signal(u'app', ['Person'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Deleting model 'Person'
|
||||
db.delete_table(u'app_person')
|
||||
|
||||
|
||||
models = {
|
||||
u'app.category': {
|
||||
'Meta': {'ordering': "['order']", 'object_name': 'Category'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'order': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1', 'db_index': 'True'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
u'app.component': {
|
||||
'Meta': {'ordering': "['order']", 'object_name': 'Component'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'order': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1', 'db_index': 'True'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
|
||||
'widget': ('adminsortable.fields.SortableForeignKey', [], {'to': u"orm['app.Widget']"})
|
||||
},
|
||||
u'app.credit': {
|
||||
'Meta': {'ordering': "['order']", 'object_name': 'Credit'},
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30'}),
|
||||
'order': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1', 'db_index': 'True'}),
|
||||
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['app.Project']"})
|
||||
},
|
||||
u'app.genericnote': {
|
||||
'Meta': {'ordering': "['order']", 'object_name': 'GenericNote'},
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'generic_notes'", 'to': u"orm['contenttypes.ContentType']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
|
||||
'order': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1', 'db_index': 'True'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
u'app.note': {
|
||||
'Meta': {'ordering': "['order']", 'object_name': 'Note'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'order': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1', 'db_index': 'True'}),
|
||||
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['app.Project']"}),
|
||||
'text': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
},
|
||||
u'app.person': {
|
||||
'Meta': {'ordering': "['order']", 'object_name': 'Person'},
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'is_board_member': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
|
||||
'order': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1', 'db_index': 'True'})
|
||||
},
|
||||
u'app.project': {
|
||||
'Meta': {'ordering': "['order']", 'object_name': 'Project'},
|
||||
'category': ('adminsortable.fields.SortableForeignKey', [], {'to': u"orm['app.Category']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'order': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1', 'db_index': 'True'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
u'app.widget': {
|
||||
'Meta': {'ordering': "['order']", 'object_name': 'Widget'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'order': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1', 'db_index': 'True'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
u'contenttypes.contenttype': {
|
||||
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['app']
|
||||
|
|
@ -95,3 +95,17 @@ class Component(SimpleModel, Sortable):
|
|||
|
||||
def __unicode__(self):
|
||||
return self.title
|
||||
|
||||
|
||||
class Person(Sortable):
|
||||
class Meta(Sortable.Meta):
|
||||
verbose_name_plural = 'People'
|
||||
|
||||
first_name = models.CharField(max_length=50)
|
||||
last_name = models.CharField(max_length=50)
|
||||
is_board_member = models.BooleanField(default=False)
|
||||
|
||||
sorting_filters = {'is_board_member': True}
|
||||
|
||||
def __unicode__(self):
|
||||
return '{} {}'.format(self.first_name, self.last_name)
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1,2 +1,2 @@
|
|||
django==1.5.2
|
||||
django==1.6.1
|
||||
south==0.8.1
|
||||
|
|
|
|||
|
|
@ -109,10 +109,7 @@ ROOT_URLCONF = 'sample_project.urls'
|
|||
WSGI_APPLICATION = 'sample_project.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.
|
||||
map_path('templates'),
|
||||
)
|
||||
|
||||
INSTALLED_APPS = (
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
{% extends change_list_template_extends %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block object-tools-items %}
|
||||
<li>
|
||||
<a href="./sort/">{% trans 'Change Order of Board Members' %}</a>
|
||||
</li>
|
||||
{{ block.super }}
|
||||
{% endblock %}
|
||||
Loading…
Reference in New Issue