1.ForeignKey, OneToOneField, and ManyToManyField
ForeignKey is many-to-one (many Orders, one Customer). OneToOneField enforces uniqueness on top of the same idea — exactly one match each way (one User, one Profile). ManyToManyField lets both sides have many matches (many Students, many Courses). related_name renames the reverse accessor (customer.order_set becomes customer.orders); related_query_name renames the reverse lookup keyword used in filter().
Key features
- ForeignKey(Model, on_delete=...) is required to declare on_delete explicitly — it has no default value
- OneToOneField is functionally a ForeignKey plus unique=True — the same on_delete rules apply to it
- ManyToManyField needs on_delete=... on NEITHER side — deleting a row just removes its rows from the join table
- related_name="orders" changes customer.order_set (the default) to customer.orders
- related_query_name changes the keyword used in filter() lookups (Customer.objects.filter(order__status=...) vs a renamed keyword) independently of related_name
The three relationship fields
- ForeignKey: plain column, unconstrained — many-to-one, a column on the "many" side
- OneToOneField: plain column, unique — ForeignKey + unique=True
- ManyToManyField: separate join table, between unconstrained and unique — a real join table, two foreign keys
Command
customer = models.ForeignKey(
"Customer", on_delete=models.PROTECT, related_name="orders", related_query_name="order",
)ForeignKey (many-to-one), OneToOneField (ForeignKey + unique=True), ManyToManyField (a separate join table, no on_delete needed) — related_name renames the reverse accessor, related_query_name renames the filter() keyword, independently.