3

環境

1 週間の営業時間を設定できるように、フォームセットを作成する必要があります。

状態

開店時間のモデルは次のとおりです。

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 を formset に入れるにはどうすればよいですか?


編集

例として、ユーザーがすでに月曜日と木曜日の時間をデータベースに設定しているとします。フォームは次のようになります。

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}
]

明らかに、これは 1 日ごとに 1 つまたは 3 つのクエリセットを構築するため非効率的です。したがって、次のように書き換えます。

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 に答える