Search code examples
djangodjango-modelsdjango-admindjango-modeladmin

How to display a value where there is none in Django admin?


Is there a Djangotastic way to display a default value for a field in the admin when there isn't a value? Like 'n/a', but not to save that to the database?

When I set all the fields in the model below to readonly in the admin, the front-end display looks like the image at the bottom. It feels visually collapsed like it should have a value or a box or something. If there isn't an easy way to do what I am looking for, then is there another solution to make the front-end admin more clear for the user?

class Package(models.Model):
    packaging_format = models.CharField(max_length=40)
    package_delivery_pattern = models.CharField(max_length=30, blank=True)
    package_delivery_comments = models.CharField(max_length=250, blank=True)
    package_manifest_filename = models.CharField(max_length=50)
    package_description = models.CharField(max_length=250, blank=True)
    package_naming_pattern = models.CharField(max_length=50)

Screenshot of fields as displayed in the admin: Screenshot of admin with readonly package fields


Solution

  • What's happening is that your actually saving a empty string '' in your CharFields instead of None values (because of the blank=True). So the Django-admin is showing the string you saved in the db (in this case, nothing).

    If you change your CharFields to null=True instead of blank=True, you will be saving NULL in your database instead of an empty string. And that way, you will get the behaviour you want.

    EDIT: I know this solution is not recommended (following Django Docs), but that's the behaviour you wanted. Django-admin is just showing you the string you have in the database, which is ''.

    Another solution that comes to my mind is to modify the ModelAdmin for your Package model, something like:

    class PackageAdmin(admin.ModelAdmin):
        readonly_fields = ['show_package_delivery_pattern', ...]
    
        def show_package_delivery_pattern(self, obj):
            if obj.package_delivery_pattern:
                return obj.package_delivery_pattern
            else:
                return 'N/A'
        # same with all your CharFields..