3

语境

我需要构建一个表单集以允许将开放时间设置为一周。

地位

这是我的开放时间模型:

WEEKDAYS = [
  (1, _("Monday")),
  (2, _("Tuesday")),
  (3, _("Wednesday")),
  (4, _("Thursday")),
  (5, _("Friday")),
  (6, _("Saturday")),
  (7, _("Sunday")),
]

class OpeningHours(models.Model):
    user = models.ForeignKey(User)
    weekday = models.IntegerField(choices=WEEKDAYS)
    from_hour = models.TimeField()
    to_hour = models.TimeField()
    class Meta:
        unique_together = (('user', 'weekday'),)

这是我为默认周设置生成表单集的方式

UserOpeningHoursFormSet = formset_factory(UserOpeningHoursForm, extra=0)
hours = [{
        'weekday': day,
        'from_hour': '08:00',
        'to_hour': '18:00',
    } for day in range(1, 8)]
formset = UserOpeningHoursFormSet(initial=hours)

这是我如何获得当前用户的营业时间

user_hours = request.user.openinghours_set.all()

问题

如何将 user_hours 放入我的表单集中?


编辑

例如,假设用户已经在数据库中设置了星期一和星期四的时间,表单应该类似于:

weekday: Monday
from_hour: '09:00' # user_set
to_hour: '19:00' # user_set

weekday: Tuesday
from_hour: # default initial value
to_hour: # default initial value

weekday: Wednesday
from_hour: # default initial value
to_hour: # default initial value

weekday: Thursday
from_hour: '13:00' # user_set
to_hour: '15:00' # user_set

weekday: Friday
from_hour: # default initial value
to_hour: # default initial value

weekday: Saturday
from_hour: # default initial value
to_hour: # default initial value
4

3 回答 3

2

扩展@Rohan的回答:

我不认为modelformset是必要的,只需像这样构建时间

hours = [
    {'weekday': day, 'from_hour': '08:00', 'to_hour': '18:00'} 
    for day in range(1, 8) if not any(request.user.openinghours_set.filter(weekday=day))
    else
    {'weekday': day, 'from_hour': request.user.openinghours_set.filter(weekday=day).from_hour,
     'to_hour': request.user.openinghours_set.filter(weekday=day).to_hour}
]

显然,这是低效的,因为它每天构造一个或三个查询集,所以重写它是这样的:

hours = []

openinghours_set = list(request.user.openinghours_set.all())
for day in range(1, 8):
    for openinghours in openinghours_set:
        if openinghours.weekday == day:
            hours.append({ fill from *openinghours* })
            break
    else:
        hours.append({ fill with default values })
于 2012-09-14T10:52:39.497 回答
0

您可以使用modelformset并提供适当的查询集。

formset = UserOpeningHoursModelFormSet(queryset=request.user.openinghours_set.filter())

还有一些其他方法可以更改查询集。

编辑:

可能是您可以max_num在创建表单集实例时使用参数以及initial. 因此,您将从现有实例中获取表单,如果实例不够,将使用初始 dict 中的数据创建新表单。

    UserOpeningHoursFormSet = modelformset_factory(UserOpeningHoursForm, extra=7, max_num=7)
    formset = UserOpeningHoursModelFormSet(initial=hours,
                 queryset=request.user.openinghours_set.filter())

我还没有验证这一点,所以我怀疑它可能会为每个初始数据项添加表单。因此,在最坏的情况下,您需要创建hours跳过设置小时数的日期的列表。

于 2012-09-14T10:17:25.650 回答
0

这是我最终得到的结果:

user_hours = request.user.openinghours_set
hours = []
for day_id in range(0, 6):
    item = {'weekday': day_id, 'from_hour': '08:00', 'to_hour': '18:00'}
    if any(user_hours.filter(weekday=day_id)):
        my_item = user_hours.get(weekday=day_id)
        item['from_hour'] = my_item.from_hour.strftime('%H:%M')
        item['to_hour'] = my_item.to_hour.strftime('%H:%M')
    hours.append(item)

我会更喜欢一个更pythonic的版本......

于 2012-09-14T13:38:10.890 回答