3

I have a series of tables which I want to all have an order field. So I made an abstract model:

class OrderedModel(models.Model):
    order = models.IntegerField(default=-1)
    def _order(self):
        pass #ordering widget for changelist_view
    _order.allow_tags = True
    def save(self,*args,**kwargs):
        #set order = 0 if < 0
        super(OrderedModel,self).save(*args,**kwargs)
    class Meta:
        abstract = True

I don't want them to change the "order" field in the change_view, so I make the following ModelAdmin:

class OrderedAdmin(models.ModelAdmin):
    list_display = ("__str__","_order","order")
    list_editable = ("order",)
    readonly_fields = ("order",)

That's fine so long as every model that inherits from OrderedModel doesn't need any more items in list_display, list_editable or readonly_fields. For example, the following would generate an error because order is in list_editable but not list_display:

class Chapter(OrderedModel):
    title = models.CharField(max_length=32)

class ChapterAdmin(OrderedAdmin):
    list_display = ("title",)

I noticed that there is a get_readonly_fields that I can change to ensure that "order" gets added to readonly_fields, but there's no get_list_display or get_list_editable to over write. Is it possible to do this?

chriscauley
  • 19,015
  • 9
  • 33
  • 33
  • Of course. If in your `ChapterAdmin` you set `list_display = ("title",)` how would you expect it to be anything else ? If you want `order` and `title` you need a statement that tells `list_display = ("order", "title")`. @SimonKagwi gives you a convenient and DRY way. – Stan Dec 26 '11 at 23:19

1 Answers1

9
class ChapterAdmin(OrderedAdmin):
    list_display = OrderedAdmin.list_display + ("title",)
Simon Kagwi
  • 1,636
  • 2
  • 19
  • 25
  • Please provide more information, since not everyone might understand why this is the answer. Thanks. – markusschmitz Dec 26 '11 at 22:45
  • 1
    @Fuzzy, `tuples` are immutables but you can [concatenate them with the '+' operator](http://docs.python.org/reference/expressions.html#binary-arithmetic-operations). So here you concatenate `OrderedAdmin.list_display` - `("order",)` - with `("title",)`. The result of this operation is a new tuple `("order", "title")`. – Stan Dec 26 '11 at 23:30
  • 1
    In addition, it would not be possible to do `list_display += ("title",)` due to how Python class variables work. See http://stackoverflow.com/questions/3648564/python-subclass-access-to-class-variable-of-parent – Simon Kagwi Dec 27 '11 at 07:35