###解決したいこと
現在、自作アプリに予約システムを実装しようとしています。こちらのサイトからクローンでアプリにひとまず実装でき、これから自分用にカスタマイズしようといったところです。
アプリのイメージは以下のようなものです。
⑴好きなカテゴリーを選択⑵オーガナイザーを選択⑶日時を決めて予約といった流れで、好きなカテゴリーについて話せる場を作れればいいなと思い、開発を進めています。
現状、クローンで実装したこともあり1つの「カテゴリー・オーガナイザー・日時」の枠で1人まで予約するところまでは問題なく進みました。で、カスタマイズをしようという段階なのですが、一つの「カテゴリー・オーガナイザー・日時」に対して予約できる人数を5人にしたいです。
###関連コード
python
1models.py 2 3class Category(models.Model): 4 name = models.CharField('Category', max_length=255) 5 6 def __str__(self): 7 return self.name 8 9 10class Staff(models.Model): 11 name = models.CharField('Name', max_length=50) 12 user = models.ForeignKey( 13 settings.AUTH_USER_MODEL, verbose_name='ログインユーザー', on_delete=models.CASCADE 14 ) 15 category = models.ForeignKey(Category, verbose_name='カテゴリー', on_delete=models.CASCADE) 16 17 class Meta: 18 constraints = [ 19 models.UniqueConstraint(fields=['user', 'category'], name='unique_staff'), 20 ] 21 22 def __str__(self): 23 return f'{self.category.name} - {self.name}' 24 25 26class Schedule(models.Model): 27 start = models.DateTimeField('Start') 28 end = models.DateTimeField('End') 29 name = models.CharField('Name', max_length=255) 30 staff = models.ForeignKey('Staff', verbose_name='スタッフ', on_delete=models.CASCADE) 31 32 def __str__(self): 33 start = timezone.localtime(self.start).strftime('%Y/%m/%d %H:%M:%S') 34 end = timezone.localtime(self.end).strftime('%Y/%m/%d %H:%M:%S') 35 return f'{self.name} {start} ~ {end} {self.staff}' 36
python
1 2#views.py 3 4from django.shortcuts import render 5 6# Create your views here. 7 8User = get_user_model() 9 10 11class OnlyStaffMixin(UserPassesTestMixin): 12 raise_exception = True 13 14 def test_func(self): 15 staff = get_object_or_404(Staff, pk=self.kwargs['pk']) 16 return staff.user == self.request.user or self.request.user.is_superuser 17 18 19class OnlyScheduleMixin(UserPassesTestMixin): 20 raise_exception = True 21 22 def test_func(self): 23 schedule = get_object_or_404(Schedule, pk=self.kwargs['pk']) 24 return schedule.staff.user == self.request.user or self.request.user.is_superuser 25 26 27class OnlyUserMixin(UserPassesTestMixin): 28 raise_exception = True 29 30 def test_func(self): 31 return self.kwargs['pk'] == self.request.user.pk or self.request.user.is_superuser 32 33 34class CategoryList(generic.ListView): 35 model = Category 36 ordering = 'name' 37 38 39class StaffList(generic.ListView): 40 model = Staff 41 ordering = 'name' 42 43 def get_context_data(self, **kwargs): 44 context = super().get_context_data(**kwargs) 45 context['category'] = self.category 46 return context 47 48 def get_queryset(self): 49 category = self.category = get_object_or_404(Category, pk=self.kwargs['pk']) 50 queryset = super().get_queryset().filter(category=category) 51 return queryset 52 53 54class StaffCalendar(generic.TemplateView): 55 template_name = 'book/calendar.html' 56 57 def get_context_data(self, **kwargs): 58 context = super().get_context_data(**kwargs) 59 staff = get_object_or_404(Staff, pk=self.kwargs['pk']) 60 today = datetime.date.today() 61 62 # どの日を基準にカレンダーを表示するかの処理。 63 # 年月日の指定があればそれを、なければ今日からの表示。 64 year = self.kwargs.get('year') 65 month = self.kwargs.get('month') 66 day = self.kwargs.get('day') 67 if year and month and day: 68 base_date = datetime.date(year=year, month=month, day=day) 69 else: 70 base_date = today 71 72 # カレンダーは1週間分表示するので、基準日から1週間の日付を作成しておく 73 days = [base_date + datetime.timedelta(days=day) for day in range(7)] 74 start_day = days[0] 75 end_day = days[-1] 76 77 # 9時から17時まで1時間刻み、1週間分の、値がTrueなカレンダーを作る 78 calendar = {} 79 for hour in range(9, 18): 80 row = {} 81 for day in days: 82 row[day] = True 83 calendar[hour] = row 84 85 # カレンダー表示する最初と最後の日時の間にある予約を取得する 86 start_time = datetime.datetime.combine(start_day, datetime.time(hour=9, minute=0, second=0)) 87 end_time = datetime.datetime.combine(end_day, datetime.time(hour=17, minute=0, second=0)) 88 for schedule in Schedule.objects.filter(staff=staff).exclude(Q(start__gt=end_time) | Q(end__lt=start_time)): 89 local_dt = timezone.localtime(schedule.start) 90 booking_date = local_dt.date() 91 booking_hour = local_dt.hour 92 if booking_hour in calendar and booking_date in calendar[booking_hour]: 93 calendar[booking_hour][booking_date] = False 94 95 context['staff'] = staff 96 context['calendar'] = calendar 97 context['days'] = days 98 context['start_day'] = start_day 99 context['end_day'] = end_day 100 context['before'] = days[0] - datetime.timedelta(days=7) 101 context['next'] = days[-1] + datetime.timedelta(days=1) 102 context['today'] = today 103 context['public_holidays'] = settings.PUBLIC_HOLIDAYS 104 return context 105 106 107class Booking(generic.CreateView): 108 model = Schedule 109 fields = ('name',) 110 template_name = 'book/booking.html' 111 112 def get_context_data(self, **kwargs): 113 context = super().get_context_data(**kwargs) 114 context['staff'] = get_object_or_404(Staff, pk=self.kwargs['pk']) 115 return context 116 117 def form_valid(self, form): 118 staff = get_object_or_404(Staff, pk=self.kwargs['pk']) 119 year = self.kwargs.get('year') 120 month = self.kwargs.get('month') 121 day = self.kwargs.get('day') 122 hour = self.kwargs.get('hour') 123 start = datetime.datetime(year=year, month=month, day=day, hour=hour) 124 end = datetime.datetime(year=year, month=month, day=day, hour=hour + 1) 125 if Schedule.objects.filter(staff=staff, start=start).exists(): 126 messages.error(self.request, 'Sorry, No empty') 127 else: 128 schedule = form.save(commit=False) 129 schedule.staff = staff 130 schedule.start = start 131 schedule.end = end 132 schedule.save() 133 return redirect('book:calendar', pk=staff.pk, year=year, month=month, day=day) 134 135 136class MyPage(LoginRequiredMixin, generic.TemplateView): 137 template_name = 'book/my_page.html' 138 139 def get_context_data(self, **kwargs): 140 context = super().get_context_data(**kwargs) 141 context['staff_list'] = Staff.objects.filter(user=self.request.user).order_by('name') 142 context['schedule_list'] = Schedule.objects.filter(staff__user=self.request.user, start__gte=timezone.now()).order_by('name') 143 return context 144 145 146class MyPageWithPk(OnlyUserMixin, generic.TemplateView): 147 template_name = 'book/my_page.html' 148 149 def get_context_data(self, **kwargs): 150 context = super().get_context_data(**kwargs) 151 context['user'] = get_object_or_404(User, pk=self.kwargs['pk']) 152 context['staff_list'] = Staff.objects.filter(user__pk=self.kwargs['pk']).order_by('name') 153 context['schedule_list'] = Schedule.objects.filter(staff__user__pk=self.kwargs['pk'], start__gte=timezone.now()).order_by('name') 154 return context 155 156 157class MyPageCalendar(OnlyStaffMixin, StaffCalendar): 158 template_name = 'book/my_page_calendar.html' 159 160 161class MyPageDayDetail(OnlyStaffMixin, generic.TemplateView): 162 template_name = 'book/my_page_day_detail.html' 163 164 def get_context_data(self, **kwargs): 165 context = super().get_context_data(**kwargs) 166 pk = self.kwargs['pk'] 167 staff = get_object_or_404(Staff, pk=pk) 168 year = self.kwargs.get('year') 169 month = self.kwargs.get('month') 170 day = self.kwargs.get('day') 171 date = datetime.date(year=year, month=month, day=day) 172 173 # 9時から17時まで1時間刻みのカレンダーを作る 174 calendar = {} 175 for hour in range(9, 18): 176 calendar[hour] = [] 177 178 # カレンダー表示する最初と最後の日時の間にある予約を取得する 179 start_time = datetime.datetime.combine(date, datetime.time(hour=9, minute=0, second=0)) 180 end_time = datetime.datetime.combine(date, datetime.time(hour=17, minute=0, second=0)) 181 for schedule in Schedule.objects.filter(staff=staff).exclude(Q(start__gt=end_time) | Q(end__lt=start_time)): 182 local_dt = timezone.localtime(schedule.start) 183 booking_date = local_dt.date() 184 booking_hour = local_dt.hour 185 if booking_hour in calendar: 186 calendar[booking_hour].append(schedule) 187 188 context['calendar'] = calendar 189 context['staff'] = staff 190 return context 191 192 193class MyPageSchedule(OnlyScheduleMixin, generic.UpdateView): 194 model = Schedule 195 fields = ('start', 'end', 'name') 196 success_url = reverse_lazy('book:my_page') 197 198 199class MyPageScheduleDelete(OnlyScheduleMixin, generic.DeleteView): 200 model = Schedule 201 success_url = reverse_lazy('book:my_page') 202 203 204@require_POST 205def my_page_holiday_add(request, pk, year, month, day, hour): 206 staff = get_object_or_404(Staff, pk=pk) 207 if staff.user == request.user or request.user.is_superuser: 208 start = datetime.datetime(year=year, month=month, day=day, hour=hour) 209 end = datetime.datetime(year=year, month=month, day=day, hour=hour + 1) 210 Schedule.objects.create(staff=staff, start=start, end=end, name='休暇(システムによる追加)') 211 return redirect('book:my_page_day_detail', pk=pk, year=year, month=month, day=day) 212 213 raise PermissionDenied 214
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/10/23 07:13 編集