From 8d337092524a23740c0a8901d9c96c3c579b6077 Mon Sep 17 00:00:00 2001 From: Yuliia Dudych Date: Tue, 10 Dec 2024 21:10:25 +0200 Subject: [PATCH] Solution --- taxi/forms.py | 44 +++++++++++++++++++++++ taxi/models.py | 11 ++++++ taxi/urls.py | 14 ++++++++ taxi/views.py | 38 ++++++++++++++++++-- templates/taxi/car_detail.html | 31 +++++++++++----- templates/taxi/driver_confirm_delete.html | 10 ++++++ templates/taxi/driver_detail.html | 6 ++++ templates/taxi/driver_form.html | 12 +++++++ templates/taxi/driver_list.html | 6 +++- 9 files changed, 160 insertions(+), 12 deletions(-) create mode 100644 taxi/forms.py create mode 100644 templates/taxi/driver_confirm_delete.html create mode 100644 templates/taxi/driver_form.html diff --git a/taxi/forms.py b/taxi/forms.py new file mode 100644 index 000000000..9c57571ec --- /dev/null +++ b/taxi/forms.py @@ -0,0 +1,44 @@ +# import re + +from django.contrib.auth.forms import UserCreationForm +# from django.core.exceptions import ValidationError +from django.forms import ModelForm, CheckboxSelectMultiple + +from taxi.models import Driver, Car + + +class DriverCreationForm(UserCreationForm): + class Meta(UserCreationForm.Meta): + model = Driver + fields = UserCreationForm.Meta.fields + ( + "first_name", "last_name", "license_number" + ) + + # def clean_license_number(self): + # data = self.cleaned_data["license_number"] + # + # if not re.fullmatch(r"^[A-Z]{3}[0-9]{5}$", data): + # raise ValidationError("The license number is incorrect.") + # + # return data + + +class DriverLicenseUpdateForm(ModelForm): + class Meta: + model = Driver + fields = ("first_name", "last_name", "license_number") + + # def clean_license_number(self): + # data = self.cleaned_data["license_number"] + # + # if not re.fullmatch(r"^[A-Z]{3}[0-9]{5}$", data): + # raise ValidationError("The license number is incorrect.") + # + # return data + + +class CarCreateForm(ModelForm): + class Meta: + model = Car + fields = "__all__" + widgets = {"drivers": CheckboxSelectMultiple} diff --git a/taxi/models.py b/taxi/models.py index 769fd7002..bd04dfb95 100644 --- a/taxi/models.py +++ b/taxi/models.py @@ -1,3 +1,6 @@ +import re + +from django.core.exceptions import ValidationError from django.db import models from django.contrib.auth.models import AbstractUser from django.urls import reverse @@ -27,6 +30,14 @@ def __str__(self): def get_absolute_url(self): return reverse("taxi:driver-detail", kwargs={"pk": self.pk}) + def clean_license_number(self): + if not re.fullmatch(r"^[A-Z]{3}[0-9]{5}$", self.license_number): + raise ValidationError("The license number is incorrect.") + + def clean(self): + super().clean() + self.clean_license_number() + class Car(models.Model): model = models.CharField(max_length=255) diff --git a/taxi/urls.py b/taxi/urls.py index 4f017a999..0394839fb 100644 --- a/taxi/urls.py +++ b/taxi/urls.py @@ -13,6 +13,9 @@ ManufacturerCreateView, ManufacturerUpdateView, ManufacturerDeleteView, + DriverCreateView, + DriverDeleteView, + DriverUpdateView, ) urlpatterns = [ @@ -46,6 +49,17 @@ path( "drivers//", DriverDetailView.as_view(), name="driver-detail" ), + path("drivers/create/", DriverCreateView.as_view(), name="driver-create"), + path( + "drivers//delete/", + DriverDeleteView.as_view(), + name="driver-delete" + ), + path( + "drivers//update/", + DriverUpdateView.as_view(), + name="driver-update" + ) ] app_name = "taxi" diff --git a/taxi/views.py b/taxi/views.py index 0789d616e..88a310f81 100644 --- a/taxi/views.py +++ b/taxi/views.py @@ -1,9 +1,10 @@ from django.contrib.auth.decorators import login_required -from django.shortcuts import render -from django.urls import reverse_lazy +from django.shortcuts import render, redirect +from django.urls import reverse_lazy, reverse from django.views import generic from django.contrib.auth.mixins import LoginRequiredMixin +from .forms import DriverCreationForm, DriverLicenseUpdateForm, CarCreateForm from .models import Driver, Car, Manufacturer @@ -61,10 +62,24 @@ class CarListView(LoginRequiredMixin, generic.ListView): class CarDetailView(LoginRequiredMixin, generic.DetailView): model = Car + def post(self, request, *args, **kwargs): + self.object = self.get_object() + user = request.user + print(user) + if "add_driver" in request.POST: + self.object.drivers.add(user) + + if "remove_driver" in request.POST: + self.object.drivers.remove(user) + + return redirect(reverse( + "taxi:car-detail", kwargs={"pk": self.object.pk} + )) + class CarCreateView(LoginRequiredMixin, generic.CreateView): model = Car - fields = "__all__" + form_class = CarCreateForm success_url = reverse_lazy("taxi:car-list") @@ -87,3 +102,20 @@ class DriverListView(LoginRequiredMixin, generic.ListView): class DriverDetailView(LoginRequiredMixin, generic.DetailView): model = Driver queryset = Driver.objects.all().prefetch_related("cars__manufacturer") + + +class DriverCreateView(LoginRequiredMixin, generic.CreateView): + model = Driver + form_class = DriverCreationForm + success_url = reverse_lazy("taxi:driver-list") + + +class DriverDeleteView(LoginRequiredMixin, generic.DeleteView): + model = Driver + success_url = reverse_lazy("taxi:driver-list") + + +class DriverUpdateView(LoginRequiredMixin, generic.UpdateView): + model = Driver + form_class = DriverLicenseUpdateForm + success_url = reverse_lazy("taxi:driver-list") diff --git a/templates/taxi/car_detail.html b/templates/taxi/car_detail.html index 78197443a..c8de55265 100644 --- a/templates/taxi/car_detail.html +++ b/templates/taxi/car_detail.html @@ -3,20 +3,35 @@ {% block content %}

{{ car.model }} - - Delete - - - - Update -

Manufacturer: ({{ car.manufacturer.name }}, {{ car.manufacturer.country }})

-

Drivers

+

+ Drivers + {% if user.is_authenticated %} +
+ {% csrf_token %} + {% if user in car.drivers.all %} + + {% else %} + + {% endif %} +
+ {% endif %} +


    {% for driver in car.drivers.all %}
  • {{ driver.username }} ({{ driver.first_name }} {{ driver.last_name }})
  • {% endfor %}
+ + Update + + + Delete + {% endblock %} diff --git a/templates/taxi/driver_confirm_delete.html b/templates/taxi/driver_confirm_delete.html new file mode 100644 index 000000000..0b885b4dc --- /dev/null +++ b/templates/taxi/driver_confirm_delete.html @@ -0,0 +1,10 @@ +{% extends "base.html" %} + +{% block content %} +

Delete driver?

+
+ {% csrf_token %} + + +
+{% endblock %} \ No newline at end of file diff --git a/templates/taxi/driver_detail.html b/templates/taxi/driver_detail.html index 788084648..b88a41b93 100644 --- a/templates/taxi/driver_detail.html +++ b/templates/taxi/driver_detail.html @@ -23,4 +23,10 @@

Cars

No cars!

{% endfor %} + + Update + + + Delete + {% endblock %} diff --git a/templates/taxi/driver_form.html b/templates/taxi/driver_form.html new file mode 100644 index 000000000..0d4a46791 --- /dev/null +++ b/templates/taxi/driver_form.html @@ -0,0 +1,12 @@ +{% extends "base.html" %} +{% load crispy_forms_filters %} + +{% block content %} +

Create driver:

+
+ {% csrf_token %} + {{ form|crispy }} + + +
+{% endblock %} \ No newline at end of file diff --git a/templates/taxi/driver_list.html b/templates/taxi/driver_list.html index b740f95ea..c9d864914 100644 --- a/templates/taxi/driver_list.html +++ b/templates/taxi/driver_list.html @@ -1,7 +1,11 @@ {% extends "base.html" %} {% block content %} -

Driver List +

+ Driver List + + Create +

{% if driver_list %}