Laravel ORM vs Django ORM Cheatsheet

A quick reference for developers switching between Laravel Eloquent and Django ORM.


1. Models = Database Tables

  • Laravel → You define a model that extends Illuminate\Database\Eloquent\Model.

  • Django → You define a model that extends django.db.models.Model.

Example: User table

// Laravel class User extends Model { protected $table = 'users'; protected $fillable = ['name', 'email']; }
# Django from django.db import models class User(models.Model): name = models.CharField(max_length=255) email = models.EmailField()
  • Both create a users table by default (Django auto-pluralizes unless you override with db_table in Meta).

  • In Django, migrations are generated automatically from the model (python manage.py makemigrations).


2. Fetching Records

All records

// Laravel $users = User::all();
# Django users = User.objects.all()

Single record

// Laravel $user = User::find(1);
# Django user = User.objects.get(id=1)

First match

// Laravel $user = User::where('email', 'test@example.com')->first();
# Django user = User.objects.filter(email="test@example.com").first()

3. Inserting Records

// Laravel $user = new User(); $user->name = "Arif"; $user->email = "arif@example.com"; $user->save();
# Django user = User(name="Arif", email="arif@example.com") user.save()

Or mass assignment:

// Laravel User::create(['name' => 'Arif', 'email' => 'arif@example.com']);
# Django User.objects.create(name="Arif", email="arif@example.com")

4. Updating Records

// Laravel $user = User::find(1); $user->name = "Updated"; $user->save();
# Django user = User.objects.get(id=1) user.name = "Updated" user.save()

Bulk update:

// Laravel User::where('active', 0)->update(['active' => 1]);
# Django User.objects.filter(active=0).update(active=1)

5. Deleting Records

// Laravel $user = User::find(1); $user->delete();
# Django user = User.objects.get(id=1) user.delete()

Bulk delete:

// Laravel User::where('active', 0)->delete();
# Django User.objects.filter(active=0).delete()

6. Query Building

Django ORM is very close to Eloquent’s query builder:

Conditions

// Laravel $users = User::where('active', 1)->where('role', 'admin')->get();
# Django users = User.objects.filter(active=1, role="admin")

OR conditions

// Laravel $users = User::where('active', 1)->orWhere('role', 'admin')->get();
# Django from django.db.models import Q users = User.objects.filter(Q(active=1) | Q(role="admin"))

Order / Limit

// Laravel $users = User::orderBy('name', 'asc')->take(10)->get();
# Django users = User.objects.order_by("name")[:10]

7. Relationships

Very similar to Laravel, but defined differently.

One-to-Many (User → Post)

// Laravel class User extends Model { public function posts() { return $this->hasMany(Post::class); } }
# Django class Post(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="posts")

Usage:

$user->posts; // Laravel
user.posts.all() # Django

Many-to-Many (User ↔ Role)

// Laravel class User extends Model { public function roles() { return $this->belongsToMany(Role::class); } }
# Django class Role(models.Model): users = models.ManyToManyField(User, related_name="roles")

Usage:

$user->roles; // Laravel
user.roles.all() # Django

8. Raw SQL

// Laravel $users = DB::select("SELECT * FROM users WHERE active = ?", [1]);
# Django from django.db import connection with connection.cursor() as cursor: cursor.execute("SELECT * FROM users WHERE active = %s", [1]) users = cursor.fetchall()

Key Idea:
Think of User:: in Laravel as User.objects in Django.
Both ORMs are active record style (model = row + query builder).


Would you like me to make a cheat sheet table (Laravel ORM vs Django ORM) for quick reference (like a side-by-side comparison)?


Advanced Django ORM (Compared to Laravel ORM)


1. Aggregates & Group By

Laravel

use Illuminate\Support\Facades\DB; $counts = User::select('role', DB::raw('count(*) as total')) ->groupBy('role') ->get();

Django

from django.db.models import Count counts = User.objects.values("role").annotate(total=Count("id"))

👉 values("role") = select role.
👉 annotate(Count("id")) = count(*).


2. Select Specific Fields

Laravel

$users = User::select('id', 'name')->get();

Django

users = User.objects.only("id", "name")

Or return dict-like rows:

users = User.objects.values("id", "name")

3. Eager Loading (Avoid N+1 Problem)

Laravel

$users = User::with('posts')->get();

Django

users = User.objects.prefetch_related("posts") # for Many/One-to-Many users = User.objects.select_related("profile") # for ForeignKey/One-to-One
  • select_relatedjoins in one query.

  • prefetch_related2 queries, cached in memory.


4. Chunking / Batching

Laravel

User::chunk(100, function($users) { foreach ($users as $user) { // ... } });

Django

for user in User.objects.iterator(chunk_size=100): # ... pass

5. Transactions

Laravel

DB::transaction(function () { User::create([...]); Profile::create([...]); });

Django

from django.db import transaction with transaction.atomic(): User.objects.create(...) Profile.objects.create(...)

6. Subqueries

Laravel

$latestPost = Post::select('title') ->whereColumn('user_id', 'users.id') ->latest() ->limit(1); $users = User::addSelect(['latest_post' => $latestPost])->get();

Django

from django.db.models import Subquery, OuterRef latest_post = Post.objects.filter(user_id=OuterRef("id")).order_by("-id")[:1] users = User.objects.annotate(latest_post=Subquery(latest_post.values("title")))

7. Case / Conditional Queries

Laravel

$users = User::select('name', DB::raw("CASE WHEN active = 1 THEN 'Active' ELSE 'Inactive' END as status")) ->get();

Django

from django.db.models import Case, When, Value, CharField users = User.objects.annotate( status=Case( When(active=1, then=Value("Active")), default=Value("Inactive"), output_field=CharField() ) )

8. Custom Manager (Like Laravel Scopes)

Laravel

class User extends Model { public function scopeActive($query) { return $query->where('active', 1); } }

Usage:

$activeUsers = User::active()->get();

Django

class ActiveUserManager(models.Manager): def get_queryset(self): return super().get_queryset().filter(active=1) class User(models.Model): name = models.CharField(max_length=255) active = models.BooleanField(default=1) objects = models.Manager() # Default manager active_users = ActiveUserManager() # Custom manager

Usage:

active_users = User.active_users.all()

9. Raw Expressions

Laravel

$users = User::whereRaw('age > ? AND active = ?', [18, 1])->get();

Django

from django.db.models.expressions import RawSQL users = User.objects.annotate( custom=RawSQL("age > %s AND active = %s", (18, 1)) )

10. Pagination

Laravel

$users = User::paginate(10);

Django

from django.core.paginator import Paginator paginator = Paginator(User.objects.all(), 10) page = paginator.get_page(1) # 1st page

11. Signals (Like Model Events)

Laravel

class User extends Model { protected static function booted() { static::creating(function ($user) { // before create }); } }

Django

from django.db.models.signals import pre_save from django.dispatch import receiver @receiver(pre_save, sender=User) def before_create_user(sender, instance, **kwargs): # before saving pass

12. Query Debugging

Laravel

DB::listen(function($query) { dump($query->sql); });

Django

from django.db import connection print(connection.queries)

✅ So Django ORM is powerful like Eloquent but a bit more Pythonic.
✅ Think of .objects as :: in Laravel.
filter() = where(), annotate() = select with aggregate, select_related() = with().

Comments