mirror of
https://github.com/jazzband/django-admin-sortable.git
synced 2026-03-17 06:20:33 +00:00
Updated database samples. Added migrations for sample project models. Updated Category model to make order not editable.
251 lines
7.3 KiB
Python
251 lines
7.3 KiB
Python
from django.contrib.contenttypes.fields import GenericForeignKey
|
|
from django.contrib.contenttypes.models import ContentType
|
|
from django.db import models
|
|
from django.utils.encoding import python_2_unicode_compatible
|
|
|
|
from adminsortable.fields import SortableForeignKey
|
|
from adminsortable.models import Sortable, SortableMixin
|
|
|
|
|
|
@python_2_unicode_compatible
|
|
class SimpleModel(models.Model):
|
|
class Meta:
|
|
abstract = True
|
|
|
|
title = models.CharField(max_length=50)
|
|
|
|
def __str__(self):
|
|
return self.title
|
|
|
|
|
|
# A model that is sortable
|
|
class Category(SimpleModel, SortableMixin):
|
|
class Meta:
|
|
verbose_name_plural = 'Categories'
|
|
ordering = ['order']
|
|
|
|
order = models.PositiveIntegerField(default=0, editable=False)
|
|
|
|
|
|
# A model with an override of its queryset for admin
|
|
@python_2_unicode_compatible
|
|
class Widget(SimpleModel, SortableMixin):
|
|
class Meta:
|
|
ordering = ['order']
|
|
|
|
def __str__(self):
|
|
return self.title
|
|
|
|
order = models.PositiveIntegerField(default=0, editable=False)
|
|
|
|
|
|
# A model that is sortable relative to a foreign key that is also sortable
|
|
# uses SortableForeignKey field. Works with versions 1.3+
|
|
class Project(SimpleModel, SortableMixin):
|
|
class Meta:
|
|
ordering = ['order']
|
|
|
|
category = SortableForeignKey(Category, on_delete=models.CASCADE)
|
|
description = models.TextField()
|
|
|
|
order = models.PositiveIntegerField(default=0, editable=False)
|
|
|
|
|
|
# Registered as a tabular inline on `Project`
|
|
@python_2_unicode_compatible
|
|
class Credit(SortableMixin):
|
|
class Meta:
|
|
ordering = ['order']
|
|
|
|
project = models.ForeignKey(Project, on_delete=models.CASCADE)
|
|
first_name = models.CharField(max_length=30, help_text="Given name")
|
|
last_name = models.CharField(max_length=30, help_text="Family name")
|
|
|
|
order = models.PositiveIntegerField(default=0, editable=False)
|
|
|
|
def __str__(self):
|
|
return '{0} {1}'.format(self.first_name, self.last_name)
|
|
|
|
|
|
# Registered as a stacked inline on `Project`
|
|
@python_2_unicode_compatible
|
|
class Note(SortableMixin):
|
|
class Meta:
|
|
ordering = ['order']
|
|
|
|
project = models.ForeignKey(Project, on_delete=models.CASCADE)
|
|
text = models.CharField(max_length=100)
|
|
|
|
order = models.PositiveIntegerField(default=0, editable=False)
|
|
|
|
def __str__(self):
|
|
return self.text
|
|
|
|
|
|
# Registered as a tabular inline on `Project` which can't be sorted
|
|
@python_2_unicode_compatible
|
|
class NonSortableCredit(models.Model):
|
|
project = models.ForeignKey(Project, on_delete=models.CASCADE)
|
|
first_name = models.CharField(max_length=30, help_text="Given name")
|
|
last_name = models.CharField(max_length=30, help_text="Family name")
|
|
|
|
def __str__(self):
|
|
return '{0} {1}'.format(self.first_name, self.last_name)
|
|
|
|
|
|
# Registered as a stacked inline on `Project` which can't be sorted
|
|
@python_2_unicode_compatible
|
|
class NonSortableNote(models.Model):
|
|
project = models.ForeignKey(Project, on_delete=models.CASCADE)
|
|
text = models.CharField(max_length=100)
|
|
|
|
def __str__(self):
|
|
return self.text
|
|
|
|
|
|
# A generic bound model
|
|
@python_2_unicode_compatible
|
|
class GenericNote(SimpleModel, SortableMixin):
|
|
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE,
|
|
verbose_name=u"Content type", related_name="generic_notes")
|
|
object_id = models.PositiveIntegerField(u"Content id")
|
|
content_object = GenericForeignKey(ct_field='content_type',
|
|
fk_field='object_id')
|
|
|
|
order = models.PositiveIntegerField(default=0, editable=False)
|
|
|
|
class Meta:
|
|
ordering = ['order']
|
|
|
|
def __str__(self):
|
|
return u'{0}: {1}'.format(self.title, self.content_object)
|
|
|
|
|
|
# An model registered as an inline that has a custom queryset
|
|
@python_2_unicode_compatible
|
|
class Component(SimpleModel, SortableMixin):
|
|
class Meta:
|
|
ordering = ['order']
|
|
|
|
widget = SortableForeignKey(Widget, on_delete=models.CASCADE)
|
|
|
|
order = models.PositiveIntegerField(default=0, editable=False)
|
|
|
|
def __str__(self):
|
|
return self.title
|
|
|
|
|
|
@python_2_unicode_compatible
|
|
class Person(SortableMixin):
|
|
class Meta:
|
|
ordering = ['order']
|
|
verbose_name_plural = 'People'
|
|
|
|
first_name = models.CharField(max_length=50)
|
|
last_name = models.CharField(max_length=50)
|
|
is_board_member = models.BooleanField('Board Member', default=False)
|
|
|
|
order = models.PositiveIntegerField(default=0, editable=False)
|
|
|
|
# Sorting Filters allow you to set up sub-sets of objects that need
|
|
# to have independent sorting. They are listed in order, from left
|
|
# to right in the sorting change list. You can use any standard
|
|
# Django ORM filter method.
|
|
sorting_filters = (
|
|
('Board Members', {'is_board_member': True}),
|
|
('Non-Board Members', {'is_board_member': False}),
|
|
)
|
|
|
|
def __str__(self):
|
|
return '{0} {1}'.format(self.first_name, self.last_name)
|
|
|
|
|
|
@python_2_unicode_compatible
|
|
class NonSortableCategory(SimpleModel):
|
|
class Meta(SimpleModel.Meta):
|
|
verbose_name = 'Non-Sortable Category'
|
|
verbose_name_plural = 'Non-Sortable Categories'
|
|
|
|
def __str__(self):
|
|
return self.title
|
|
|
|
|
|
@python_2_unicode_compatible
|
|
class SortableCategoryWidget(SimpleModel, SortableMixin):
|
|
class Meta:
|
|
ordering = ['order']
|
|
verbose_name = 'Sortable Category Widget'
|
|
verbose_name_plural = 'Sortable Category Widgets'
|
|
|
|
non_sortable_category = SortableForeignKey(
|
|
NonSortableCategory, on_delete=models.CASCADE)
|
|
|
|
order = models.PositiveIntegerField(default=0, editable=False)
|
|
|
|
def __str__(self):
|
|
return self.title
|
|
|
|
|
|
@python_2_unicode_compatible
|
|
class SortableNonInlineCategory(SimpleModel, SortableMixin):
|
|
"""Example of a model that is sortable, but has a SortableForeignKey
|
|
that is *not* sortable, and is also not defined as an inline of the
|
|
SortableForeignKey field."""
|
|
|
|
non_sortable_category = SortableForeignKey(
|
|
NonSortableCategory, on_delete=models.CASCADE)
|
|
|
|
order = models.PositiveIntegerField(default=0, editable=False)
|
|
|
|
class Meta:
|
|
ordering = ['order']
|
|
verbose_name = 'Sortable Non-Inline Category'
|
|
verbose_name_plural = 'Sortable Non-Inline Categories'
|
|
|
|
def __str__(self):
|
|
return self.title
|
|
|
|
|
|
@python_2_unicode_compatible
|
|
class CustomWidget(SortableMixin, SimpleModel):
|
|
|
|
# custom field for ordering
|
|
custom_order_field = models.PositiveIntegerField(default=0, db_index=True,
|
|
editable=False)
|
|
|
|
class Meta:
|
|
ordering = ['custom_order_field']
|
|
verbose_name = 'Custom Widget'
|
|
verbose_name_plural = 'Custom Widgets'
|
|
|
|
def __str__(self):
|
|
return self.title
|
|
|
|
|
|
@python_2_unicode_compatible
|
|
class CustomWidgetComponent(SortableMixin, SimpleModel):
|
|
|
|
custom_widget = models.ForeignKey(CustomWidget, on_delete=models.CASCADE)
|
|
|
|
# custom field for ordering
|
|
widget_order = models.PositiveIntegerField(default=0, db_index=True,
|
|
editable=False)
|
|
|
|
class Meta:
|
|
ordering = ['widget_order']
|
|
verbose_name = 'Custom Widget Component'
|
|
verbose_name_plural = 'Custom Widget Components'
|
|
|
|
def __str__(self):
|
|
return self.title
|
|
|
|
|
|
@python_2_unicode_compatible
|
|
class BackwardCompatibleWidget(Sortable, SimpleModel):
|
|
|
|
class Meta(Sortable.Meta):
|
|
verbose_name = 'Backward Compatible Widget'
|
|
verbose_name_plural = 'Backward Compatible Widgets'
|
|
|
|
def __str__(self):
|
|
return self.title
|