如何通过属性的选择对查询集进行排序

问题描述 投票:0回答:1

我在 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
,就像这里的问题并按该字段排序

我也尝试了此页面上的解决方案,但没有任何效果。

django django-models
1个回答
0
投票

我自己还没有机会对此进行测试,但我的猜测是使用月份名称作为字典中的“键”,其中相应的“值”是适当的月份序数值(即 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")

正如我所说,我自己还没有运行过这段代码,但是“键”->“值”映射的这个方面是我过去解决类似问题的方法!

© www.soinside.com 2019 - 2024. All rights reserved.