Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternative code position for Django admin list display settings

Tags:

python

django

I am following the tutorial of Django 1.6, which includes a model Poll that has a derived attribute was_published_recently (a method of class Poll). The model was originally defined as follows.

# polls/models.py (excerpted)

class Poll(models.Model):
    # ...
    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)

And the admin interface for this app:

# polls/admin.py (excerpted)

class PollAdmin(admin.ModelAdmin):
    # ...
    list_display = ('question', 'pub_date', 'was_published_recently')

admin.site.register(Poll, PollAdmin)

Now we want to improve the display and sorting functionality of was_published_recently.

In the tutorial, file polls/models.py is updated:

class Poll(models.Model):
    # ...
    was_published_recently.admin_order_field = 'pub_date'
    was_published_recently.boolean = True
    was_published_recently.short_description = 'Published recently?'

However, I think this may not be good enough in practice, because what we are specifying is completely about the admin user interface, not the model per se. So I instead updated polls/admin.py:

class PollAdmin(admin.ModelAdmin):
    Poll.was_published_recently.admin_order_field = 'pub_date'
    Poll.was_published_recently.boolean = True
    Poll.was_published_recently.short_description = 'Published recently?'
    # ...

After this modification, the app works as expected as well (multiple polls work well also). Since I am new to Python, I investigated a bit further by printing was_published_recently in both Poll and PollAdmin:

class Poll(models.Model):
    # ...
    print("in class Poll", was_published_recently)

class PollAdmin(admin.ModelAdmin):
    print("in class PollAdmin", Poll.was_published_recently)
    # ...

And the output is

in class Poll <function Poll.was_published_recently at 0x10fc92050>
in class PollAdmin <function Poll.was_published_recently at 0x10fc92050>

So apparently was_published_recently in class Poll is the same as Poll.published_recently accessed in class PollAdmin.

My question: Should I specify the admin_order_field stuffs in admin.py or models.py? If specified in admin.py instead of models.py, are there any drawbacks?

like image 877
Xiao Jia Avatar asked May 12 '26 15:05

Xiao Jia


1 Answers

Briefly, everything is working as intended, and it's semantically the same to put admin_order_field stuffs either in models.py or admin.py.

So apparently was_published_recently in class Poll is the same as Poll.published_recently accessed in class PollAdmin.

Yes. They should be the same. Classes are objects. So Poll is an object. Poll.was_published_recently is an attribute of object Poll, and is also an object with type instancemethod. Wherever you access it, it is the same object.

AFAIK, the only difference between writing admin_order_field stuffs in models.py and admin.py is the order of interpretation. Django loads models.py before admin.py, so everything runs at loading time and relies on admin_order_field stuffs will fail. But since admin_order_field is only used in admin.py, I think what you are doing is fine.

Python is so dynamic that allows you to modify definitions from even other modules. This can lead to hard-to-find bugs and bad readability / maintainability. Be sure to use this black magic with caution.

like image 130
Xiangru Chen Avatar answered May 14 '26 04:05

Xiangru Chen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!