Compare commits
5 Commits
4281941814
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 57c730a2cf | |||
| c55577e04e | |||
| 56a8b7afaa | |||
| 82ebef8465 | |||
| 5874c5299b |
3
Pipfile
3
Pipfile
@@ -7,8 +7,9 @@ name = "pypi"
|
|||||||
Django = "*"
|
Django = "*"
|
||||||
django-registration-redux = "*"
|
django-registration-redux = "*"
|
||||||
django-tailwind = "*"
|
django-tailwind = "*"
|
||||||
|
django-reversion = "*"
|
||||||
|
|
||||||
[dev-packages]
|
[dev-packages]
|
||||||
|
|
||||||
[requires]
|
[requires]
|
||||||
python_version = "3.8"
|
python_version = "3.10"
|
||||||
|
|||||||
59
Pipfile.lock
generated
59
Pipfile.lock
generated
@@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"_meta": {
|
"_meta": {
|
||||||
"hash": {
|
"hash": {
|
||||||
"sha256": "7c687a6bc97aa06b7d51dcb4f6b6115d9dec1ca067ebe7189c94a98dfe8c0c7b"
|
"sha256": "68bdb29cd524e36b810214289b254227c5f1ca9d18c311b7e49f9d4cd1f3e7e3"
|
||||||
},
|
},
|
||||||
"pipfile-spec": 6,
|
"pipfile-spec": 6,
|
||||||
"requires": {
|
"requires": {
|
||||||
"python_version": "3.8"
|
"python_version": "3.10"
|
||||||
},
|
},
|
||||||
"sources": [
|
"sources": [
|
||||||
{
|
{
|
||||||
@@ -18,48 +18,59 @@
|
|||||||
"default": {
|
"default": {
|
||||||
"asgiref": {
|
"asgiref": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:5ee950735509d04eb673bd7f7120f8fa1c9e2df495394992c73234d526907e17",
|
"sha256:71e68008da809b957b7ee4b43dbccff33d1b23519fb8344e33f049897077afac",
|
||||||
"sha256:7162a3cb30ab0609f1a4c95938fd73e8604f63bdba516a7f7d64b83ff09478f0"
|
"sha256:9567dfe7bd8d3c8c892227827c41cce860b368104c3431da67a0c5a65a949506"
|
||||||
],
|
],
|
||||||
"version": "==3.3.1"
|
"markers": "python_version >= '3.7'",
|
||||||
|
"version": "==3.6.0"
|
||||||
},
|
},
|
||||||
"django": {
|
"django": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:169e2e7b4839a7910b393eec127fd7cbae62e80fa55f89c6510426abf673fe5f",
|
"sha256:066b6debb5ac335458d2a713ed995570536c8b59a580005acb0732378d5eb1ee",
|
||||||
"sha256:c6c0462b8b361f8691171af1fb87eceb4442da28477e12200c40420176206ba7"
|
"sha256:7efa6b1f781a6119a10ac94b4794ded90db8accbe7802281cd26f8664ffed59c"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==3.1.6"
|
"version": "==4.2.1"
|
||||||
|
},
|
||||||
|
"django-browser-reload": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:054ef5ce8b80f46e0beda1a3c847becdff51272cad6f2bda607e201a7afe7425",
|
||||||
|
"sha256:6db7e6c5807fff87e421b53926c50cfa3de0115e438f3c2de6103d3069557adb"
|
||||||
|
],
|
||||||
|
"markers": "python_version >= '3.7'",
|
||||||
|
"version": "==1.8.0"
|
||||||
},
|
},
|
||||||
"django-registration-redux": {
|
"django-registration-redux": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:e3d123354a1b8cbfa005d60f1ebb89ae8541f3eaffd6174d9f2aff529b57e430",
|
"sha256:2213bbe8732be72724034f4146f0255a7bd666eb5a5e1b2d8d8aa633fe8af894",
|
||||||
"sha256:e94b8a945e1cbfa9ec6c32b549597270405328d4e26651985d287d0211120691"
|
"sha256:56fbc7b01a7f0f48812fe4d4e0729d2dac916e16f8aaed36b3f10129f2df9d0f"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==2.9"
|
"version": "==2.12"
|
||||||
|
},
|
||||||
|
"django-reversion": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:a591cbce8621b5d036a37617554668b5ef2eb9777682e3af20b6401ee87cfbc5",
|
||||||
|
"sha256:c12bab452d31dd3c244456cf1df383acf14ba147cf99404c5e44412596de42fc"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==5.0.4"
|
||||||
},
|
},
|
||||||
"django-tailwind": {
|
"django-tailwind": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:2c1bf6c91fc54c844b85e8b379c211c971a2827c3d5b84f7e0464485ef9b8adf",
|
"sha256:c089b05b47d0e9d19567a81a74949fde16cbbfd8e4264c1f8eb4216a644065b2",
|
||||||
"sha256:d3aadba6aa046ead22efc68584b9ddccd0f25ccfbad433bb4727bee684a02177"
|
"sha256:dcc3b29463fff48a0e8ccd15c87fd467f0e746a7987bde0fdde6253dbb7861be"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==1.1.1"
|
"version": "==3.5.0"
|
||||||
},
|
|
||||||
"pytz": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da",
|
|
||||||
"sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798"
|
|
||||||
],
|
|
||||||
"version": "==2021.1"
|
|
||||||
},
|
},
|
||||||
"sqlparse": {
|
"sqlparse": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:017cde379adbd6a1f15a61873f43e8274179378e95ef3fede90b5aa64d304ed0",
|
"sha256:5430a4fe2ac7d0f93e66f1efc6e1338a41884b7ddf2a350cedd20ccc4d9d28f3",
|
||||||
"sha256:0f91fd2e829c44362cbcfab3e9ae12e22badaa8a29ad5ff599f9ec109f0454e8"
|
"sha256:d446183e84b8349fa3061f0fe7f06ca94ba65b426946ffebe6e3e8295332420c"
|
||||||
],
|
],
|
||||||
"version": "==0.4.1"
|
"markers": "python_version >= '3.5'",
|
||||||
|
"version": "==0.4.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"develop": {}
|
"develop": {}
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ https://docs.djangoproject.com/en/3.1/ref/settings/
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from django.forms.renderers import TemplatesSetting
|
||||||
|
|
||||||
|
|
||||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||||
@@ -35,6 +37,7 @@ if DEBUG:
|
|||||||
|
|
||||||
INSTALLED_APPS = [
|
INSTALLED_APPS = [
|
||||||
# Django
|
# Django
|
||||||
|
'django.forms',
|
||||||
'django.contrib.admin',
|
'django.contrib.admin',
|
||||||
'django.contrib.auth',
|
'django.contrib.auth',
|
||||||
'django.contrib.contenttypes',
|
'django.contrib.contenttypes',
|
||||||
@@ -44,6 +47,7 @@ INSTALLED_APPS = [
|
|||||||
# 3rd Party
|
# 3rd Party
|
||||||
'registration',
|
'registration',
|
||||||
'tailwind',
|
'tailwind',
|
||||||
|
'reversion',
|
||||||
# 1st Party
|
# 1st Party
|
||||||
'theme',
|
'theme',
|
||||||
'users',
|
'users',
|
||||||
@@ -53,6 +57,7 @@ INSTALLED_APPS = [
|
|||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
'django.middleware.security.SecurityMiddleware',
|
'django.middleware.security.SecurityMiddleware',
|
||||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||||
|
'reversion.middleware.RevisionMiddleware',
|
||||||
'django.middleware.common.CommonMiddleware',
|
'django.middleware.common.CommonMiddleware',
|
||||||
'django.middleware.csrf.CsrfViewMiddleware',
|
'django.middleware.csrf.CsrfViewMiddleware',
|
||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
@@ -65,7 +70,7 @@ ROOT_URLCONF = 'core.urls'
|
|||||||
TEMPLATES = [
|
TEMPLATES = [
|
||||||
{
|
{
|
||||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||||
'DIRS': [],
|
'DIRS': ['templates'],
|
||||||
'APP_DIRS': True,
|
'APP_DIRS': True,
|
||||||
'OPTIONS': {
|
'OPTIONS': {
|
||||||
'context_processors': [
|
'context_processors': [
|
||||||
@@ -131,3 +136,8 @@ USE_TZ = True
|
|||||||
|
|
||||||
STATIC_URL = '/static/'
|
STATIC_URL = '/static/'
|
||||||
TAILWIND_APP_NAME = 'theme'
|
TAILWIND_APP_NAME = 'theme'
|
||||||
|
|
||||||
|
class CustomFormRenderer(TemplatesSetting):
|
||||||
|
form_template_name = "custom_form.html"
|
||||||
|
|
||||||
|
FORM_RENDERER = "core.settings.CustomFormRenderer"
|
||||||
|
|||||||
@@ -2,7 +2,10 @@ from django.contrib import admin
|
|||||||
from django.urls import path
|
from django.urls import path
|
||||||
from django.conf.urls import include
|
from django.conf.urls import include
|
||||||
|
|
||||||
|
from . import views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
path('', views.Index.as_view(), name='index'),
|
||||||
path('user/', include('users.urls')),
|
path('user/', include('users.urls')),
|
||||||
path('vehicles/', include('vehicles.urls')),
|
path('vehicles/', include('vehicles.urls')),
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
|
|||||||
5
core/views.py
Normal file
5
core/views.py
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
from django.views import generic
|
||||||
|
|
||||||
|
|
||||||
|
class Index(generic.TemplateView):
|
||||||
|
template_name = 'index.html'
|
||||||
0
maintenance/__init__.py
Normal file
0
maintenance/__init__.py
Normal file
3
maintenance/admin.py
Normal file
3
maintenance/admin.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
# Register your models here.
|
||||||
5
maintenance/apps.py
Normal file
5
maintenance/apps.py
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class MaintenanceConfig(AppConfig):
|
||||||
|
name = 'maintenance'
|
||||||
0
maintenance/migrations/__init__.py
Normal file
0
maintenance/migrations/__init__.py
Normal file
3
maintenance/models.py
Normal file
3
maintenance/models.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
from django.db import models
|
||||||
|
|
||||||
|
# Create your models here.
|
||||||
3
maintenance/tests.py
Normal file
3
maintenance/tests.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
||||||
3
maintenance/views.py
Normal file
3
maintenance/views.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
from django.shortcuts import render
|
||||||
|
|
||||||
|
# Create your views here.
|
||||||
10
templates/index.html
Normal file
10
templates/index.html
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1 class="text-4xl center py-2 font-serif font-black">SUPERINTENDANT</h1>
|
||||||
|
<h2 class="text-3xl center py-2">Fleet Manager</h2>
|
||||||
|
<h3 class="text-2xl center italic py-2 pb-8 text-blue-400">Fljōtr - Swift (Old Norse)</h3>
|
||||||
|
<h2 class="text-2xl underline text-blue-100 py-2"><a href="{% url 'vehicle_list' %}"><svg style="width: 24px; height: 24px;" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
|
||||||
|
</svg>Vehicle List</a></h2>
|
||||||
|
{% endblock %}
|
||||||
183849
theme/static/css/styles.css
183849
theme/static/css/styles.css
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
6475
theme/static_src/package-lock.json
generated
Normal file
6475
theme/static_src/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -16,15 +16,19 @@
|
|||||||
"author": "",
|
"author": "",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"autoprefixer": "^10.0.2",
|
"@tailwindcss/aspect-ratio": "^0.4.2",
|
||||||
|
"@tailwindcss/forms": "^0.5.3",
|
||||||
|
"@tailwindcss/line-clamp": "^0.4.4",
|
||||||
|
"@tailwindcss/typography": "^0.5.9",
|
||||||
|
"autoprefixer": "^10.4.14",
|
||||||
"clean-css-cli": "^4.3.0",
|
"clean-css-cli": "^4.3.0",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"node-sass": "^5.0.0",
|
"node-sass": "^5.0.0",
|
||||||
"postcss": "^8.1.9",
|
"postcss": "^8.4.23",
|
||||||
"postcss-cli": "^8.3.0",
|
"postcss-cli": "^8.3.0",
|
||||||
"postcss-scss": "^3.0.4",
|
"postcss-scss": "^3.0.4",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"tailwindcss": "^2.0.1",
|
"tailwindcss": "^3.3.2",
|
||||||
"watch": "^1.0.2"
|
"watch": "^1.0.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
@tailwind base;
|
@tailwind base;
|
||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
|
input {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,14 +2,10 @@
|
|||||||
// If you need the full config, get it from here:
|
// If you need the full config, get it from here:
|
||||||
// https://unpkg.com/browse/tailwindcss@latest/stubs/defaultConfig.stub.js
|
// https://unpkg.com/browse/tailwindcss@latest/stubs/defaultConfig.stub.js
|
||||||
module.exports = {
|
module.exports = {
|
||||||
purge: [
|
content: [
|
||||||
// Templates within theme app (e.g. base.html)
|
|
||||||
'../templates/**/*.html',
|
'../templates/**/*.html',
|
||||||
// Templates in other apps. Uncomment the following line if it matches
|
|
||||||
// your project structure or change it to match.
|
|
||||||
'../../templates/**/*.html',
|
'../../templates/**/*.html',
|
||||||
],
|
],
|
||||||
darkMode: 'media',
|
|
||||||
theme: {
|
theme: {
|
||||||
extend: {},
|
extend: {},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -9,13 +9,13 @@
|
|||||||
<title>Fleet Management</title>
|
<title>Fleet Management</title>
|
||||||
<meta name="description" content="">
|
<meta name="description" content="">
|
||||||
<meta name="keywords" content="">
|
<meta name="keywords" content="">
|
||||||
<meta name="author" content="">
|
<meta name="author" content="FreneticScribbler">
|
||||||
|
|
||||||
<link rel="stylesheet" href="{% static 'css/styles.css' %}">
|
<link rel="stylesheet" href="{% static 'css/styles.css' %}">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="bg-grey-lightest font-serif leading-normal tracking-normal">
|
<body class="bg-gray-900 font-sans leading-normal tracking-normal">
|
||||||
<div class="container mx-auto">
|
<div class="container mx-auto text-white py-4 text-center">
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
3
theme/templates/custom_form.html
Normal file
3
theme/templates/custom_form.html
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{% for field in form %}
|
||||||
|
{{ field.label_tag }} {{ field }} <br/>
|
||||||
|
{% endfor %}
|
||||||
39
users/migrations/0002_driver_licence.py
Normal file
39
users/migrations/0002_driver_licence.py
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# Generated by Django 3.1.6 on 2021-02-14 12:44
|
||||||
|
|
||||||
|
import django.contrib.auth.models
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('users', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Licence',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('licence_number', models.CharField(max_length=100)),
|
||||||
|
('date_obtained', models.DateField()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Driver',
|
||||||
|
fields=[
|
||||||
|
('customuser_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='users.customuser')),
|
||||||
|
('licence', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.licence')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'user',
|
||||||
|
'verbose_name_plural': 'users',
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
bases=('users.customuser',),
|
||||||
|
managers=[
|
||||||
|
('objects', django.contrib.auth.models.UserManager()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
||||||
21
users/migrations/0003_driver_insurance.py
Normal file
21
users/migrations/0003_driver_insurance.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Generated by Django 3.1.6 on 2021-02-14 13:15
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('vehicles', '0003_auto_20210214_1315'),
|
||||||
|
('users', '0002_driver_licence'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='driver',
|
||||||
|
name='insurance',
|
||||||
|
field=models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, related_name='insurance', to='vehicles.insurancepolicy'),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -1,6 +1,18 @@
|
|||||||
from django.contrib.auth.models import AbstractUser
|
from django.contrib.auth.models import AbstractUser
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
# Create your models here.
|
|
||||||
class CustomUser(AbstractUser):
|
class CustomUser(AbstractUser):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Licence(models.Model):
|
||||||
|
licence_number = models.CharField(max_length=100)
|
||||||
|
date_obtained = models.DateField()
|
||||||
|
# entitlements
|
||||||
|
|
||||||
|
|
||||||
|
class Driver(CustomUser):
|
||||||
|
licence = models.ForeignKey('Licence', on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
insurance = models.ForeignKey('vehicles.InsurancePolicy', related_name='insurance', on_delete=models.CASCADE)
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
# Register your models here.
|
from vehicles.models import Make, Model, Status, Vehicle
|
||||||
|
|
||||||
|
admin.site.register(Make)
|
||||||
|
admin.site.register(Model)
|
||||||
|
admin.site.register(Status)
|
||||||
|
admin.site.register(Vehicle)
|
||||||
|
|||||||
47
vehicles/migrations/0002_auto_20210214_1244.py
Normal file
47
vehicles/migrations/0002_auto_20210214_1244.py
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
# Generated by Django 3.1.6 on 2021-02-14 12:44
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.utils.timezone import utc
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('vehicles', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='vehicle',
|
||||||
|
name='engine_number',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='vehicle',
|
||||||
|
name='date_purchased',
|
||||||
|
field=models.DateField(default=datetime.datetime(2021, 2, 14, 12, 44, 16, 378064, tzinfo=utc)),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='vehicle',
|
||||||
|
name='first_registered',
|
||||||
|
field=models.DateField(default=datetime.datetime(2021, 2, 14, 12, 44, 22, 562249, tzinfo=utc)),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='vehicle',
|
||||||
|
name='yom',
|
||||||
|
field=models.DateField(default=datetime.datetime(2021, 2, 14, 12, 44, 32, 354386, tzinfo=utc)),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='ICEVehicle',
|
||||||
|
fields=[
|
||||||
|
('vehicle_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='vehicles.vehicle')),
|
||||||
|
('engine_number', models.CharField(max_length=50)),
|
||||||
|
('capacity', models.IntegerField()),
|
||||||
|
],
|
||||||
|
bases=('vehicles.vehicle',),
|
||||||
|
),
|
||||||
|
]
|
||||||
50
vehicles/migrations/0003_auto_20210214_1315.py
Normal file
50
vehicles/migrations/0003_auto_20210214_1315.py
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
# Generated by Django 3.1.6 on 2021-02-14 13:15
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.utils.timezone import utc
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('vehicles', '0002_auto_20210214_1244'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='InsurancePolicy',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('expires', models.DateField()),
|
||||||
|
('company', models.CharField(max_length=20)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='vehicle',
|
||||||
|
name='mot_expires',
|
||||||
|
field=models.DateField(default=datetime.datetime(2021, 2, 14, 13, 15, 32, 868514, tzinfo=utc)),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='vehicle',
|
||||||
|
name='tax_expires',
|
||||||
|
field=models.DateField(default=datetime.datetime(2021, 2, 14, 13, 15, 37, 180671, tzinfo=utc)),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='MotorcycleInsurancePolicy',
|
||||||
|
fields=[
|
||||||
|
('insurancepolicy_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='vehicles.insurancepolicy')),
|
||||||
|
('ride_other_bikes', models.BooleanField(default=False)),
|
||||||
|
('pillion', models.BooleanField(default=False)),
|
||||||
|
],
|
||||||
|
bases=('vehicles.insurancepolicy',),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='insurancepolicy',
|
||||||
|
name='vehicle',
|
||||||
|
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='vehicles.vehicle'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -1,26 +1,65 @@
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
|
from reversion import revisions as reversion
|
||||||
|
|
||||||
|
|
||||||
class Status(models.Model):
|
class Status(models.Model):
|
||||||
name = models.CharField(max_length=80)
|
name = models.CharField(max_length=80)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
class Make(models.Model):
|
class Make(models.Model):
|
||||||
name = models.CharField(max_length=80)
|
name = models.CharField(max_length=80)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
class Model(models.Model): # Cause that won't be a confusing name at all
|
class Model(models.Model): # Cause that won't be a confusing name at all
|
||||||
name = models.CharField(max_length=80)
|
name = models.CharField(max_length=80)
|
||||||
make = models.ForeignKey('Make', on_delete=models.CASCADE)
|
make = models.ForeignKey('Make', on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "{} {}".format(self.make.name, self.name)
|
||||||
|
|
||||||
|
|
||||||
|
@reversion.register
|
||||||
class Vehicle(models.Model):
|
class Vehicle(models.Model):
|
||||||
name = models.CharField(max_length=50)
|
name = models.CharField(max_length=50)
|
||||||
|
# color
|
||||||
|
|
||||||
|
yom = models.DateField(verbose_name="Year of Manufacture")
|
||||||
|
first_registered = models.DateField()
|
||||||
|
date_purchased = models.DateField()
|
||||||
|
|
||||||
reg_number = models.CharField(max_length=7)
|
reg_number = models.CharField(max_length=7)
|
||||||
vin_number = models.CharField(max_length=50)
|
vin_number = models.CharField(max_length=50)
|
||||||
chassis_number = models.CharField(max_length=50)
|
chassis_number = models.CharField(max_length=50)
|
||||||
engine_number = models.CharField(max_length=50)
|
|
||||||
|
|
||||||
status = models.ForeignKey('Status', on_delete=models.CASCADE)
|
status = models.ForeignKey('Status', on_delete=models.CASCADE)
|
||||||
owner = models.ForeignKey('users.CustomUser', blank=True, null=True, on_delete=models.CASCADE)
|
owner = models.ForeignKey('users.CustomUser', blank=True, null=True, on_delete=models.CASCADE)
|
||||||
model = models.ForeignKey('Model', on_delete=models.CASCADE)
|
model = models.ForeignKey('Model', on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
tax_expires = models.DateField()
|
||||||
|
mot_expires = models.DateField()
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
|
class ICEVehicle(Vehicle):
|
||||||
|
engine_number = models.CharField(max_length=50)
|
||||||
|
capacity = models.IntegerField()
|
||||||
|
|
||||||
|
|
||||||
|
class InsurancePolicy(models.Model):
|
||||||
|
vehicle = models.OneToOneField('Vehicle', on_delete=models.CASCADE) # Not always one to one in practice
|
||||||
|
expires = models.DateField()
|
||||||
|
company = models.CharField(max_length=20)
|
||||||
|
|
||||||
|
|
||||||
|
class MotorcycleInsurancePolicy(InsurancePolicy):
|
||||||
|
ride_other_bikes = models.BooleanField(default=False)
|
||||||
|
pillion = models.BooleanField(default=False)
|
||||||
|
|||||||
20
vehicles/templates/vehicle_detail.html
Normal file
20
vehicles/templates/vehicle_detail.html
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1 class="text-2xl">Vehicle: <span class="font-bold">{{ object }}</span></h1>
|
||||||
|
<div class="bg-yellow-400 text-black font-black rounded text-xl p-2 w-1/12 m-2 center">{{ object.reg_number|slice:"4:" }} {{ object.reg_number|slice:":3" }}</div>
|
||||||
|
<div class="flex flex-nowrap">
|
||||||
|
<div class="border w-1/3 bg-green-800">
|
||||||
|
<h4 class="font-bold">Tax:</h4>
|
||||||
|
Valid until {{ object.tax_expires }}
|
||||||
|
</div>
|
||||||
|
<div class="border w-1/3 bg-green-800">
|
||||||
|
<h4 class="font-bold">MOT:</h4>
|
||||||
|
Valid until {{ object.mot_expires }}
|
||||||
|
</div>
|
||||||
|
<div class="border w-1/3 bg-green-800">
|
||||||
|
<h4 class="font-bold">Insurance:</h4>
|
||||||
|
Valid until {{ object.insurance.expires }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
9
vehicles/templates/vehicle_form.html
Normal file
9
vehicles/templates/vehicle_form.html
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<form action="{% url 'vehicle_create' %}" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form }}
|
||||||
|
<input type="submit" value="Submit">
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
@@ -1,5 +1,37 @@
|
|||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
Test!
|
<h1 class="text-2xl py-3 font-bold">All Vehicles</h1>
|
||||||
|
<table class="table-auto border w-full">
|
||||||
|
<thead>
|
||||||
|
<th class="p-2">Name</th>
|
||||||
|
<th class="p-2">Make & Model</th>
|
||||||
|
<th class="p-2">Registration</th>
|
||||||
|
<th class="p-2">Owner</th>
|
||||||
|
<th class="p-2">Status</th>
|
||||||
|
<th class="p-2">VIN Number</th>
|
||||||
|
<th class="p-2">Engine Number</th>
|
||||||
|
<th class="p-2">Chassis Number</th>
|
||||||
|
<th class="p-2">Links</th>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for object in object_list %}
|
||||||
|
<tr>
|
||||||
|
<th scope="row" class="p-2">{{ object.name }}</th>
|
||||||
|
<td class="p-2">{{ object.model }}</td>
|
||||||
|
<td class="bg-yellow-400 text-black font-black rounded text-xl px-2">{{ object.reg_number|slice:"4:" }} {{ object.reg_number|slice:":3" }}</td>
|
||||||
|
<td class="p-2">{{ object.owner|default:"God" }}</td>
|
||||||
|
<td class="p-2">{{ object.status }}</td>
|
||||||
|
<td class="p-2">{{ object.vin_number|default:"Unknown" }}</td>
|
||||||
|
<td class="p-2">{{ object.engine_number|default:"Unknown" }}</td>
|
||||||
|
<td class="p-2">{{ object.chassis_number|default:"Unknown" }}</td>
|
||||||
|
<td class="p-2"><a href="{% url 'vehicle_detail' object.pk %}" class="underline text-blue-100">Detail</a></td>
|
||||||
|
</tr>
|
||||||
|
{% empty %}
|
||||||
|
<tr class="bg-yellow-400">
|
||||||
|
<td span="10">Nothing found!</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
from .views import VehicleList
|
from . import views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('list/', VehicleList.as_view(), name='vehicle_list')
|
path('list/', views.VehicleList.as_view(), name='vehicle_list'),
|
||||||
|
path('<int:pk>/', views.VehicleDetail.as_view(), name='vehicle_detail'),
|
||||||
|
path('create/', views.VehicleCreate.as_view(), name='vehicle_create'),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,9 +1,20 @@
|
|||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.views.generic.list import ListView
|
from django.views import generic
|
||||||
|
|
||||||
from .models import Vehicle
|
from .models import Vehicle
|
||||||
|
|
||||||
|
|
||||||
class VehicleList(ListView):
|
class VehicleList(generic.ListView):
|
||||||
template_name = 'vehicle_list.html'
|
template_name = 'vehicle_list.html'
|
||||||
model = Vehicle
|
model = Vehicle
|
||||||
|
|
||||||
|
|
||||||
|
class VehicleDetail(generic.DetailView):
|
||||||
|
template_name = 'vehicle_detail.html'
|
||||||
|
model = Vehicle
|
||||||
|
|
||||||
|
|
||||||
|
class VehicleCreate(generic.CreateView):
|
||||||
|
template_name = 'vehicle_form.html'
|
||||||
|
model = Vehicle
|
||||||
|
fields = "__all__"
|
||||||
|
|||||||
Reference in New Issue
Block a user