質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Webサイト

一つのドメイン上に存在するWebページの集合体をWebサイトと呼びます。

Q&A

解決済

1回答

1949閲覧

Djangoで予約可能人数の上限をあげたい。

Kazuhiro-ch

総合スコア85

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Webサイト

一つのドメイン上に存在するWebページの集合体をWebサイトと呼びます。

0グッド

0クリップ

投稿2021/10/16 07:55

###解決したいこと
現在、自作アプリに予約システムを実装しようとしています。こちらのサイトからクローンでアプリにひとまず実装でき、これから自分用にカスタマイズしようといったところです。

アプリのイメージは以下のようなものです。
⑴好きなカテゴリーを選択⑵オーガナイザーを選択⑶日時を決めて予約といった流れで、好きなカテゴリーについて話せる場を作れればいいなと思い、開発を進めています。

現状、クローンで実装したこともあり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

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

単純に、コードのどこかでバリデーションをすれば良いと思います。

流れとしては、

  1. viewである予約イベント(Scheduleモデル)のidを指定し
  2. 紐づく外部キーのユーザーをカウントし
  3. 5人以上なら400番エラーを返す

という感じで実装は可能です。

投稿2021/10/17 00:46

prof

総合スコア179

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Kazuhiro-ch

2021/10/23 07:13 編集

Bookingクラスのdef form_valid(self, form)関数をもとに変更を加えていくという認識で間違いありませんか?勉強不足は承知の上なのですが、関数のあたりがまだあまり慣れていないので、もう少し具体的におしえていただけるとありがたいです。どうぞよろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問