Django_ CreateView показывает наличие класса
У меня есть проект тренажерного зала на django, с booking_create (CreateView) для создания заказов на занятия в тренажерном зале. Я использую модель и форму, с типами пользователей и классов. В HTML-шаблоне есть форма для бронирования занятий. Я хочу сделать эту форму недоступной, когда класс полностью забронирован, показывая вместо этого предупреждающее сообщение.
Мои мысли: Я должен иметь счетчик бронирований для созданных бронирований (например, booking_count), пересчитать это значение к вместимости класса и сохранить это в переменной (например, av_places= class_capacity-booking_count) и если av_places больше нуля, показать форму для регистрации, иначе показать предупреждение. Не уверен, как добавить эту функциональность в представление класса
Ниже представлены классы model, view и template.
models.py:
class Class_Book (models.Model):
user= models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
class = models.ForeignKey(Class, on_delete=models.CASCADE,default= '')
def __str__(self):
return f'{self.class}'
views.py
class booking_create (LoginRequiredMixin,CreateView):
form_class= Booking_Form
template_name= ‘booking_create.html'
success_url=reverse_lazy('home')
template:
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button class="btn btn-success" type="submit">SAVE</button>
</form>
Вы хотите сделать так, чтобы, если класс полностью забронирован, люди не могли видеть форму бронирования. Вместо этого они увидят сообщение о том, что класс заполнен. Этого можно добиться, добавив некоторую логику в представление.
Сначала настроим модели Ваша модель Booking выглядит хорошо, но есть небольшое замечание:
from django.db import models
from django.contrib.auth.models import User
class Booking(models.Model):
# It's fine to allow null=True, but usually, you’d want every booking to be tied to a user.
# You can automatically set the user in the view, so you might
# not need null=True unless there's a specific reason.
user = models.ForeignKey(
User, on_delete=models.CASCADE, blank=True
)
klass = models.ForeignKey(Class, on_delete=models.CASCADE)
# Just a heads up that default="" isn’t valid for ForeignKey fields, so it’s best to remove that.
def __str__(self):
return f"{self.klass}"
Добавление логики бронирования в представление
Теперь давайте добавим в ваше представление логику для проверки того, заполнен ли класс. Для этого мы переопределим метод get в вашем BookingCreateView:
from django.http import HttpResponse
from django.shortcuts import redirect
from django.urls import reverse, reverse_lazy
from django.views.generic import CreateView
from django.contrib.auth.mixins import LoginRequiredMixin
class BookingCreateView(LoginRequiredMixin, CreateView):
form_class = BookingForm
template_name = "booking_create.html"
success_url = reverse_lazy("home")
# Override the get method to check for availability
def get(self, request, *args, **kwargs) -> HttpResponse:
klass_id = self.kwargs.get('klass_id')
klass = Class.objects.get(id=klass_id)
# Count how many bookings already exist for this class
booking_count = Booking.objects.filter(klass=klass).count()
# Check if the class is full
if booking_count >= klass.capacity: # Assuming 'capacity' is a field in your Class model
return redirect(reverse("booking_closed")) # Redirect to a 'booking closed' page
# If there's space, show the form
return super().get(request, *args, **kwargs)
def form_valid(self, form: BookingForm):
# Inject the user to the form before saving.
booking: Booking = form.instance
booking.user = self.request.user
response = super().form_valid(form)#form save happens here
return response
Вам нужно создать простую страницу, которая сообщает пользователям, что класс полностью забронирован. Вот как это можно сделать с помощью представления на основе классов (CBV) или представления на основе функций (FBV).
from django.views.generic import TemplateView
class BookingClosedView(TemplateView):
template_name = "booking_closed.html"
Использование функционально-ориентированного представления (FBV):
from django.shortcuts import render
def booking_closed_view(request):
return render(request, "booking_closed.html")
Не забудьте добавить шаблон URL для этого в ваш urls.py
: