Django Admin – Update Objects

Last updated 3 weeks, 3 days ago | 89 views 75     5

Tags:- Python Django

One of the most powerful features of Django's admin interface is its ability to update model objects directly through a secure and user-friendly dashboard. With just a few lines of code, you can customize how objects are updated, validate changes, make fields read-only, or even trigger automated actions.

This article covers:

  • How to update objects in Django Admin

  • Customizing object update forms

  • Using readonly_fields, save_model(), and prepopulated_fields

  • Bulk updates with actions

  • Tips and common pitfalls


Updating Objects in Django Admin

By default, once a model is registered in the admin, you can click on any instance to update it. Django automatically generates a form from your model fields.

Basic Example

# blog/models.py
from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    published = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
# blog/admin.py
from django.contrib import admin
from .models import Post

admin.site.register(Post)

After registering the model, go to /admin/, click on a Post object, and edit it.


Customizing Object Update Forms

Use fields to Control Editable Fields

class PostAdmin(admin.ModelAdmin):
    fields = ('title', 'content', 'published')

This shows only the listed fields on the edit form.


Use readonly_fields for Non-editable Display

class PostAdmin(admin.ModelAdmin):
    readonly_fields = ('created_at', 'updated_at')

This displays those fields but makes them read-only.


Use fieldsets for Structured Layout

class PostAdmin(admin.ModelAdmin):
    fieldsets = (
        ('Post Content', {'fields': ('title', 'content')}),
        ('Status', {'fields': ('published',)}),
        ('Timestamps', {'fields': ('created_at', 'updated_at')}),
    )
    readonly_fields = ('created_at', 'updated_at')

Validating & Saving Data: save_model()

You can override the save_model method in your custom admin class to handle special logic during updates.

class PostAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        if change:
            print(f"Post '{obj.title}' is being updated.")
        else:
            print(f"New post '{obj.title}' is being created.")
        super().save_model(request, obj, form, change)

✅ Add Prepopulated Fields

Useful when you want fields like slug to auto-fill based on the title:

class PostAdmin(admin.ModelAdmin):
    prepopulated_fields = {'slug': ('title',)}

Bulk Update Objects Using Admin Actions

You can define custom actions to update multiple objects at once.

class PostAdmin(admin.ModelAdmin):
    list_display = ('title', 'published')
    actions = ['publish_selected']

    def publish_selected(self, request, queryset):
        updated = queryset.update(published=True)
        self.message_user(request, f"{updated} post(s) marked as published.")
    publish_selected.short_description = "Mark selected posts as published"

✅ Now, select multiple posts from the list view and apply the "Mark selected posts as published" action.


Complete Example

models.py

from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=200)
    slug = models.SlugField(unique=True)
    content = models.TextField()
    published = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

admin.py

from django.contrib import admin
from .models import Post

class PostAdmin(admin.ModelAdmin):
    list_display = ('title', 'published', 'updated_at')
    fields = ('title', 'slug', 'content', 'published', 'created_at', 'updated_at')
    readonly_fields = ('created_at', 'updated_at')
    prepopulated_fields = {'slug': ('title',)}

    actions = ['publish_selected']

    def publish_selected(self, request, queryset):
        count = queryset.update(published=True)
        self.message_user(request, f"{count} post(s) published.")
    publish_selected.short_description = "Publish selected posts"

    def save_model(self, request, obj, form, change):
        if change:
            print(f"Post updated: {obj}")
        else:
            print(f"New post created: {obj}")
        super().save_model(request, obj, form, change)

admin.site.register(Post, PostAdmin)

Tips

  • Use formfield_overrides to apply widgets (e.g., Markdown editor or rich text).

  • Combine readonly_fields with fields to prevent edits on system-generated fields.

  • Use the save_model() hook to automatically log, audit, or transform data.

  • Define custom form classes if you need validation or widget customization.


⚠️ Common Pitfalls

Pitfall Solution
Can't edit a field Check if it's in readonly_fields or missing from fields.
Object not updating Confirm that save_model() is calling super() properly.
Read-only fields not updating in database They must be auto-updated in the model (auto_now, etc.).
Bulk actions don't run custom logic Use queryset.update() wisely; it bypasses model save().

Conclusion

The Django Admin interface makes object updates extremely simple while still offering powerful customization. From manually editing individual objects to applying bulk updates and validations, the admin is a must-know tool for any Django developer.

By mastering field customization, save_model, and admin actions, you can create an admin interface that’s efficient, user-friendly, and aligned with your project needs.