Django:修复对象列表的顺序问题

inn6fuwd  于 2022-11-18  发布在  Go
关注(0)|答案(2)|浏览(164)

我有一个从数据库中获取查询集结果并进行一些操作的函数。
当我得到那个列表的结果时,不知何故顺序被改变了。
而正是这个函数改变了顺序:schedules = list(set(schedule_list) - set(excluded_schedules))
所以我会确切地解释:
我想显示某个专业人员的可用性以进行预约。此专业人员具有可用插槽的列表。
当访问者加载专业人士的个人资料页面时,Django会查询该专业人士的所有时间段,然后获取所有现有的约会,然后从总日程表中删除已预订的日程表,以显示其余的(可用的日程表)。
因此,代码如下(针对敏感信息进行了编辑):

def get_home_schedules(date, professional):
    day = get_day_by_date(date)
    try:
        schedules = Schedule.objects.filter(professional=professional, day=day, stype="Home").order_by('timefrom')
        excluded_schedules = []
        schedule_list = []
        for s in schedules:
            new_appointments = s.appointments.filter(schedule=s, date=date, status='New')
            confirmed_appointments = s.appointments.filter(schedule=s, date=date, status='Confirmed')
            appointments = chain(new_appointments,confirmed_appointments)
            schedule_list.append(s)
            if appointments:
                for a in appointments:
                    excluded_schedules.append(a.schedule)
        schedules = list(set(schedule_list) - set(excluded_schedules))
        return schedules
    except:
        return None

计划模型为:

class Schedule(models.Model):
    professional = models.ForeignKey(d, on_delete=models.CASCADE)
    timefrom = models.CharField(max_length=5, choices=HOURTIME, default="00:00")
    timeto = models.CharField(max_length=5, choices=HOURTIME, default="00:00")
    day = models.CharField(max_length=8, choices=DAYS, default="Monday")
    stype = models.CharField(max_length=10, choices=APPOINTMENT_TYPE, default='Office')
    posted = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = "Availability"
        verbose_name_plural = "Availabilities"
        constraints = [
            models.UniqueConstraint(fields=['professional', 'timefrom', 'day'], name='unique schedule')
        ]

    def __str__(self):
        return '%s (%s - %s - %s)' % (self.professional, self.day, self.timefrom, self.timeto)

预约类型包括:办公室、联机、家庭
我的问题是,我有3个不同的功能,获得可用的时间表,每种约会类型一个,该功能在办公室和在线类型中没有任何问题,但在家庭类型中有顺序问题。
订单可能是因为小时,请告诉我,如果它是真的或不是(即使我不认为这是情况,因为订单没有得到混乱,在其他情况下)。

zfciruhq

zfciruhq1#

当你这样做

schedules = list(set(schedule_list) - set(excluded_schedules))

顺序丢失(因为set是无序的)。
您可以在之后重新排序(这样就可以去掉.order_by(),因为它并不重要):

schedules = sorted(
   set(schedule_list) - set(excluded_schedules),
   key=lambda s: s.timefrom,
)

您还可以使用以下方法将其优化为正好2个查询

day = get_day_by_date(date)

schedules = Schedule.objects.filter(professional=professional, day=day, stype="Home").order_by('timefrom')

conflicting_appointment_schedule_ids = set(Appointment.objects.filter(
    schedule__in=schedules,
    status__in=["New", "Confirmed"],
    date=date,
).values_list("schedule_id", flat=True))

return [sched for sched in schedules if sched.id not in conflicting_appointment_schedule_ids]

而且我相信单个查询也是可能的。

qvk1mo1f

qvk1mo1f2#

python集合是一个无序的对象集合,这意味着在创建如下所示的计划列表时,顺序可能会发生变化:

schedules = list(set(schedule_list) - set(excluded_schedules))

在检索初始查询集时,您应该删除.order_by('timefrom')(因为无论如何都不能保证顺序),并将其添加到return语句中。例如:

def get_home_schedules(date, professional):
    day = get_day_by_date(date)
    try:
        schedules = Schedule.objects.filter(professional=professional, day=day, stype="Home")
        excluded_schedules = []
        schedule_list = []
        for s in schedules:
            new_appointments = s.appointments.filter(schedule=s, date=date, status='New')
            confirmed_appointments = s.appointments.filter(schedule=s, date=date, status='Confirmed')
            appointments = chain(new_appointments,confirmed_appointments)
            schedule_list.append(s.id)
            if appointments:
                for a in appointments:
                    excluded_schedules.append(a.schedule.id)
        schedule_ids = list(set(schedule_list) - set(excluded_schedules))
        return Schedule.objects.filter(id__in=schedule_ids).order_by('timefrom')
    except:
        return None

相关问题