Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solution #875

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions taxi/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from django import forms
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit
from .models import Car, Manufacturer


class CarForm(forms.ModelForm):
class Meta:
model = Car
fields = ["model", "manufacturer", "drivers"]

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.add_input(Submit("submit", "Save"))


class ManufacturerForm(forms.ModelForm):
class Meta:
model = Manufacturer
fields = ["name", "country"]

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.add_input(Submit("submit", "Save"))
173 changes: 144 additions & 29 deletions taxi/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,54 +13,169 @@ class Migration(migrations.Migration):
initial = True

dependencies = [
('auth', '0012_alter_user_first_name_max_length'),
("auth", "0012_alter_user_first_name_max_length"),
]

operations = [
migrations.CreateModel(
name='Driver',
name="Driver",
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('password', models.CharField(max_length=128, verbose_name='password')),
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')),
('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
('license_number', models.CharField(max_length=255, unique=True)),
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')),
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')),
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("password", models.CharField(max_length=128, verbose_name="password")),
(
"last_login",
models.DateTimeField(
blank=True, null=True, verbose_name="last login"
),
),
(
"is_superuser",
models.BooleanField(
default=False,
help_text="Designates that this user has all permissions without explicitly assigning them.",
verbose_name="superuser status",
),
),
(
"username",
models.CharField(
error_messages={
"unique": "A user with that username already exists."
},
help_text="Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.",
max_length=150,
unique=True,
validators=[
django.contrib.auth.validators.UnicodeUsernameValidator()
],
verbose_name="username",
),
),
(
"first_name",
models.CharField(
blank=True, max_length=150, verbose_name="first name"
),
),
(
"last_name",
models.CharField(
blank=True, max_length=150, verbose_name="last name"
),
),
(
"email",
models.EmailField(
blank=True, max_length=254, verbose_name="email address"
),
),
(
"is_staff",
models.BooleanField(
default=False,
help_text="Designates whether the user can log into this admin site.",
verbose_name="staff status",
),
),
(
"is_active",
models.BooleanField(
default=True,
help_text="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.",
verbose_name="active",
),
),
(
"date_joined",
models.DateTimeField(
default=django.utils.timezone.now, verbose_name="date joined"
),
),
("license_number", models.CharField(max_length=255, unique=True)),
(
"groups",
models.ManyToManyField(
blank=True,
help_text="The groups this user belongs to. A user will get all permissions granted to each of their groups.",
related_name="user_set",
related_query_name="user",
to="auth.Group",
verbose_name="groups",
),
),
(
"user_permissions",
models.ManyToManyField(
blank=True,
help_text="Specific permissions for this user.",
related_name="user_set",
related_query_name="user",
to="auth.Permission",
verbose_name="user permissions",
),
),
],
options={
'verbose_name': 'driver',
'verbose_name_plural': 'drivers',
"verbose_name": "driver",
"verbose_name_plural": "drivers",
},
managers=[
('objects', django.contrib.auth.models.UserManager()),
("objects", django.contrib.auth.models.UserManager()),
],
),
migrations.CreateModel(
name='Manufacturer',
name="Manufacturer",
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255, unique=True)),
('country', models.CharField(max_length=255)),
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("name", models.CharField(max_length=255, unique=True)),
("country", models.CharField(max_length=255)),
],
options={
'ordering': ['name'],
"ordering": ["name"],
},
),
migrations.CreateModel(
name='Car',
name="Car",
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('model', models.CharField(max_length=255)),
('drivers', models.ManyToManyField(related_name='cars', to=settings.AUTH_USER_MODEL)),
('manufacturer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='taxi.manufacturer')),
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("model", models.CharField(max_length=255)),
(
"drivers",
models.ManyToManyField(
related_name="cars", to=settings.AUTH_USER_MODEL
),
),
(
"manufacturer",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="taxi.manufacturer",
),
),
],
),
]
28 changes: 27 additions & 1 deletion taxi/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
DriverListView,
DriverDetailView,
ManufacturerListView,
CarCreateView,
CarUpdateView,
CarDeleteView,
ManufacturerCreateView,
ManufacturerUpdateView,
ManufacturerDeleteView,
)

urlpatterns = [
Expand All @@ -20,7 +26,27 @@
path("cars/<int:pk>/", CarDetailView.as_view(), name="car-detail"),
path("drivers/", DriverListView.as_view(), name="driver-list"),
path(
"drivers/<int:pk>/", DriverDetailView.as_view(), name="driver-detail"
"drivers/<int:pk>/",
DriverDetailView.as_view(),
name="driver-detail"
),
path("cars/create/", CarCreateView.as_view(), name="car-create"),
path("cars/<int:pk>/update/", CarUpdateView.as_view(), name="car-update"),
path("cars/<int:pk>/delete/", CarDeleteView.as_view(), name="car-delete"),
path(
"manufacturers/create/",
ManufacturerCreateView.as_view(),
name="manufacturer-create",
),
path(
"manufacturers/<int:pk>/update/",
ManufacturerUpdateView.as_view(),
name="manufacturer-update",
),
path(
"manufacturers/<int:pk>/delete/",
ManufacturerDeleteView.as_view(),
name="manufacturer-delete",
),
]

Expand Down
43 changes: 43 additions & 0 deletions taxi/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@
from django.shortcuts import render
from django.views import generic
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy
from django.views.generic import CreateView, UpdateView, DeleteView

from .models import Driver, Car, Manufacturer
from .forms import CarForm, ManufacturerForm


@login_required
Expand Down Expand Up @@ -52,3 +55,43 @@ class DriverListView(LoginRequiredMixin, generic.ListView):
class DriverDetailView(LoginRequiredMixin, generic.DetailView):
model = Driver
queryset = Driver.objects.all().prefetch_related("cars__manufacturer")


class CarCreateView(CreateView):
model = Car
form_class = CarForm
template_name = "taxi/car_form.html"
success_url = reverse_lazy("taxi:car-list")


class CarUpdateView(UpdateView):
model = Car
form_class = CarForm
template_name = "taxi/car_form.html"
success_url = reverse_lazy("taxi:car-list")


class CarDeleteView(DeleteView):
model = Car
template_name = "taxi/car_confirm_delete.html"
success_url = reverse_lazy("taxi:car-list")


class ManufacturerCreateView(CreateView):
model = Manufacturer
form_class = ManufacturerForm
template_name = "taxi/manufacturer_form.html"
success_url = reverse_lazy("taxi:manufacturer-list")


class ManufacturerUpdateView(UpdateView):
model = Manufacturer
form_class = ManufacturerForm
template_name = "taxi/manufacturer_form.html"
success_url = reverse_lazy("taxi:manufacturer-list")


class ManufacturerDeleteView(DeleteView):
model = Manufacturer
template_name = "taxi/manufacturer_confirm_delete.html"
success_url = reverse_lazy("taxi:manufacturer-list")
3 changes: 3 additions & 0 deletions taxi_service/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"django.contrib.staticfiles",
"debug_toolbar",
"taxi",
"crispy_forms",
]

MIDDLEWARE = [
Expand Down Expand Up @@ -140,3 +141,5 @@
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

CRISPY_TEMPLATE_PACK = "bootstrap4"
11 changes: 11 additions & 0 deletions templates/taxi/car_confirm_delete.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{% extends "base.html" %}

{% block content %}
<h1>Delete Car</h1>
<p>Are you sure you want to delete "{{ object }}"?</p>
<form method="post">
{% csrf_token %}
<button type="submit" class="btn btn-danger">Delete</button>
<a href="{% url 'taxi:car-list' %}" class="btn btn-secondary">Cancel</a>
</form>
{% endblock %}
12 changes: 12 additions & 0 deletions templates/taxi/car_form.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{% extends "base.html" %}

{% load crispy_forms_tags %}

{% block content %}
<h1>{% if object %}Edit{% else %}Add{% endif %} Car</h1>
<form method="post">
{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="btn btn-primary">Save</button>
</form>
{% endblock %}
7 changes: 5 additions & 2 deletions templates/taxi/car_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@

{% block content %}
<h1>Car list</h1>
<a href="{% url 'taxi:car-create' %}" class="btn btn-primary">Add Car</a>
{% if car_list %}
<ul>
{% for car in car_list %}
<li>
<a href="{% url "taxi:car-detail" pk=car.id %} ">{{ car.id }}</a>
{{ car.model }} ({{ car.manufacturer.name }})
<a href="{% url 'taxi:car-detail' pk=car.id %}">{{ car.model }}</a>
({{ car.manufacturer.name }})
<a href="{% url 'taxi:car-update' pk=car.id %}" class="btn btn-secondary">Edit</a>
<a href="{% url 'taxi:car-delete' pk=car.id %}" class="btn btn-danger">Delete</a>
</li>
{% endfor %}
</ul>
Expand Down
11 changes: 11 additions & 0 deletions templates/taxi/manufacturer_confirm_delete.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{% extends "base.html" %}

{% block content %}
<h1>Delete Manufacturer</h1>
<p>Are you sure you want to delete "{{ object }}"?</p>
<form method="post">
{% csrf_token %}
<button type="submit" class="btn btn-danger">Delete</button>
<a href="{% url 'taxi:manufacturer-list' %}" class="btn btn-secondary">Cancel</a>
</form>
{% endblock %}
Loading