When working with Django Admin, you’ll often need to customize how fields appear in your forms. Django provides hooks such as formfield_for_foreignkey, formfield_for_choice_field, and formfield_for_dbfield — all of which receive an argument called db_field.
If you’ve ever wondered what exactly db_field is and how you can use it, this article is for you.
For complete article please visit db_field in Django Admin
What is db_field?
In short, db_field is the model field object being processed when Django builds the admin form.
When you define a model:
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
Django Admin inspects each field (title, author, etc.) when rendering the form. At that point, it passes the actual field instance (a CharField or ForeignKey) to your override methods as db_field.
So:
- For
Book.title→db_fieldwill be aCharFieldinstance. - For
Book.author→db_fieldwill be aForeignKeyinstance.
Where is db_field Used?
The db_field argument appears in several admin customization methods:
formfield_for_foreignkey(self, db_field, request, **kwargs)
→ Lets you change howForeignKeyfields are displayed.formfield_for_choice_field(self, db_field, request, **kwargs)
→ Lets you modify dropdowns created fromchoices.formfield_for_dbfield(self, db_field, request, **kwargs)
→ A generic hook for any field type.
Example 1 — Filtering a ForeignKey
Imagine you want to limit which authors appear in the dropdown when creating a book.
from django.contrib import admin
class BookAdmin(admin.ModelAdmin):
def formfield_for_foreignkey(self, db_field, request, **kwargs):
# Only customize the "author" field
if db_field.name == "author":
kwargs["queryset"] = Author.objects.filter(name__startswith="A")
return super().formfield_for_foreignkey(db_field, request, **kwargs)
🔎 What’s happening?
- Django passes the
Book.authorfield asdb_field. - We check
db_field.name == "author". - Then we override its queryset to only show authors whose names start with “A”.
Example 2 — Customizing Choices
Suppose you have a field with predefined choices:
class Book(models.Model):
GENRE_CHOICES = [
("fiction", "Fiction"),
("nonfiction", "Non-Fiction"),
("poetry", "Poetry"),
]
title = models.CharField(max_length=200)
genre = models.CharField(max_length=20, choices=GENRE_CHOICES)
You can alter how these choices appear in admin:
class BookAdmin(admin.ModelAdmin):
def formfield_for_choice_field(self, db_field, request, **kwargs):
if db_field.name == "genre":
# Reorder or filter choices
kwargs["choices"] = [
("fiction", "Fiction"),
("poetry", "Poetry"),
]
return super().formfield_for_choice_field(db_field, request, **kwargs)
Example 3 — Catch-All with formfield_for_dbfield
If you want to apply a rule to all fields, use formfield_for_dbfield:
class BookAdmin(admin.ModelAdmin):
def formfield_for_dbfield(self, db_field, request, **kwargs):
# Example: add placeholder text to all CharFields
if isinstance(db_field, models.CharField):
kwargs["widget"].attrs["placeholder"] = f"Enter {db_field.verbose_name}"
return super().formfield_for_dbfield(db_field, request, **kwargs)
Here, every CharField in the model gets a placeholder in its admin input box.
Why is db_field Useful?
- 🎯 Granular Control — target individual fields like
authororgenre. - 👥 User-Specific Filtering — restrict dropdowns per user role.
- 🛠 Custom Widgets — attach custom widgets or attributes.
- 🧹 Centralized Logic — all customization stays inside
ModelAdmin.
Key Takeaways
-
db_fieldis the actual field object from your model. - Django sends it to hooks so you can inspect the field and modify its admin form behavior.
-
Use:
-
formfield_for_foreignkey→ controlForeignKeydropdowns. -
formfield_for_choice_field→ controlchoices. -
formfield_for_dbfield→ catch-all for any field type.
-
✅ By leveraging db_field, you can transform the Django Admin from a basic CRUD tool into a finely tuned interface that enforces business rules and improves usability.

