Comprehensive Django ORM Guide: Model Definition, Custom Table Names, Indexes, Relationships, Query Optimization, and Validation
This article provides an in‑depth tutorial on using Django's ORM, covering model creation, custom table names, single and composite indexes, one‑to‑many and many‑to‑many relationships, forward and reverse lookups, performance tuning with select_related and prefetch_related, and model validation techniques.
The article introduces Django's ORM capabilities, explaining that a model can create database tables, operate on them, and perform data validation.
Custom Table Name
By default Django generates a table name as app_label_classname (e.g., app01_user ). To override this, define db_table inside the inner Meta class:
class User(models.Model):
user = models.CharField(max_length=32)
pwd = models.CharField(max_length=64)
class Meta:
db_table = "user"Indexes
Single‑column indexes can be added with db_index=True on a field. Composite (joint) indexes are defined via index_together in Meta :
class User(models.Model):
user = models.CharField(max_length=32)
pwd = models.CharField(max_length=64)
class Meta:
db_table = "user"
index_together = [("user", "pwd")]Only queries that include the leftmost column of a composite index can use the index (e.g., WHERE user='zhangsan' or WHERE user='zhangsan' AND pwd='111' ).
Unique Composite Index
Use unique_together = (("name", "pwd"),) to enforce uniqueness of a column pair.
One‑to‑Many Relationship
class UserType(models.Model):
name = models.CharField(max_length=32)
class User(models.Model):
user = models.CharField(max_length=32, db_index=True)
pwd = models.CharField(max_length=64, db_index=True)
ut = models.ForeignKey(
to="UserType",
to_field="id",
on_delete=models.CASCADE,
related_name="cc",
limit_choices_to={"id__gt": 2},
)When a UserType instance is deleted, Django 1.10+ cascades the delete to related User rows if on_delete=models.CASCADE is set.
ForeignKey Parameters
to : target model name.
to_field : target field name.
on_delete : behavior when the referenced row is removed ( CASCADE , DO_NOTHING , PROTECT , SET_NULL , SET_DEFAULT , SET(value) ).
related_name : custom name for reverse relation (e.g., cc ).
related_query_name : name used in reverse lookups (e.g., aa_set if set to aa ).
limit_choices_to : filter options shown in Django admin or ModelForm.
Forward and Reverse Lookups
Forward lookup example:
v1 = models.User.objects.all().values("user", "ut__name")Reverse lookup example:
v3 = models.UserType.objects.all().values("name", "user__user")Both can also be performed with explicit loops.
Many‑to‑Many Relationships
Three ways to create many‑to‑many relations:
Let Django create an implicit through table using ManyToManyField :
Manually create an explicit through table:
Manually create a through table and attach it via through and through_fields for finer control (recommended).
ORM Basic CRUD Operations
Examples of creating, reading, updating, and deleting records:
models.Tb1.objects.create(c1='xx', c2='oo')
obj = models.Tb1(c1='xx', c2='oo')
obj.save()
models.Tb1.objects.get(id=123)
models.Tb1.objects.filter(name='seven')
models.Tb1.objects.exclude(name='seven')
models.Tb1.objects.filter(name='seven').update(gender='0')
models.Tb1.objects.filter(name='seven').delete()Additional QuerySet methods covered include count , range filters ( id__gt , id__lt ), in , isnull , contains , ordering, grouping with annotate , pagination ( [10:20] ), and raw SQL execution via raw() .
Performance Optimization
Using select_related('ut') performs a SQL join and fetches related UserType data in a single query, while prefetch_related('ut') runs two separate queries and caches the related objects, reducing the number of database hits in loops.
Model Validation
Calling full_clean() on a model instance triggers field‑level validation and the clean() hook. An example custom validation ensures the name field is unique:
def clean(self):
if UserInfo.objects.filter(name=self.name).count():
raise ValidationError("用户名已经存在", code="cc1")The validation order is: field regex validation → clean() hook.
Overall, the article serves as a practical reference for Django developers needing detailed guidance on model design, indexing strategies, relationship handling, query optimization, and data validation.
Test Development Learning Exchange
Test Development Learning Exchange
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.