我正在构建预订表格,并希望允许用户从未来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
现在我难住了……我该怎么做?我觉得我走错了路。
预先感谢
答案 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_list
与flat=True
结合使用,以获取所有现有的预订日期,然后创建一个由2个元组组成的列表date_choices
,以实际的datetime对象作为值,并在其中显示字符串表示形式。使用strftime
选择的任何格式。
然后使用sorted
根据第一个键按日期升序对日期进行排序,因为使用集合会弄乱排序顺序。
然后看看this question,以了解如何从视图中将这些选择传递到表单中,因为我认为在定义Form类本身时尝试动态设置选择不是一件好事。