Django动态选择字段,约会空缺

时间:2018-10-30 22:49:01

标签: django python-3.x filter django-rest-framework aggregate

关于如何为表单创建动态选择字段,我需要一些指导。上下文是约会。我想让人们有能力预定自己的约会,但是这需要基于一些标准。标准是日期,时间和人数。

我希望时间字段成为动态选择字段。根据日期和聚会的大小“ psize” 我本来以为可以通过过滤,聚合和求和来实现。使用从谁发出的输入。

我当时想我可以从表格中获取日期和聚会的人数,并使用它来过滤和汇总选择相同选择的人数(这很重要,因为我希望15人或更少的人注册任何人给定的时间段),我的时间段以15分钟为增量,并在元组中列出(例如常规选择字段)。有什么想法吗?

models.py

class Reservation(models.Model):
"""This tuple is for the Inside, Outside, First Available 
drop down menu for the reservations tab """
    INSIDEOUTSIDE = (
        ('Inside','Inside'),
        ('Outside', 'Outside'),
        ('First Available', 'First Available'),
    )

    STATUS = (
        ('Reservation','Reservation'),
        ('Checked In','Checked In'),
        ('Seated','Seated'),
    )

    PARTYSIZE = (
        (1,'1'),
        (2,'2'),
        (3,'3'),
        (4,'4'),
        (5,'5'),
        (6,'6'),
        (7,'7'),
        (8,'8'),
        (9,'9'),
        (10,'10'),
        (11,'11'),
        (12,'12'),
    )    

    TIMEPERIOD= (
        ('11:30','11:30'),
        ('11:45','11:45'), 
        ('12:00','12:00'), 
        ('12:15','12:15'), 
    )


    name = models.CharField(max_length=22)
    psize = models.IntegerField('Party Size', choices= PARTYSIZE)
    Date = models.DateField()
    Time = models.CharField(max_length=15, choices=TIMEPERIOD)
    location = models.CharField(max_length=15, choices= INSIDEOUTSIDE, default= 'First Available')
    status = models.CharField(max_length=15, choices=STATUS, default='Reservation')
下面的

是有效的过滤器,并不完全正确。它返回我键入的项目,我希望能够将其传递给列表,并使其以部件尺寸“ psize”进行计算,然后将列表传递回具有可用时隙(时隙)的表格人数少于15人(包括填写表格的人数)。

Reservation.objects.filter(Date='2018-01-01',Time='2:30').aggregate(Sum('psize'))

有人能指出我正确的方向吗?有什么想法吗?

更新 下面是我在shell中用于确定选择的代码。

def getchoices(request):
    DATE = request.POST.get('Date')
    psize_input = request.post.get('psize')
    slots = Reservation.objects.filter(Date=DATE).values_list('Time').annotate(Sum('psize'))
    TIMEPERIOD= (
    ('11:30','11:30'),
    ('11:45','11:45'),
    ('12:00','12:00'),
    ('12:15','12:15'),
    ('12:30','12:30'),
    ('12:45','12:45'),
    ('01:00','01:00'),
    ('01:15','01:15'),
    ('01:30','01:30'),
    ('01:45','01:45'),
    ('02:00','02:00'),
    ('02:15','02:15'),
    ('02:30','02:30'),
    )
    def checkpsize():
            fullslots1=[]
            fullslots2=[]
            for object in slots:
                    if object[1] > 15-psize_input:
                            fullslots1.append(object[0])
                            fullslots2.append(object[0])
                            fullslotszip = zip(fullslots1, fullslots2)
                            fullslotstup = list(fullslotszip)
                            newchoices = list(filter(lambda x: x not in fullslotstup, TIMEPERIOD))
            return newchoices

但是,我发现很难将其连接到表单。我似乎无法弄清楚如何在表单中实现Ajax以根据psize和date输入填充时间字段。有什么好的开始的想法吗?一个教程可能吗?

1 个答案:

答案 0 :(得分:1)

假设您的用户插入了值psize_input,则可以使用:

 Reservation.objects
    .order_by('Date', 'Time')
    .values('Date', 'Time')
    .annotate(Sum('psize'))  # adds psize sum for each distinct data/time combo
    .filter(psize__sum__lte=15-psize_input)  # filters combos with enough capacity

获取以下形式的词典列表(实际上是ValuesIterable):

[
    {'Date': datetime.date(2018, 10, 31), 'Time': '11:30', 'psize__sum': 5},
    {'Date': datetime.date(2018, 10, 31), 'Time': '12:15', 'psize__sum': 2},
    {'Date': datetime.date(2018, 11, 1), 'Time': '11:45', 'psize__sum': 7},
    # ...
]

准确地包含具有足够容量的时隙,而该时隙中的当前psize总共有剩余容量。