无法解包不可迭代的datetime.date对象

时间:2019-11-29 15:28:12

标签: python django

我正在构建预订表格,并希望允许用户从未来60天内的可用日期中选择预订日期。

接下来的60天,我将通过:

base = datetime.date.today()
date_list = [base + datetime.timedelta(days=x) for x in range(60)]

然后我减去已存储在数据库中的预定日期:

bookings = list(Booking.objects.all())
primarykeys = []
unav = []

for b in bookings:
    primarykeys.append(b.pk)

for p in primarykeys:
    unav.append(Booking.objects.get(pk=p).booking_date)

for date in unav:
    if date in date_list:
        date_list.remove(date)

然后将结果更改为表单的元组(不确定是否正确吗?):

date_list = tuple(date_list)

然后我将其传递给表单字段,如下所示:

booking_date = forms.ChoiceField(choices=date_list, required=True)

这给我一个cannot unpack non-iterable datetime.date object

的错误

现在我难住了……我该怎么做?我觉得我走错了路。

预先感谢

1 个答案:

答案 0 :(得分:1)

Django Form fields的文档显示以下内容:

  

选择

     

要么是一个2元组的可迭代对象用作该字段的选择,要么是一个可返回该迭代对象的可调用对象。该论点接受   与模型字段的choices参数相同的格式。见模型   有关选择的详细信息,请参考现场参考文档。如果   参数是可调用的,每次字段字段为   初始化。默认为空列表。

您似乎传递的是以下格式的元组:

(date object, date object, ...)

但是您需要传递类似2元组的列表的内容,每个元组的第一个元素是为每个选择存储的值,第二个元素是以以下形式显示给用户的值:

[(date_object, date_string), (date_object, date_string), ...)

将您的代码更改为以下代码,然后查看是否适合您:

base = datetime.date.today()
date_set = set([base + datetime.timedelta(days=x) for x in range(60)])
booking_dates = set(Booking.objects.all().values_list('booking_date', flat=True))
valid_dates = date_set - booking_dates

date_choices = sorted([(valid_date, valid_date.strftime('%Y-%m-%d')) for valid_date in valid_dates], 
                      key=lambda x: x[0])

我使用了集合来简化确保唯一值的过程,并在没有多个for循环的情况下将它们彼此相减。您可以将values_listflat=True结合使用,以获取所有现有的预订日期,然后创建一个由2个元组组成的列表date_choices,以实际的datetime对象作为值,并在其中显示字符串表示形式。使用strftime选择的任何格式。

然后使用sorted根据第一个键按日期升序对日期进行排序,因为使用集合会弄乱排序顺序。

然后看看this question,以了解如何从视图中将这些选择传递到表单中,因为我认为在定义Form类本身时尝试动态设置选择不是一件好事。