我在 Django (5.0.4) 上有一个模型,具有可选择的月份和年份,如下所示:
class Item(models.Model):
MONTHS_CHOICES = [
('JANUARY', 'January'),
('FEBRUARY', 'February'),
('MARCH', 'March'),
('APRIL', 'April'),
('MAY', 'May'),
('JUNE', 'June'),
('JULY', 'July'),
('AUGUST', 'August'),
('SEPTEMBER', 'September'),
('OCTOBER', 'October'),
('NOVEMBER', 'November'),
('DECEMBER', 'December')
]
month = models.CharField(max_length=9, choices=MONTHS_CHOICES, default="JANUARY", db_index=True)
year = models.IntegerField(default=0)
(...)
如果我尝试按月和年订购商品
Item.objects.all().order_by("-year", "month")
。
从逻辑上讲,月份将按字母顺序排列。
我该怎么做才能获得与我在
MONTHS_CHOICES
月份相同的订单订购的商品?
选项B只是重做模型以包含仅包含年份和月份的
DateField
,就像这里的问题并按该字段排序
我也尝试了此页面上的解决方案,但没有任何效果。
我自己还没有机会对此进行测试,但我的猜测是使用月份名称作为字典中的“键”,其中相应的“值”是适当的月份序数值(即 Jan -> 1、2 月 -> 2 等)
这是我的想法:
class Item(models.Model):
MONTHS_CHOICES = [
('JANUARY', 'January'),
('FEBRUARY', 'February'),
('MARCH', 'March'),
('APRIL', 'April'),
('MAY', 'May'),
('JUNE', 'June'),
('JULY', 'July'),
('AUGUST', 'August'),
('SEPTEMBER', 'September'),
('OCTOBER', 'October'),
('NOVEMBER', 'November'),
('DECEMBER', 'December')
]
MONTHS_ORDER = {
'JANUARY': 1,
'FEBRUARY': 2,
'MARCH': 3,
'APRIL': 4,
'MAY': 5,
'JUNE': 6,
'JULY': 7,
'AUGUST': 8,
'SEPTEMBER': 9,
'OCTOBER': 10,
'NOVEMBER': 11,
'DECEMBER': 12
}
month = models.CharField(max_length=9, choices=MONTHS_CHOICES, default="JANUARY", db_index=True)
month_numeric = models.IntegerField(editable=False, db_index=True)
year = models.IntegerField(default=0)
def (self, *args, **kwargs):
self.month_numeric = self.MONTHS_ORDER[self.month]
super().save(*args, **kwargs)
注意: 如果您的数据库中已有数据,则需要编辑迁移文件以自动为已存储在数据库中的对象进行设置。同样,未经测试,但我想象如下:
def populate_month_numeric(apps, schema_editor):
Item = apps.get_model('YOUR APP NAME - CHANGE THIS!', 'Item')
for item in Item.objects.all():
item.month_numeric = Item.MONTHS_ORDER[item.month]
item.save()
然后,运行
makemigrations
后,打开创建的迁移文件,并在 Migration
类的 operations
字段中,在末尾处添加以下内容:
migrations.RunPython(populate_month_numeric)
当然,实际运行
migrate
函数,您的查询应该如下所示:
items = Item.objects.all().order_by("-year", "month_numeric")
正如我所说,我自己还没有运行过这段代码,但是“键”->“值”映射的这个方面是我过去解决类似问题的方法!