Thao tác này tương tự như cấu trúc if-elif-else trong cơ sở dữ liệu.
1. Chuẩn bị dữ liệu
class User(models.Model):
BASIC = 'B'
PREMIUM = 'P'
ELITE = 'E'
ACCOUNT_TYPE_CHOICES = [
(BASIC, 'Basic'),
(PREMIUM, 'Premium'),
(ELITE, 'Elite'),
]
username = models.CharField(max_length=50)
registration_date = models.DateField()
membership_type = models.CharField(
max_length=1,
choices=ACCOUNT_TYPE_CHOICES,
default=BASIC,
)
Mã tạo dữ liệu mẫu:
from myapp.models import User
User.objects.create(username="user_1", registration_date="2020-01-01", membership_type="B")
User.objects.create(username="user_2", registration_date="2021-07-12", membership_type="P")
User.objects.create(username="user_3", registration_date="2022-09-20", membership_type="E")
User.objects.create(username="user_4", registration_date="2022-12-07", membership_type="E")
2. Thêm trường mới với When và Case
from django.db.models import Case, Value, When
results = User.objects.annotate(
season_name=Case(
When(registration_date__month__in=[1, 2, 3], then=Value("Mùa xuân")),
When(registration_date__month__in=[4, 5, 6], then=Value("Mùa hè")),
When(registration_date__month__in=[7, 8, 9], then=Value("Mùa thu")),
When(registration_date__month__in=[10, 11, 12], then=Value("Mùa đông")),
default=Value("Mùa xuân")
)
)
Lấy giá trị từ trường khác:
When(registration_date__month__in=[1, 2, 3], then="username")
Sử dụng F() để truy cập trường:
from django.db.models import F
When(registration_date__month__in=[1, 2, 3], then=F("username"))
3. Lọc dữ liệu theo điều kiện
filtered_users = User.objects.annotate(
season_name=Case(
When(registration_date__month__in=[1, 2, 3], then=Value("Mùa xuân")),
When(registration_date__month__in=[4, 5, 6], then=Value("Mùa hè")),
When(registration_date__month__in=[7, 8, 9], then=Value("Mùa thu")),
When(registration_date__month__in=[10, 11, 12], then=Value("Mùa đông")),
default=Value("Mùa xuân")
)
).filter(season_name="Mùa xuân")
Dùng Case trong filter:
from datetime import date, timedelta
current_date = date.today()
month_ago = current_date - timedelta(days=30)
year_ago = current_date - timedelta(days=365)
User.objects.filter(
registration_date__lte=Case(
When(membership_type=User.PREMIUM, then=month_ago),
When(membership_type=User.ELITE, then=year_ago)
)
)
4. Cập nhật dữ liệu theo điều kiện
User.objects.update(
membership_type=Case(
When(registration_date__year=2020, then=Value(User.ELITE)),
When(registration_date__year=2021, then=Value(User.BASIC)),
default=Value(User.PREMIUM)
)
)
Áp dụng cho năm cụ thể:
User.objects.filter(registration_date__year__in=[2020, 2021]).update(
membership_type=Case(
When(registration_date__year=2020, then=Value(User.ELITE)),
When(registration_date__year=2021, then=Value(User.BASIC)),
default=Value(User.PREMIUM)
)
)