Skip to content

Commit

Permalink
Solution
Browse files Browse the repository at this point in the history
  • Loading branch information
VladimirDolhyi committed Aug 14, 2024
1 parent 46d9023 commit 2c81596
Show file tree
Hide file tree
Showing 17 changed files with 182 additions and 124 deletions.
1 change: 1 addition & 0 deletions taxi/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class DriverAdmin(UserAdmin):

@admin.register(Car)
class CarAdmin(admin.ModelAdmin):
list_display = ["model", "manufacturer", ]
search_fields = ("model",)
list_filter = ("manufacturer",)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,63 +1,65 @@
# Generated by Django 4.0.2 on 2022-03-24 06:38

from django.conf import settings
import django.contrib.auth.models
import django.contrib.auth.validators
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone


class Migration(migrations.Migration):

initial = True

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

operations = [
migrations.CreateModel(
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)),
('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',
},
managers=[
('objects', django.contrib.auth.models.UserManager()),
],
),
migrations.CreateModel(
name='Manufacturer',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255)),
('country', models.CharField(max_length=255)),
],
),
migrations.CreateModel(
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')),
],
),
]
# Generated by Django 4.1 on 2024-08-14 12:27

from django.conf import settings
import django.contrib.auth.models
import django.contrib.auth.validators
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone


class Migration(migrations.Migration):

replaces = [('taxi', '0001_initial')]

initial = True

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

operations = [
migrations.CreateModel(
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 registration.', verbose_name='active')),
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
('license_number', models.CharField(max_length=255)),
('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',
},
managers=[
('objects', django.contrib.auth.models.UserManager()),
],
),
migrations.CreateModel(
name='Manufacturer',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255)),
('country', models.CharField(max_length=255)),
],
),
migrations.CreateModel(
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')),
],
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Generated by Django 4.1 on 2024-08-14 14:44

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('taxi', '0001_squashed_0001_initial'),
]

operations = [
migrations.AlterModelOptions(
name='car',
options={'ordering': ('model',)},
),
migrations.AlterModelOptions(
name='driver',
options={'ordering': ('username',), 'verbose_name': 'driver', 'verbose_name_plural': 'drivers'},
),
migrations.AlterModelOptions(
name='manufacturer',
options={'ordering': ['name']},
),
migrations.AlterField(
model_name='car',
name='manufacturer',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='cars', to='taxi.manufacturer'),
),
migrations.AlterField(
model_name='driver',
name='is_active',
field=models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active'),
),
migrations.AlterField(
model_name='driver',
name='license_number',
field=models.CharField(max_length=255, unique=True),
),
migrations.AlterField(
model_name='manufacturer',
name='name',
field=models.CharField(max_length=255, unique=True),
),
]
22 changes: 0 additions & 22 deletions taxi/migrations/0002_alter_manufacturer_options_and_more.py

This file was deleted.

18 changes: 0 additions & 18 deletions taxi/migrations/0003_alter_manufacturer_name.py

This file was deleted.

21 changes: 15 additions & 6 deletions taxi/models.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from django.conf import settings
from django.db import models
from django.contrib.auth.models import AbstractUser

Expand All @@ -10,24 +11,32 @@ class Meta:
ordering = ["name"]

def __str__(self):
return f"{self.name} {self.country}"
return f"{self.name}, {self.country}"


class Driver(AbstractUser):
license_number = models.CharField(max_length=255, unique=True)

class Meta:
ordering = ("username",)
verbose_name = "driver"
verbose_name_plural = "drivers"

def __str__(self):
return f"{self.username} ({self.first_name} {self.last_name})"
return f"{self.username}: ({self.first_name} {self.last_name})"


class Car(models.Model):
model = models.CharField(max_length=255)
manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE)
drivers = models.ManyToManyField(Driver, related_name="cars")
manufacturer = models.ForeignKey(
Manufacturer, on_delete=models.CASCADE, related_name="cars"
)
drivers = models.ManyToManyField(
settings.AUTH_USER_MODEL, related_name="cars"
)

def __str__(self):
return self.model
class Meta:
ordering = ("model",)

def __str__(self) -> str:
return f"{self.model}, {self.manufacturer.country}"
20 changes: 13 additions & 7 deletions taxi/views.py
Original file line number Diff line number Diff line change
@@ -1,47 +1,53 @@
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpRequest, HttpResponse
from django.shortcuts import render
from django.views import generic

from .models import Driver, Car, Manufacturer


def index(request):
@login_required
def index(request: HttpRequest) -> HttpResponse:
"""View function for the home page of the site."""

num_drivers = Driver.objects.count()
num_cars = Car.objects.count()
num_manufacturers = Manufacturer.objects.count()

num_visits = request.session.get("num_visits", 0)
request.session["num_visits"] = num_visits + 1
context = {
"num_drivers": num_drivers,
"num_cars": num_cars,
"num_manufacturers": num_manufacturers,
"num_visits": num_visits + 1
}

return render(request, "taxi/index.html", context=context)


class ManufacturerListView(generic.ListView):
class ManufacturerListView(LoginRequiredMixin, generic.ListView):
model = Manufacturer
context_object_name = "manufacturer_list"
template_name = "taxi/manufacturer_list.html"
paginate_by = 5


class CarListView(generic.ListView):
class CarListView(LoginRequiredMixin, generic.ListView):
model = Car
paginate_by = 5
queryset = Car.objects.select_related("manufacturer")


class CarDetailView(generic.DetailView):
class CarDetailView(LoginRequiredMixin, generic.DetailView):
model = Car


class DriverListView(generic.ListView):
class DriverListView(LoginRequiredMixin, generic.ListView):
model = Driver
paginate_by = 5


class DriverDetailView(generic.DetailView):
class DriverDetailView(LoginRequiredMixin, generic.DetailView):
model = Driver
queryset = Driver.objects.prefetch_related("cars__manufacturer")
2 changes: 2 additions & 0 deletions taxi_service/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,5 @@
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

LOGIN_REDIRECT_URL = "/taxi/"
1 change: 1 addition & 0 deletions taxi_service/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@
urlpatterns = [
path("admin/", admin.site.urls),
path("", include("taxi.urls", namespace="taxi")),
path("accounts/", include("django.contrib.auth.urls")),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
6 changes: 3 additions & 3 deletions templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2"
crossorigin="anonymous">
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2"
crossorigin="anonymous">
<!-- Add additional CSS in static file -->
{% load static %}
<link rel="stylesheet" href="{% static 'css/styles.css' %}">
Expand Down
7 changes: 7 additions & 0 deletions templates/includes/sidebar.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
<ul class="sidebar-nav">
{% if user.is_authenticated %}
<li><a href="{% url "taxi:driver-detail" pk=user.id %}">User: {{ user.username }}</a></li>
<li><a href="{% url 'logout' %}">Logout</a></li>
{% else %}
<li><a href="{% url 'login' %}">Login</a></li>
{% endif %}
<br>
<li><a href="{% url "taxi:index" %}">Home page</a></li>
<li><a href="{% url "taxi:manufacturer-list" %}">Manufacturers</a></li>
<li><a href="{% url "taxi:car-list" %}">Cars</a></li>
Expand Down
6 changes: 6 additions & 0 deletions templates/registration/logged_out.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{% extends "base.html" %}

{% block content %}
<p>Logged out!</p>
<a href="{% url 'login' %}">Click here to login again.</a>
{% endblock %}
16 changes: 16 additions & 0 deletions templates/registration/login.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{% extends "base.html" %}

{% block content %}
<h1>Login</h1>

{% if form.errors %}
<p style="color: red">Invalid credentials</p>
{% endif %}

<form method="post" action="{% url 'login' %}">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit">
<input type="hidden" name="next" value="{{ next }}">
</form>
{% endblock %}
Loading

0 comments on commit 2c81596

Please sign in to comment.