James Williams
cursor.execute("SELECT * FROM users WHERE age > 21")
User.objects.filter(age__gt=21)
# models.py
from django.db import models
from django.contrib.auth.models import User
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
published = models.BooleanField(default=False)
def __str__(self):
return self.title
class Meta:
ordering = ['-created_at']
# Character/Text fields
CharField(max_length=100)
TextField()
EmailField()
URLField()
# Numeric fields
IntegerField()
DecimalField(max_digits=10, decimal_places=2)
FloatField()
# Date/Time fields
DateField()
DateTimeField()
TimeField()
# Boolean
BooleanField(default=False)
# File fields
FileField(upload_to='files/')
ImageField(upload_to='images/')
| id | title | content | author_id | created_at | published |
|---|---|---|---|---|---|
| 1 | Django Tutorial | Learn Django ORM... | 1 | 2024-01-15 10:30 | ✓ |
| 2 | Python Basics | Introduction to Python... | 2 | 2024-01-16 14:20 | ✓ |
| 3 | Web Security | Best practices... | 1 | 2024-01-17 09:15 | ✗ |
Django automatically creates an 'id' primary key field
# Create migration files
python manage.py makemigrations
# Output:
# Migrations for 'blog':
# Â Â blog/migrations/0001_initial.py
# Â Â Â Â - Create model Post
# Apply migrations
python manage.py migrate
# View SQL
python manage.py sqlmigrate blog 0001
# Show migration status
python manage.py showmigrations
# Method 1: Create and save
post = Post()
post.title = "My First Post"
post.content = "Hello World!"
post.author = request.user
post.save()
# Method 2: Create in one line
post = Post.objects.create(
title="My First Post",
content="Hello World!",
author=request.user
)
# Method 3: get_or_create
post, created = Post.objects.get_or_create(
title="Unique Title",
defaults={'content': 'Content', 'author': user}
)
# Get all objects
posts = Post.objects.all()
# Get specific object
post = Post.objects.get(id=1)
post = Post.objects.get(title="Django Tutorial")
# Filter objects
published = Post.objects.filter(published=True)
recent = Post.objects.filter(created_at__gte='2024-01-01')
# Exclude
drafts = Post.objects.exclude(published=True)
# First/Last
first_post = Post.objects.first()
latest = Post.objects.last()
# Count
count = Post.objects.count()
# Chaining filters
posts = Post.objects.filter(
published=True
).filter(
created_at__year=2024
).order_by('-created_at')
# OR queries
from django.db.models import Q
posts = Post.objects.filter(
Q(title__icontains='django') | Q(content__icontains='django')
)
# Lookup types
Post.objects.filter(title__icontains='python') # Case-insensitive
Post.objects.filter(title__startswith='Django')
Post.objects.filter(created_at__year=2024)
Post.objects.filter(id__in=[1, 2, 3])
Post.objects.filter(title__isnull=False)
# Method 1: Get, modify, save
post = Post.objects.get(id=1)
post.title = "Updated Title"
post.published = True
post.save()
# Method 2: Update queryset (bulk update)
Post.objects.filter(author=user).update(published=True)
# Update specific fields only
post = Post.objects.get(id=1)
post.title = "New Title"
post.save(update_fields=['title']) # Only update title
# Delete single object
post = Post.objects.get(id=1)
post.delete()
# Delete multiple objects
Post.objects.filter(published=False).delete()
# Delete all (BE CAREFUL!)
Post.objects.all().delete()
Create a fully functional blog with CRUD operations
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE)
text = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
# Access
post.comment_set.all() # All comments for a post
comment.post # The post this comment belongs to
PK = Primary Key | FK = Foreign Key
class Tag(models.Model):
name = models.CharField(max_length=50)
class Post(models.Model):
title = models.CharField(max_length=200)
tags = models.ManyToManyField(Tag)
# Usage
post = Post.objects.get(id=1)
tag = Tag.objects.get(name='Django')
# Add tag to post
post.tags.add(tag)
# Get all tags for a post
post.tags.all()
# Get all posts with a tag
Tag.objects.get(name='Python').post_set.all()
# Remove tag
post.tags.remove(tag)
from django.contrib import admin
from .models import Post, Comment
@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
list_display = ('title', 'author', 'created_at', 'published')
list_filter = ('published', 'created_at')
search_fields = ('title', 'content')
date_hierarchy = 'created_at'
ordering = ('-created_at',)
admin.site.register(Comment)
python manage.py createsuperuser
# Visit: http://127.0.0.1:8000/admin/
Enhance blog with relationships and admin interface
# Without optimization (N+1 queries)
posts = Post.objects.all()
for post in posts:
print(post.author.username) # Database hit each time
# With select_related (1 query with JOIN)
posts = Post.objects.select_related('author').all()
for post in posts:
print(post.author.username) # No extra queries
# Optimize ManyToMany
posts = Post.objects.prefetch_related('tags').all()
for post in posts:
print(post.tags.all()) # Already loaded
Preparation: Install: pip install djangorestframework
Contact: JWilliams@Staff.newman.ac.uk
Office Hours: By appointment
Resources: Django ORM Docs, QuerySet API Reference
Thank you for your attention!