参考ページ⇒https://narito.ninja/blog/detail/126/
カレンダーにスケジュールを保存できるようにしたく勉強中ですが、行き詰まりご助力お願いします。
やりたいこと:
下記コードだと、各日に予定を入力する新規フォームが設置されていますが、予定を保存すると更に新規フォームが追加されます。
予定未保存⇒新規フォームのみ 予定保存済⇒新規フォーム、更新フォーム
って感じです。
予定未保存⇒新規フォームのみ 予定保存済⇒更新フォーム
と変更したいのですが、どうすればいいのか分かりません。
説明下手ですいません。
下記画像
mixins.py class MonthWithFormsMixin(MonthCalendarMixin): """スケジュール付きの、月間カレンダーを提供するMixin""" def get_month_forms(self, start, end, days): """それぞれの日と紐づくフォームを作成する""" lookup = { # '例えば、date__range: (1日, 31日)'を動的に作る '{}__range'.format(self.date_field): (start, end), 'user__pk': self.kwargs.get('user_pk'), } # 例えば、Schedule.objects.filter(date__range=(1日, 31日)) になる queryset = self.model.objects.filter(**lookup) days_count = len(days) FormClass = forms.modelformset_factory(self.model, self.form_class, extra=days_count,max_num=days_count) if self.request.method == 'POST': formset = self.month_formset = FormClass(self.request.POST, queryset=queryset) else: formset = self.month_formset = FormClass(queryset=queryset) # {1日のdatetime: 1日に関連するフォーム, 2日のdatetime: 2日のフォーム...}のような辞書を作る day_forms = {day: [] for day in days } # 各日に、新規作成用フォームを1つずつ配置 for empty_form, (date, empty_list) in zip(formset.extra_forms, day_forms.items()): empty_form.initial = {self.date_field: date} empty_list.append(empty_form) # スケジュールがある各日に、そのスケジュールの更新用フォームを配置 for bound_form in formset.initial_forms: instance = bound_form.instance date = getattr(instance, self.date_field) day_forms[date].append(bound_form) # day_forms辞書を、周毎に分割する。[{1日: 1日のフォーム...}, {8日: 8日のフォーム...}, ...] # 7個ずつ取り出して分割しています。 return [{key: day_forms[key] for key in itertools.islice(day_forms, i, i+7)} for i in range(0, days_count, 7)] def get_month_calendar(self): calendar_context = super().get_month_calendar() month_days = calendar_context['month_days'] month_first = month_days[0] month_last = month_days[-1] calendar_context['month_day_forms'] = self.get_month_forms( month_first, month_last, month_days ) calendar_context['month_formset'] = self.month_formset return calendar_context
views.py class MonthWithFormsCalendar(mixins.MonthWithFormsMixin, generic.View): """フォーム付きの月間カレンダーを表示するビュー""" template_name = 'app/month_with_forms.html' model = Schedule date_field = 'date' form_class = SimpleScheduleForm def get(self, request, **kwargs): context = self.get_month_calendar() context['user'] = get_object_or_404(User, pk=self.kwargs['user_pk']) return render(request, self.template_name, context) def post(self, request, **kwargs): context = self.get_month_calendar() user_pk = self.kwargs['user_pk'] user = get_object_or_404(User, pk=user_pk) context['user'] = user formset = context['month_formset'] if formset.is_valid(): instances = formset.save(commit=False) for schedule in instances: schedule.user = user schedule.save() return redirect('app:month_with_forms', user_pk=user_pk) return render(request, self.template_name, context)
models.py SUB_START = ( ('0', '✕'), ('1', '14'), ('2', '16'), ('3', '17'), ('4', '17.5'), ('5', '18'), ('6', '18.5'), ('7', '19'), ('8', '19.5'), ('9', '20'), ('10', '〇'), ) SUB_END = ( ('0', '✕'), ('1', '22'), ('2', '23'), ('3', '〇'), ) class Schedule(models.Model): """スケジュール""" user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='ユーザー', on_delete=models.SET_NULL, blank=True, null=True) start_time = models.CharField('開始時間', choices= SUB_START, max_length=50,blank=True,default="0") end_time = models.CharField('終了時間', choices= SUB_END, max_length=50,blank=True,default="0") date = models.DateField('日付') # created_at = models.DateTimeField('作成日', default=timezone.now) def __int__(self): return self.date
forms.py from django import forms from .models import Schedule class BS4ScheduleForm(forms.ModelForm): """Bootstrapに対応するためのModelForm""" class Meta: model = Schedule fields = ('start_time', 'end_time') widgets = { 'start_time': forms.TextInput(attrs={ 'class': 'form-control', }), 'end_time': forms.TextInput(attrs={ 'class': 'form-control', }), } def clean_end_time(self): start_time = self.cleaned_data['start_time'] end_time = self.cleaned_data['end_time'] if end_time <= start_time: raise forms.ValidationError( '終了時間は、開始時間よりも後にしてください' ) return end_time class SimpleScheduleForm(forms.ModelForm): """シンプルなスケジュール登録用フォーム""" class Meta: model = Schedule fields = ('start_time', 'end_time', 'date') 'date': forms.HiddenInput, }
code内のコメントは参考ページ内でのコメントです。
modelformset周りがよくわかっておらず、参考にできそうなサイトなどあれば教えて頂けると助かります。
よろしくお願いします。
あなたの回答
tips
プレビュー