From 2b9bec7d9524a631d65a06e655c6a532b56ee468 Mon Sep 17 00:00:00 2001
From: Leo Wang <97806370+leowang801@users.noreply.github.com>
Date: Sun, 15 Oct 2023 02:39:50 +0800
Subject: [PATCH 01/15] Create django.yml
---
.github/workflows/django.yml | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
create mode 100644 .github/workflows/django.yml
diff --git a/.github/workflows/django.yml b/.github/workflows/django.yml
new file mode 100644
index 0000000..f2c0f2a
--- /dev/null
+++ b/.github/workflows/django.yml
@@ -0,0 +1,30 @@
+name: Django CI
+
+on:
+ push:
+ branches: [ "main" ]
+ pull_request:
+ branches: [ "main" ]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+ strategy:
+ max-parallel: 4
+ matrix:
+ python-version: [3.7, 3.8, 3.9]
+
+ steps:
+ - uses: actions/checkout@v3
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v3
+ with:
+ python-version: ${{ matrix.python-version }}
+ - name: Install Dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install -r requirements.txt
+ - name: Run Tests
+ run: |
+ python manage.py test
From 09a54cfeb58fca21e2f3362a0cd384b46e1b0514 Mon Sep 17 00:00:00 2001
From: Lance Tan
Date: Sat, 21 Oct 2023 13:22:26 -0700
Subject: [PATCH 02/15] Add template
---
.github/workflows/backend/python.yml | 46 ++++++++++++++++++++++++++++
.github/workflows/build.yml | 15 +++++++++
.github/workflows/django.yml | 30 ------------------
3 files changed, 61 insertions(+), 30 deletions(-)
create mode 100644 .github/workflows/backend/python.yml
create mode 100644 .github/workflows/build.yml
delete mode 100644 .github/workflows/django.yml
diff --git a/.github/workflows/backend/python.yml b/.github/workflows/backend/python.yml
new file mode 100644
index 0000000..c6275f1
--- /dev/null
+++ b/.github/workflows/backend/python.yml
@@ -0,0 +1,46 @@
+name: Build Python and Django
+
+on:
+ workflow_call:
+ inputs:
+ python_version:
+ description: 'Python version'
+ type: string
+ default: '3.10'
+ secrets:
+ django_secret:
+ required: true
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Set up Python ${{ inputs.python_verison }}
+ uses: actions/setup-python@v3
+ with:
+ python-version: ${{ inputs.python_version }}
+
+ - name: Install pipenv
+ run: |
+ python -m pip install --upgrade pipenv wheel
+
+ - id: cache-pipenv
+ uses: actions/cache@v1
+ with:
+ path: ~/.local/share/virtualenvs
+ key: ${{ runner.os }}-pipenv-${{ hashFiles('**/Pipfile.lock') }}
+
+ - name: Install dependencies
+ if: steps.cache-pipenv.outputs.cache-hit != 'true'
+ run: |
+ pipenv install --deploy --dev
+
+ - name: Makes sure it runs
+ env:
+ SECRET_KEY: ${{ secrets.django_secret }}
+ run: |
+ pipenv run python manage.py check
+
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..7d2551e
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,15 @@
+name: Build Pipeline
+
+on:
+ push:
+ branches: [ main ]
+ pull_request:
+ branches: [ main ]
+ workflow_dispatch:
+
+jobs:
+ python:
+ uses: backend/python.yml
+ secrets:
+ django_secret: ${{ secrets.DJANGO_SECRET }}
+
diff --git a/.github/workflows/django.yml b/.github/workflows/django.yml
deleted file mode 100644
index f2c0f2a..0000000
--- a/.github/workflows/django.yml
+++ /dev/null
@@ -1,30 +0,0 @@
-name: Django CI
-
-on:
- push:
- branches: [ "main" ]
- pull_request:
- branches: [ "main" ]
-
-jobs:
- build:
-
- runs-on: ubuntu-latest
- strategy:
- max-parallel: 4
- matrix:
- python-version: [3.7, 3.8, 3.9]
-
- steps:
- - uses: actions/checkout@v3
- - name: Set up Python ${{ matrix.python-version }}
- uses: actions/setup-python@v3
- with:
- python-version: ${{ matrix.python-version }}
- - name: Install Dependencies
- run: |
- python -m pip install --upgrade pip
- pip install -r requirements.txt
- - name: Run Tests
- run: |
- python manage.py test
From bf234a66d8a4077ae91969d3e19542848570cd37 Mon Sep 17 00:00:00 2001
From: Lance Tan
Date: Sat, 21 Oct 2023 13:31:49 -0700
Subject: [PATCH 03/15] Fix path
---
.github/workflows/backend/python.yml | 4 ++--
.github/workflows/build.yml | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/backend/python.yml b/.github/workflows/backend/python.yml
index c6275f1..aa27493 100644
--- a/.github/workflows/backend/python.yml
+++ b/.github/workflows/backend/python.yml
@@ -16,10 +16,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Set up Python ${{ inputs.python_verison }}
- uses: actions/setup-python@v3
+ uses: actions/setup-python@v4
with:
python-version: ${{ inputs.python_version }}
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 7d2551e..23f28a5 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -9,7 +9,7 @@ on:
jobs:
python:
- uses: backend/python.yml
+ uses: ubclaunchpad/microvan/.github/workflows/backend/python.yml
secrets:
django_secret: ${{ secrets.DJANGO_SECRET }}
From d23c26558f4f8d0c33d746387fb43a55ab02da4f Mon Sep 17 00:00:00 2001
From: Lance Tan
Date: Sat, 21 Oct 2023 13:33:32 -0700
Subject: [PATCH 04/15] Fix the uses
---
.github/workflows/backend/python.yml | 2 --
.github/workflows/build.yml | 15 +++++++++++----
2 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/.github/workflows/backend/python.yml b/.github/workflows/backend/python.yml
index aa27493..2a8f2dc 100644
--- a/.github/workflows/backend/python.yml
+++ b/.github/workflows/backend/python.yml
@@ -16,8 +16,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
-
- name: Set up Python ${{ inputs.python_verison }}
uses: actions/setup-python@v4
with:
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 23f28a5..94b57f7 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -8,8 +8,15 @@ on:
workflow_dispatch:
jobs:
- python:
- uses: ubclaunchpad/microvan/.github/workflows/backend/python.yml
- secrets:
- django_secret: ${{ secrets.DJANGO_SECRET }}
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Check out code
+ uses: actions/checkout@v4
+
+ - name: Run Python workflow
+ uses: ubclaunchpad/microvan/.github/workflows/backend/python.yml@main
+ with:
+ django_secret: ${{ secrets.DJANGO_SECRET }}
From de7194c11a923c9bb893ce88fb516fdfb7d73a53 Mon Sep 17 00:00:00 2001
From: Lance Tan
Date: Sat, 21 Oct 2023 13:34:11 -0700
Subject: [PATCH 05/15] Change template to steps
---
.github/workflows/backend/python.yml | 48 +++++++++++++---------------
1 file changed, 22 insertions(+), 26 deletions(-)
diff --git a/.github/workflows/backend/python.yml b/.github/workflows/backend/python.yml
index 2a8f2dc..8763485 100644
--- a/.github/workflows/backend/python.yml
+++ b/.github/workflows/backend/python.yml
@@ -11,34 +11,30 @@ on:
django_secret:
required: true
-jobs:
- build:
- runs-on: ubuntu-latest
+steps:
+ - name: Set up Python ${{ inputs.python_verison }}
+ uses: actions/setup-python@v4
+ with:
+ python-version: ${{ inputs.python_version }}
- steps:
- - name: Set up Python ${{ inputs.python_verison }}
- uses: actions/setup-python@v4
- with:
- python-version: ${{ inputs.python_version }}
+ - name: Install pipenv
+ run: |
+ python -m pip install --upgrade pipenv wheel
- - name: Install pipenv
- run: |
- python -m pip install --upgrade pipenv wheel
+ - id: cache-pipenv
+ uses: actions/cache@v1
+ with:
+ path: ~/.local/share/virtualenvs
+ key: ${{ runner.os }}-pipenv-${{ hashFiles('**/Pipfile.lock') }}
- - id: cache-pipenv
- uses: actions/cache@v1
- with:
- path: ~/.local/share/virtualenvs
- key: ${{ runner.os }}-pipenv-${{ hashFiles('**/Pipfile.lock') }}
-
- - name: Install dependencies
- if: steps.cache-pipenv.outputs.cache-hit != 'true'
- run: |
- pipenv install --deploy --dev
+ - name: Install dependencies
+ if: steps.cache-pipenv.outputs.cache-hit != 'true'
+ run: |
+ pipenv install --deploy --dev
- - name: Makes sure it runs
- env:
- SECRET_KEY: ${{ secrets.django_secret }}
- run: |
- pipenv run python manage.py check
+ - name: Makes sure it runs
+ env:
+ SECRET_KEY: ${{ secrets.django_secret }}
+ run: |
+ pipenv run python manage.py check
From 75f88bf848b19c281aefc848af6669b274196645 Mon Sep 17 00:00:00 2001
From: Lance Tan
Date: Sat, 21 Oct 2023 13:35:41 -0700
Subject: [PATCH 06/15] Fix template
---
.github/workflows/backend/python.yml | 47 +++++++++++++++-------------
1 file changed, 25 insertions(+), 22 deletions(-)
diff --git a/.github/workflows/backend/python.yml b/.github/workflows/backend/python.yml
index 8763485..ebc1743 100644
--- a/.github/workflows/backend/python.yml
+++ b/.github/workflows/backend/python.yml
@@ -11,30 +11,33 @@ on:
django_secret:
required: true
-steps:
- - name: Set up Python ${{ inputs.python_verison }}
- uses: actions/setup-python@v4
- with:
- python-version: ${{ inputs.python_version }}
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Set up Python ${{ inputs.python_version }}
+ uses: actions/setup-python@v4
+ with:
+ python-version: ${{ inputs.python_version }}
- - name: Install pipenv
- run: |
- python -m pip install --upgrade pipenv wheel
+ - name: Install pipenv
+ run: |
+ python -m pip install --upgrade pipenv wheel
- - id: cache-pipenv
- uses: actions/cache@v1
- with:
- path: ~/.local/share/virtualenvs
- key: ${{ runner.os }}-pipenv-${{ hashFiles('**/Pipfile.lock') }}
+ - id: cache-pipenv
+ uses: actions/cache@v1
+ with:
+ path: ~/.local/share/virtualenvs
+ key: ${{ runner.os }}-pipenv-${{ hashFiles('**/Pipfile.lock') }}
- - name: Install dependencies
- if: steps.cache-pipenv.outputs.cache-hit != 'true'
- run: |
- pipenv install --deploy --dev
+ - name: Install dependencies
+ if: steps.cache-pipenv.outputs.cache-hit != 'true'
+ run: |
+ pipenv install --deploy --dev
- - name: Makes sure it runs
- env:
- SECRET_KEY: ${{ secrets.django_secret }}
- run: |
- pipenv run python manage.py check
+ - name: Makes sure it runs
+ env:
+ SECRET_KEY: ${{ secrets.django_secret }}
+ run: |
+ pipenv run python manage.py check
From 218217644249cbfbe8641191157281fc6538ad3b Mon Sep 17 00:00:00 2001
From: Lance Tan
Date: Sat, 21 Oct 2023 13:40:22 -0700
Subject: [PATCH 07/15] Fixed
---
.github/workflows/backend/python.yml | 8 ++++----
.github/workflows/build.yml | 17 ++++++++---------
2 files changed, 12 insertions(+), 13 deletions(-)
diff --git a/.github/workflows/backend/python.yml b/.github/workflows/backend/python.yml
index ebc1743..45161cc 100644
--- a/.github/workflows/backend/python.yml
+++ b/.github/workflows/backend/python.yml
@@ -14,9 +14,10 @@ on:
jobs:
build:
runs-on: ubuntu-latest
+
steps:
- name: Set up Python ${{ inputs.python_version }}
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v3
with:
python-version: ${{ inputs.python_version }}
@@ -25,7 +26,7 @@ jobs:
python -m pip install --upgrade pipenv wheel
- id: cache-pipenv
- uses: actions/cache@v1
+ uses: actions/cache@v3
with:
path: ~/.local/share/virtualenvs
key: ${{ runner.os }}-pipenv-${{ hashFiles('**/Pipfile.lock') }}
@@ -39,5 +40,4 @@ jobs:
env:
SECRET_KEY: ${{ secrets.django_secret }}
run: |
- pipenv run python manage.py check
-
+ pipenv run python manage.py check
\ No newline at end of file
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 94b57f7..b882e55 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -2,9 +2,9 @@ name: Build Pipeline
on:
push:
- branches: [ main ]
+ branches: [main]
pull_request:
- branches: [ main ]
+ branches: [main]
workflow_dispatch:
jobs:
@@ -12,11 +12,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- - name: Check out code
- uses: actions/checkout@v4
-
- - name: Run Python workflow
- uses: ubclaunchpad/microvan/.github/workflows/backend/python.yml@main
- with:
- django_secret: ${{ secrets.DJANGO_SECRET }}
+ - name: Check out code
+ uses: actions/checkout@v4
+ - name: Run Python workflow
+ uses: ./.github/workflows/backend/python.yml
+ with:
+ django_secret: ${{ secrets.DJANGO_SECRET }}
\ No newline at end of file
From 0c6aba41f6d688f3f990b2752c2254bb87be19c7 Mon Sep 17 00:00:00 2001
From: Lance Tan
Date: Sat, 21 Oct 2023 13:47:42 -0700
Subject: [PATCH 08/15] Remove template
---
.../{backend/python.yml => backend-ci.yml} | 23 ++++++++-----------
.github/workflows/build.yml | 21 -----------------
2 files changed, 10 insertions(+), 34 deletions(-)
rename .github/workflows/{backend/python.yml => backend-ci.yml} (63%)
delete mode 100644 .github/workflows/build.yml
diff --git a/.github/workflows/backend/python.yml b/.github/workflows/backend-ci.yml
similarity index 63%
rename from .github/workflows/backend/python.yml
rename to .github/workflows/backend-ci.yml
index 45161cc..25bfac3 100644
--- a/.github/workflows/backend/python.yml
+++ b/.github/workflows/backend-ci.yml
@@ -1,25 +1,22 @@
-name: Build Python and Django
+name: Build Pipeline for Python and Django
on:
- workflow_call:
- inputs:
- python_version:
- description: 'Python version'
- type: string
- default: '3.10'
- secrets:
- django_secret:
- required: true
+ push:
+ branches: [ main ]
+ pull_request:
+ branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- - name: Set up Python ${{ inputs.python_version }}
+ - uses: actions/checkout@v4
+
+ - name: Set up Python
uses: actions/setup-python@v3
with:
- python-version: ${{ inputs.python_version }}
+ python-version: '3.10'
- name: Install pipenv
run: |
@@ -38,6 +35,6 @@ jobs:
- name: Makes sure it runs
env:
- SECRET_KEY: ${{ secrets.django_secret }}
+ SECRET_KEY: ${{ secrets.DJANGO_SECRET }}
run: |
pipenv run python manage.py check
\ No newline at end of file
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
deleted file mode 100644
index b882e55..0000000
--- a/.github/workflows/build.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: Build Pipeline
-
-on:
- push:
- branches: [main]
- pull_request:
- branches: [main]
- workflow_dispatch:
-
-jobs:
- build:
- runs-on: ubuntu-latest
-
- steps:
- - name: Check out code
- uses: actions/checkout@v4
-
- - name: Run Python workflow
- uses: ./.github/workflows/backend/python.yml
- with:
- django_secret: ${{ secrets.DJANGO_SECRET }}
\ No newline at end of file
From 1b56aa2b7e6fec5acc5ff45a776d2de34b7c8fa6 Mon Sep 17 00:00:00 2001
From: Lance Tan
Date: Sat, 21 Oct 2023 13:56:26 -0700
Subject: [PATCH 09/15] add path
---
.github/workflows/backend-ci.yml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.github/workflows/backend-ci.yml b/.github/workflows/backend-ci.yml
index 25bfac3..48d937f 100644
--- a/.github/workflows/backend-ci.yml
+++ b/.github/workflows/backend-ci.yml
@@ -12,6 +12,8 @@ jobs:
steps:
- uses: actions/checkout@v4
+ with:
+ path: 'backend'
- name: Set up Python
uses: actions/setup-python@v3
From 99c4aab280e10b17515104af2e72b64f204f8000 Mon Sep 17 00:00:00 2001
From: Lance Tan
Date: Sat, 21 Oct 2023 13:58:22 -0700
Subject: [PATCH 10/15] Add default working directory
---
.github/workflows/backend-ci.yml | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/backend-ci.yml b/.github/workflows/backend-ci.yml
index 48d937f..fdf23cc 100644
--- a/.github/workflows/backend-ci.yml
+++ b/.github/workflows/backend-ci.yml
@@ -9,11 +9,13 @@ on:
jobs:
build:
runs-on: ubuntu-latest
+ defaults:
+ run:
+ shell: bash
+ working-directory: ./backend
steps:
- uses: actions/checkout@v4
- with:
- path: 'backend'
- name: Set up Python
uses: actions/setup-python@v3
From fb479c1401bef20f095ceed66de10dec03765ba3 Mon Sep 17 00:00:00 2001
From: Lance Tan
Date: Sat, 21 Oct 2023 16:39:49 -0700
Subject: [PATCH 11/15] Remove pre-commit
---
.github/workflows/backend-ci.yml | 10 +-
backend/Pipfile | 9 ++
backend/Pipfile.lock | 120 ++++++++++++++++++++-
backend/auction/apps.py | 4 +-
backend/auction/migrations/0001_initial.py | 34 +++---
backend/auction/models.py | 3 +
backend/bid/apps.py | 4 +-
backend/bid/migrations/0001_initial.py | 52 ++++++---
backend/bid/models.py | 5 +-
backend/core/asgi.py | 2 +-
backend/core/models.py | 7 +-
backend/core/settings.py | 74 ++++++-------
backend/core/urls.py | 2 +-
backend/core/wsgi.py | 2 +-
backend/manage.py | 4 +-
backend/tox.ini | 12 +++
backend/user/apps.py | 4 +-
backend/user/models.py | 16 +--
backend/vehicle/apps.py | 4 +-
backend/vehicle/migrations/0001_initial.py | 120 +++++++++++++++------
backend/vehicle/models.py | 7 +-
21 files changed, 367 insertions(+), 128 deletions(-)
create mode 100644 backend/tox.ini
diff --git a/.github/workflows/backend-ci.yml b/.github/workflows/backend-ci.yml
index fdf23cc..ef0bff2 100644
--- a/.github/workflows/backend-ci.yml
+++ b/.github/workflows/backend-ci.yml
@@ -37,8 +37,16 @@ jobs:
run: |
pipenv install --deploy --dev
+ - name: Run linting
+ run: |
+ pipenv run flake8
+
- name: Makes sure it runs
env:
SECRET_KEY: ${{ secrets.DJANGO_SECRET }}
run: |
- pipenv run python manage.py check
\ No newline at end of file
+ pipenv run python manage.py check
+
+ - name: Run tests
+ run: |
+ pipenv run python manage.py test
\ No newline at end of file
diff --git a/backend/Pipfile b/backend/Pipfile
index 7498a7b..09551d9 100644
--- a/backend/Pipfile
+++ b/backend/Pipfile
@@ -10,6 +10,15 @@ django-environ = ">=0.11.2"
psycopg2 = ">=2.9.9"
[dev-packages]
+flake8 = ">=6.1.0"
+isort = ">=5.12.0"
+black = ">=23.10.0"
[requires]
python_version = "3.10"
+
+[scripts]
+test = "python manage.py test"
+start = "python manage.py runserver"
+migrate = "python manage.py migrate"
+makemigrations = "python manage.py makemigrations"
diff --git a/backend/Pipfile.lock b/backend/Pipfile.lock
index 967b541..e52a4d8 100644
--- a/backend/Pipfile.lock
+++ b/backend/Pipfile.lock
@@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
- "sha256": "aabb292a0b3b876cee4c86b66a5b788d6d3afa03ad0d45d17e6ef2e714d9f126"
+ "sha256": "8f339dddb20c59384a08c804be30fe4b94ab6bea17190284007d3211c25308d2"
},
"pipfile-spec": 6,
"requires": {
@@ -24,6 +24,39 @@
"markers": "python_version >= '3.7'",
"version": "==3.7.2"
},
+ "black": {
+ "hashes": [
+ "sha256:0e232f24a337fed7a82c1185ae46c56c4a6167fb0fe37411b43e876892c76699",
+ "sha256:30b78ac9b54cf87bcb9910ee3d499d2bc893afd52495066c49d9ee6b21eee06e",
+ "sha256:31946ec6f9c54ed7ba431c38bc81d758970dd734b96b8e8c2b17a367d7908171",
+ "sha256:31b9f87b277a68d0e99d2905edae08807c007973eaa609da5f0c62def6b7c0bd",
+ "sha256:47c4510f70ec2e8f9135ba490811c071419c115e46f143e4dce2ac45afdcf4c9",
+ "sha256:481167c60cd3e6b1cb8ef2aac0f76165843a374346aeeaa9d86765fe0dd0318b",
+ "sha256:6901631b937acbee93c75537e74f69463adaf34379a04eef32425b88aca88a23",
+ "sha256:76baba9281e5e5b230c9b7f83a96daf67a95e919c2dfc240d9e6295eab7b9204",
+ "sha256:7fb5fc36bb65160df21498d5a3dd330af8b6401be3f25af60c6ebfe23753f747",
+ "sha256:960c21555be135c4b37b7018d63d6248bdae8514e5c55b71e994ad37407f45b8",
+ "sha256:a3c2ddb35f71976a4cfeca558848c2f2f89abc86b06e8dd89b5a65c1e6c0f22a",
+ "sha256:c870bee76ad5f7a5ea7bd01dc646028d05568d33b0b09b7ecfc8ec0da3f3f39c",
+ "sha256:d3d9129ce05b0829730323bdcb00f928a448a124af5acf90aa94d9aba6969604",
+ "sha256:db451a3363b1e765c172c3fd86213a4ce63fb8524c938ebd82919bf2a6e28c6a",
+ "sha256:e223b731a0e025f8ef427dd79d8cd69c167da807f5710add30cdf131f13dd62e",
+ "sha256:f20ff03f3fdd2fd4460b4f631663813e57dc277e37fb216463f3b907aa5a9bdd",
+ "sha256:f74892b4b836e5162aa0452393112a574dac85e13902c57dfbaaf388e4eda37c",
+ "sha256:f8dc7d50d94063cdfd13c82368afd8588bac4ce360e4224ac399e769d6704e98"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '3.8'",
+ "version": "==23.10.0"
+ },
+ "click": {
+ "hashes": [
+ "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28",
+ "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"
+ ],
+ "markers": "python_version >= '3.7'",
+ "version": "==8.1.7"
+ },
"django": {
"hashes": [
"sha256:08f41f468b63335aea0d904c5729e0250300f6a1907bf293a65499496cdbc68f",
@@ -51,6 +84,38 @@
"markers": "python_version >= '3.6'",
"version": "==3.14.0"
},
+ "mypy-extensions": {
+ "hashes": [
+ "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d",
+ "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"
+ ],
+ "markers": "python_version >= '3.5'",
+ "version": "==1.0.0"
+ },
+ "packaging": {
+ "hashes": [
+ "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5",
+ "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"
+ ],
+ "markers": "python_version >= '3.7'",
+ "version": "==23.2"
+ },
+ "pathspec": {
+ "hashes": [
+ "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20",
+ "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"
+ ],
+ "markers": "python_version >= '3.7'",
+ "version": "==0.11.2"
+ },
+ "platformdirs": {
+ "hashes": [
+ "sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3",
+ "sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e"
+ ],
+ "markers": "python_version >= '3.7'",
+ "version": "==3.11.0"
+ },
"psycopg2": {
"hashes": [
"sha256:121081ea2e76729acfb0673ff33755e8703d45e926e416cb59bae3a86c6a4981",
@@ -84,6 +149,14 @@
"markers": "python_version >= '3.5'",
"version": "==0.4.4"
},
+ "tomli": {
+ "hashes": [
+ "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc",
+ "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"
+ ],
+ "markers": "python_version < '3.11'",
+ "version": "==2.0.1"
+ },
"typing-extensions": {
"hashes": [
"sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0",
@@ -93,5 +166,48 @@
"version": "==4.8.0"
}
},
- "develop": {}
+ "develop": {
+ "flake8": {
+ "hashes": [
+ "sha256:d5b3857f07c030bdb5bf41c7f53799571d75c4491748a3adcd47de929e34cd23",
+ "sha256:ffdfce58ea94c6580c77888a86506937f9a1a227dfcd15f245d694ae20a6b6e5"
+ ],
+ "index": "pypi",
+ "markers": "python_full_version >= '3.8.1'",
+ "version": "==6.1.0"
+ },
+ "isort": {
+ "hashes": [
+ "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504",
+ "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"
+ ],
+ "index": "pypi",
+ "markers": "python_full_version >= '3.8.0'",
+ "version": "==5.12.0"
+ },
+ "mccabe": {
+ "hashes": [
+ "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325",
+ "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"
+ ],
+ "markers": "python_version >= '3.6'",
+ "version": "==0.7.0"
+ },
+ "pycodestyle": {
+ "hashes": [
+ "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f",
+ "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"
+ ],
+ "markers": "python_version >= '3.8'",
+ "version": "==2.11.1"
+ },
+ "pyflakes": {
+ "hashes": [
+ "sha256:4132f6d49cb4dae6819e5379898f2b8cce3c5f23994194c24b77d5da2e36f774",
+ "sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc"
+ ],
+ "markers": "python_version >= '3.8'",
+ "version": "==3.1.0"
+ }
+ }
}
diff --git a/backend/auction/apps.py b/backend/auction/apps.py
index 46cb478..a9df69d 100644
--- a/backend/auction/apps.py
+++ b/backend/auction/apps.py
@@ -2,5 +2,5 @@
class AuctionConfig(AppConfig):
- default_auto_field = 'django.db.models.BigAutoField'
- name = 'auction'
+ default_auto_field = "django.db.models.BigAutoField"
+ name = "auction"
diff --git a/backend/auction/migrations/0001_initial.py b/backend/auction/migrations/0001_initial.py
index f153ce1..871437b 100644
--- a/backend/auction/migrations/0001_initial.py
+++ b/backend/auction/migrations/0001_initial.py
@@ -1,29 +1,39 @@
# Generated by Django 4.2.5 on 2023-10-07 23:50
-from django.db import migrations, models
import uuid
+from django.db import migrations, models
-class Migration(migrations.Migration):
+class Migration(migrations.Migration):
initial = True
- dependencies = [
- ]
+ dependencies = []
operations = [
migrations.CreateModel(
- name='Auction',
+ name="Auction",
fields=[
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('identifier', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)),
- ('created_at', models.DateTimeField(editable=False)),
- ('updated_at', models.DateTimeField()),
- ('end_date', models.DateTimeField(editable=False)),
+ (
+ "id",
+ models.BigAutoField(
+ auto_created=True,
+ primary_key=True,
+ serialize=False,
+ verbose_name="ID",
+ ),
+ ),
+ (
+ "identifier",
+ models.UUIDField(default=uuid.uuid4, editable=False, unique=True),
+ ),
+ ("created_at", models.DateTimeField(editable=False)),
+ ("updated_at", models.DateTimeField()),
+ ("end_date", models.DateTimeField(editable=False)),
],
options={
- 'ordering': ['-created_at'],
- 'abstract': False,
+ "ordering": ["-created_at"],
+ "abstract": False,
},
),
]
diff --git a/backend/auction/models.py b/backend/auction/models.py
index b07373c..3ee02d6 100644
--- a/backend/auction/models.py
+++ b/backend/auction/models.py
@@ -1,7 +1,10 @@
from django.db import models
+
from core.models import MainModel
from user.models import User
from vehicle.models import Vehicle
+
+
class Auction(MainModel):
# start date is given by MainMode's created_at date
end_date = models.DateTimeField(editable=False)
diff --git a/backend/bid/apps.py b/backend/bid/apps.py
index 64250c0..8f7600f 100644
--- a/backend/bid/apps.py
+++ b/backend/bid/apps.py
@@ -2,5 +2,5 @@
class BidConfig(AppConfig):
- default_auto_field = 'django.db.models.BigAutoField'
- name = 'bid'
+ default_auto_field = "django.db.models.BigAutoField"
+ name = "bid"
diff --git a/backend/bid/migrations/0001_initial.py b/backend/bid/migrations/0001_initial.py
index 713e726..ce687ba 100644
--- a/backend/bid/migrations/0001_initial.py
+++ b/backend/bid/migrations/0001_initial.py
@@ -1,34 +1,56 @@
# Generated by Django 4.2.5 on 2023-10-07 23:50
-from django.db import migrations, models
-import django.db.models.deletion
import uuid
+import django.db.models.deletion
+from django.db import migrations, models
+
class Migration(migrations.Migration):
-
initial = True
dependencies = [
- ('user', '__first__'),
- ('vehicle', '0001_initial'),
+ ("user", "__first__"),
+ ("vehicle", "0001_initial"),
]
operations = [
migrations.CreateModel(
- name='Bid',
+ name="Bid",
fields=[
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('identifier', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)),
- ('created_at', models.DateTimeField(editable=False)),
- ('updated_at', models.DateTimeField()),
- ('amount', models.IntegerField()),
- ('bidder', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='user.user')),
- ('vehicle', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='vehicle.vehicle')),
+ (
+ "id",
+ models.BigAutoField(
+ auto_created=True,
+ primary_key=True,
+ serialize=False,
+ verbose_name="ID",
+ ),
+ ),
+ (
+ "identifier",
+ models.UUIDField(default=uuid.uuid4, editable=False, unique=True),
+ ),
+ ("created_at", models.DateTimeField(editable=False)),
+ ("updated_at", models.DateTimeField()),
+ ("amount", models.IntegerField()),
+ (
+ "bidder",
+ models.ForeignKey(
+ on_delete=django.db.models.deletion.PROTECT, to="user.user"
+ ),
+ ),
+ (
+ "vehicle",
+ models.ForeignKey(
+ on_delete=django.db.models.deletion.PROTECT,
+ to="vehicle.vehicle",
+ ),
+ ),
],
options={
- 'ordering': ['-created_at'],
- 'abstract': False,
+ "ordering": ["-created_at"],
+ "abstract": False,
},
),
]
diff --git a/backend/bid/models.py b/backend/bid/models.py
index 0e6aee8..d5f0f21 100644
--- a/backend/bid/models.py
+++ b/backend/bid/models.py
@@ -1,10 +1,11 @@
from django.db import models
-from django.db import models
+
from core.models import MainModel
from user.models import User
from vehicle.models import Vehicle
+
class Bid(MainModel):
amount = models.IntegerField(null=False)
vehicle = models.ForeignKey(Vehicle, on_delete=models.PROTECT)
- bidder = models.ForeignKey(User, on_delete=models.PROTECT)
\ No newline at end of file
+ bidder = models.ForeignKey(User, on_delete=models.PROTECT)
diff --git a/backend/core/asgi.py b/backend/core/asgi.py
index 6e9eda7..361ea22 100644
--- a/backend/core/asgi.py
+++ b/backend/core/asgi.py
@@ -11,6 +11,6 @@
from django.core.asgi import get_asgi_application
-os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings')
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "core.settings")
application = get_asgi_application()
diff --git a/backend/core/models.py b/backend/core/models.py
index cc61bc3..bafb1c8 100644
--- a/backend/core/models.py
+++ b/backend/core/models.py
@@ -6,9 +6,10 @@
class MainModel(models.Model):
"""
- The skeleton for all models, will provide three unique fields
- that every model should have. All models should extend this.
+ The skeleton for all models, will provide three unique fields
+ that every model should have. All models should extend this.
"""
+
identifier = models.UUIDField(unique=True, default=uuid.uuid4, editable=False)
created_at = models.DateTimeField(editable=False)
updated_at = models.DateTimeField()
@@ -19,7 +20,7 @@ class Meta:
def save(self, *args, **kwargs):
date = timezone.now()
- if not self.id and self.created_at is None:
+ if not self.id and self.created_at is None:
self.created_at = date
self.updated_at = date
diff --git a/backend/core/settings.py b/backend/core/settings.py
index 7b657e2..b27644a 100644
--- a/backend/core/settings.py
+++ b/backend/core/settings.py
@@ -12,6 +12,7 @@
import os
from pathlib import Path
+
import environ
# Reads environment variables
@@ -29,7 +30,6 @@
SECRET_KEY = env("SECRET_KEY")
-
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
@@ -39,12 +39,12 @@
# Application definition
INSTALLED_APPS = [
- 'django.contrib.admin',
- 'django.contrib.auth',
- 'django.contrib.contenttypes',
- 'django.contrib.sessions',
- 'django.contrib.messages',
- 'django.contrib.staticfiles',
+ "django.contrib.admin",
+ "django.contrib.auth",
+ "django.contrib.contenttypes",
+ "django.contrib.sessions",
+ "django.contrib.messages",
+ "django.contrib.staticfiles",
"rest_framework",
"core",
"auction",
@@ -54,44 +54,44 @@
]
MIDDLEWARE = [
- 'django.middleware.security.SecurityMiddleware',
- 'django.contrib.sessions.middleware.SessionMiddleware',
- 'django.middleware.common.CommonMiddleware',
- 'django.middleware.csrf.CsrfViewMiddleware',
- 'django.contrib.auth.middleware.AuthenticationMiddleware',
- 'django.contrib.messages.middleware.MessageMiddleware',
- 'django.middleware.clickjacking.XFrameOptionsMiddleware',
+ "django.middleware.security.SecurityMiddleware",
+ "django.contrib.sessions.middleware.SessionMiddleware",
+ "django.middleware.common.CommonMiddleware",
+ "django.middleware.csrf.CsrfViewMiddleware",
+ "django.contrib.auth.middleware.AuthenticationMiddleware",
+ "django.contrib.messages.middleware.MessageMiddleware",
+ "django.middleware.clickjacking.XFrameOptionsMiddleware",
]
-ROOT_URLCONF = 'core.urls'
+ROOT_URLCONF = "core.urls"
TEMPLATES = [
{
- 'BACKEND': 'django.template.backends.django.DjangoTemplates',
- 'DIRS': [],
- 'APP_DIRS': True,
- 'OPTIONS': {
- 'context_processors': [
- 'django.template.context_processors.debug',
- 'django.template.context_processors.request',
- 'django.contrib.auth.context_processors.auth',
- 'django.contrib.messages.context_processors.messages',
+ "BACKEND": "django.template.backends.django.DjangoTemplates",
+ "DIRS": [],
+ "APP_DIRS": True,
+ "OPTIONS": {
+ "context_processors": [
+ "django.template.context_processors.debug",
+ "django.template.context_processors.request",
+ "django.contrib.auth.context_processors.auth",
+ "django.contrib.messages.context_processors.messages",
],
},
},
]
-WSGI_APPLICATION = 'core.wsgi.application'
+WSGI_APPLICATION = "core.wsgi.application"
# Database
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases
""""""
DATABASES = {
- 'default': {
- 'ENGINE': 'django.db.backends.sqlite3',
- 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
- },
+ "default": {
+ "ENGINE": "django.db.backends.sqlite3",
+ "NAME": os.path.join(BASE_DIR, "db.sqlite3"),
+ },
}
"""
@@ -110,16 +110,16 @@
AUTH_PASSWORD_VALIDATORS = [
{
- 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
+ "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
},
{
- 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+ "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
},
{
- 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
+ "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
},
{
- 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
+ "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
},
]
@@ -127,9 +127,9 @@
# Internationalization
# https://docs.djangoproject.com/en/4.2/topics/i18n/
-LANGUAGE_CODE = 'en-us'
+LANGUAGE_CODE = "en-us"
-TIME_ZONE = 'UTC'
+TIME_ZONE = "UTC"
USE_I18N = True
@@ -139,9 +139,9 @@
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.2/howto/static-files/
-STATIC_URL = 'static/'
+STATIC_URL = "static/"
# Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
-DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
+DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
diff --git a/backend/core/urls.py b/backend/core/urls.py
index 97def4c..86ddbdd 100644
--- a/backend/core/urls.py
+++ b/backend/core/urls.py
@@ -18,5 +18,5 @@
from django.urls import path
urlpatterns = [
- path('admin/', admin.site.urls),
+ path("admin/", admin.site.urls),
]
diff --git a/backend/core/wsgi.py b/backend/core/wsgi.py
index fba1d91..5762abd 100644
--- a/backend/core/wsgi.py
+++ b/backend/core/wsgi.py
@@ -11,6 +11,6 @@
from django.core.wsgi import get_wsgi_application
-os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings')
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "core.settings")
application = get_wsgi_application()
diff --git a/backend/manage.py b/backend/manage.py
index f2a662c..4e20ce5 100755
--- a/backend/manage.py
+++ b/backend/manage.py
@@ -6,7 +6,7 @@
def main():
"""Run administrative tasks."""
- os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings')
+ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "core.settings")
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
@@ -18,5 +18,5 @@ def main():
execute_from_command_line(sys.argv)
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/backend/tox.ini b/backend/tox.ini
new file mode 100644
index 0000000..8e4a014
--- /dev/null
+++ b/backend/tox.ini
@@ -0,0 +1,12 @@
+[flake8]
+exclude = static,assets,logs,media,tests,templates,*/migrations/*.py,urls.py,settings.py,Pipfile,Pipfile.lock
+max-line-length = 88
+ignore = F401
+
+[tool:black]
+line-length = 88
+
+[isort]
+skip = static,assets,logs,media,tests,templates,docs,migrations,Pipfile,Pipfile.lock
+not_skip = __init__.py
+multi_line_output = 4
\ No newline at end of file
diff --git a/backend/user/apps.py b/backend/user/apps.py
index 36cce4c..578292c 100644
--- a/backend/user/apps.py
+++ b/backend/user/apps.py
@@ -2,5 +2,5 @@
class UserConfig(AppConfig):
- default_auto_field = 'django.db.models.BigAutoField'
- name = 'user'
+ default_auto_field = "django.db.models.BigAutoField"
+ name = "user"
diff --git a/backend/user/models.py b/backend/user/models.py
index b550c4d..f2d7e82 100644
--- a/backend/user/models.py
+++ b/backend/user/models.py
@@ -1,15 +1,19 @@
from django.db import models
+
from core.models import MainModel
+
+
# Create your models here.
class User(MainModel):
"""
- The model used for handling users, this includes bidders and admins.
- A user will become a bidder if their manytomanyfield contains the
- auction in question. An auction will have many bidders, and a bidder
- will be in many auctions.
+ The model used for handling users, this includes bidders and admins.
+ A user will become a bidder if their manytomanyfield contains the
+ auction in question. An auction will have many bidders, and a bidder
+ will be in many auctions.
+
-
"""
+
name = models.CharField(max_length=150, null=False)
email = models.CharField(max_length=150, null=False)
- auction = models.ManyToManyField('auction.Auction', related_name='auction')
\ No newline at end of file
+ auction = models.ManyToManyField("auction.Auction", related_name="auction")
diff --git a/backend/vehicle/apps.py b/backend/vehicle/apps.py
index ca2fef4..f4ca26d 100644
--- a/backend/vehicle/apps.py
+++ b/backend/vehicle/apps.py
@@ -2,5 +2,5 @@
class VehicleConfig(AppConfig):
- default_auto_field = 'django.db.models.BigAutoField'
- name = 'vehicle'
+ default_auto_field = "django.db.models.BigAutoField"
+ name = "vehicle"
diff --git a/backend/vehicle/migrations/0001_initial.py b/backend/vehicle/migrations/0001_initial.py
index d52427d..12fc4b0 100644
--- a/backend/vehicle/migrations/0001_initial.py
+++ b/backend/vehicle/migrations/0001_initial.py
@@ -1,66 +1,116 @@
# Generated by Django 4.2.5 on 2023-10-07 23:50
-from django.db import migrations, models
-import django.db.models.deletion
import uuid
+import django.db.models.deletion
+from django.db import migrations, models
+
class Migration(migrations.Migration):
-
initial = True
dependencies = [
- ('auction', '0001_initial'),
+ ("auction", "0001_initial"),
]
operations = [
migrations.CreateModel(
- name='Brand',
+ name="Brand",
fields=[
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('identifier', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)),
- ('created_at', models.DateTimeField(editable=False)),
- ('updated_at', models.DateTimeField()),
- ('name', models.CharField(max_length=150)),
+ (
+ "id",
+ models.BigAutoField(
+ auto_created=True,
+ primary_key=True,
+ serialize=False,
+ verbose_name="ID",
+ ),
+ ),
+ (
+ "identifier",
+ models.UUIDField(default=uuid.uuid4, editable=False, unique=True),
+ ),
+ ("created_at", models.DateTimeField(editable=False)),
+ ("updated_at", models.DateTimeField()),
+ ("name", models.CharField(max_length=150)),
],
options={
- 'ordering': ['-created_at'],
- 'abstract': False,
+ "ordering": ["-created_at"],
+ "abstract": False,
},
),
migrations.CreateModel(
- name='VehicleType',
+ name="VehicleType",
fields=[
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('identifier', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)),
- ('created_at', models.DateTimeField(editable=False)),
- ('updated_at', models.DateTimeField()),
- ('name', models.CharField(max_length=150)),
+ (
+ "id",
+ models.BigAutoField(
+ auto_created=True,
+ primary_key=True,
+ serialize=False,
+ verbose_name="ID",
+ ),
+ ),
+ (
+ "identifier",
+ models.UUIDField(default=uuid.uuid4, editable=False, unique=True),
+ ),
+ ("created_at", models.DateTimeField(editable=False)),
+ ("updated_at", models.DateTimeField()),
+ ("name", models.CharField(max_length=150)),
],
options={
- 'ordering': ['-created_at'],
- 'abstract': False,
+ "ordering": ["-created_at"],
+ "abstract": False,
},
),
migrations.CreateModel(
- name='Vehicle',
+ name="Vehicle",
fields=[
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('identifier', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)),
- ('created_at', models.DateTimeField(editable=False)),
- ('updated_at', models.DateTimeField()),
- ('date', models.DateTimeField(editable=False)),
- ('asking_price', models.IntegerField()),
- ('description', models.CharField(max_length=2000)),
- ('unicode_id', models.IntegerField()),
- ('model_number', models.IntegerField()),
- ('auction', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='auction.auction')),
- ('brand', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='vehicle.brand')),
- ('vehicle_type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='vehicle.vehicletype')),
+ (
+ "id",
+ models.BigAutoField(
+ auto_created=True,
+ primary_key=True,
+ serialize=False,
+ verbose_name="ID",
+ ),
+ ),
+ (
+ "identifier",
+ models.UUIDField(default=uuid.uuid4, editable=False, unique=True),
+ ),
+ ("created_at", models.DateTimeField(editable=False)),
+ ("updated_at", models.DateTimeField()),
+ ("date", models.DateTimeField(editable=False)),
+ ("asking_price", models.IntegerField()),
+ ("description", models.CharField(max_length=2000)),
+ ("unicode_id", models.IntegerField()),
+ ("model_number", models.IntegerField()),
+ (
+ "auction",
+ models.ForeignKey(
+ on_delete=django.db.models.deletion.PROTECT,
+ to="auction.auction",
+ ),
+ ),
+ (
+ "brand",
+ models.ForeignKey(
+ on_delete=django.db.models.deletion.PROTECT, to="vehicle.brand"
+ ),
+ ),
+ (
+ "vehicle_type",
+ models.ForeignKey(
+ on_delete=django.db.models.deletion.PROTECT,
+ to="vehicle.vehicletype",
+ ),
+ ),
],
options={
- 'ordering': ['-created_at'],
- 'abstract': False,
+ "ordering": ["-created_at"],
+ "abstract": False,
},
),
]
diff --git a/backend/vehicle/models.py b/backend/vehicle/models.py
index dc37312..2259656 100644
--- a/backend/vehicle/models.py
+++ b/backend/vehicle/models.py
@@ -1,13 +1,16 @@
from django.db import models
+
from core.models import MainModel
+
class Brand(MainModel):
name = models.CharField(max_length=150, null=False)
-
+
class VehicleType(MainModel):
name = models.CharField(max_length=150, null=False)
-
+
+
class Vehicle(MainModel):
date = models.DateTimeField(editable=False)
asking_price = models.IntegerField(null=False)
From 69716e0b7fa7c9d52271e559a3d2a60e043dcd88 Mon Sep 17 00:00:00 2001
From: Lance Tan
Date: Sat, 21 Oct 2023 16:40:55 -0700
Subject: [PATCH 12/15] Update Pipfile.lock
---
backend/Pipfile.lock | 156 +++++++++++++++++++++++--------------------
1 file changed, 82 insertions(+), 74 deletions(-)
diff --git a/backend/Pipfile.lock b/backend/Pipfile.lock
index e52a4d8..309822d 100644
--- a/backend/Pipfile.lock
+++ b/backend/Pipfile.lock
@@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
- "sha256": "8f339dddb20c59384a08c804be30fe4b94ab6bea17190284007d3211c25308d2"
+ "sha256": "f957e36f17fd5e450c735c18856ee3c9f33219ee524bec76c3796c5b6c190f68"
},
"pipfile-spec": 6,
"requires": {
@@ -24,39 +24,6 @@
"markers": "python_version >= '3.7'",
"version": "==3.7.2"
},
- "black": {
- "hashes": [
- "sha256:0e232f24a337fed7a82c1185ae46c56c4a6167fb0fe37411b43e876892c76699",
- "sha256:30b78ac9b54cf87bcb9910ee3d499d2bc893afd52495066c49d9ee6b21eee06e",
- "sha256:31946ec6f9c54ed7ba431c38bc81d758970dd734b96b8e8c2b17a367d7908171",
- "sha256:31b9f87b277a68d0e99d2905edae08807c007973eaa609da5f0c62def6b7c0bd",
- "sha256:47c4510f70ec2e8f9135ba490811c071419c115e46f143e4dce2ac45afdcf4c9",
- "sha256:481167c60cd3e6b1cb8ef2aac0f76165843a374346aeeaa9d86765fe0dd0318b",
- "sha256:6901631b937acbee93c75537e74f69463adaf34379a04eef32425b88aca88a23",
- "sha256:76baba9281e5e5b230c9b7f83a96daf67a95e919c2dfc240d9e6295eab7b9204",
- "sha256:7fb5fc36bb65160df21498d5a3dd330af8b6401be3f25af60c6ebfe23753f747",
- "sha256:960c21555be135c4b37b7018d63d6248bdae8514e5c55b71e994ad37407f45b8",
- "sha256:a3c2ddb35f71976a4cfeca558848c2f2f89abc86b06e8dd89b5a65c1e6c0f22a",
- "sha256:c870bee76ad5f7a5ea7bd01dc646028d05568d33b0b09b7ecfc8ec0da3f3f39c",
- "sha256:d3d9129ce05b0829730323bdcb00f928a448a124af5acf90aa94d9aba6969604",
- "sha256:db451a3363b1e765c172c3fd86213a4ce63fb8524c938ebd82919bf2a6e28c6a",
- "sha256:e223b731a0e025f8ef427dd79d8cd69c167da807f5710add30cdf131f13dd62e",
- "sha256:f20ff03f3fdd2fd4460b4f631663813e57dc277e37fb216463f3b907aa5a9bdd",
- "sha256:f74892b4b836e5162aa0452393112a574dac85e13902c57dfbaaf388e4eda37c",
- "sha256:f8dc7d50d94063cdfd13c82368afd8588bac4ce360e4224ac399e769d6704e98"
- ],
- "index": "pypi",
- "markers": "python_version >= '3.8'",
- "version": "==23.10.0"
- },
- "click": {
- "hashes": [
- "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28",
- "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"
- ],
- "markers": "python_version >= '3.7'",
- "version": "==8.1.7"
- },
"django": {
"hashes": [
"sha256:08f41f468b63335aea0d904c5729e0250300f6a1907bf293a65499496cdbc68f",
@@ -84,38 +51,6 @@
"markers": "python_version >= '3.6'",
"version": "==3.14.0"
},
- "mypy-extensions": {
- "hashes": [
- "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d",
- "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"
- ],
- "markers": "python_version >= '3.5'",
- "version": "==1.0.0"
- },
- "packaging": {
- "hashes": [
- "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5",
- "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"
- ],
- "markers": "python_version >= '3.7'",
- "version": "==23.2"
- },
- "pathspec": {
- "hashes": [
- "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20",
- "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"
- ],
- "markers": "python_version >= '3.7'",
- "version": "==0.11.2"
- },
- "platformdirs": {
- "hashes": [
- "sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3",
- "sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e"
- ],
- "markers": "python_version >= '3.7'",
- "version": "==3.11.0"
- },
"psycopg2": {
"hashes": [
"sha256:121081ea2e76729acfb0673ff33755e8703d45e926e416cb59bae3a86c6a4981",
@@ -149,14 +84,6 @@
"markers": "python_version >= '3.5'",
"version": "==0.4.4"
},
- "tomli": {
- "hashes": [
- "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc",
- "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"
- ],
- "markers": "python_version < '3.11'",
- "version": "==2.0.1"
- },
"typing-extensions": {
"hashes": [
"sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0",
@@ -167,6 +94,39 @@
}
},
"develop": {
+ "black": {
+ "hashes": [
+ "sha256:0e232f24a337fed7a82c1185ae46c56c4a6167fb0fe37411b43e876892c76699",
+ "sha256:30b78ac9b54cf87bcb9910ee3d499d2bc893afd52495066c49d9ee6b21eee06e",
+ "sha256:31946ec6f9c54ed7ba431c38bc81d758970dd734b96b8e8c2b17a367d7908171",
+ "sha256:31b9f87b277a68d0e99d2905edae08807c007973eaa609da5f0c62def6b7c0bd",
+ "sha256:47c4510f70ec2e8f9135ba490811c071419c115e46f143e4dce2ac45afdcf4c9",
+ "sha256:481167c60cd3e6b1cb8ef2aac0f76165843a374346aeeaa9d86765fe0dd0318b",
+ "sha256:6901631b937acbee93c75537e74f69463adaf34379a04eef32425b88aca88a23",
+ "sha256:76baba9281e5e5b230c9b7f83a96daf67a95e919c2dfc240d9e6295eab7b9204",
+ "sha256:7fb5fc36bb65160df21498d5a3dd330af8b6401be3f25af60c6ebfe23753f747",
+ "sha256:960c21555be135c4b37b7018d63d6248bdae8514e5c55b71e994ad37407f45b8",
+ "sha256:a3c2ddb35f71976a4cfeca558848c2f2f89abc86b06e8dd89b5a65c1e6c0f22a",
+ "sha256:c870bee76ad5f7a5ea7bd01dc646028d05568d33b0b09b7ecfc8ec0da3f3f39c",
+ "sha256:d3d9129ce05b0829730323bdcb00f928a448a124af5acf90aa94d9aba6969604",
+ "sha256:db451a3363b1e765c172c3fd86213a4ce63fb8524c938ebd82919bf2a6e28c6a",
+ "sha256:e223b731a0e025f8ef427dd79d8cd69c167da807f5710add30cdf131f13dd62e",
+ "sha256:f20ff03f3fdd2fd4460b4f631663813e57dc277e37fb216463f3b907aa5a9bdd",
+ "sha256:f74892b4b836e5162aa0452393112a574dac85e13902c57dfbaaf388e4eda37c",
+ "sha256:f8dc7d50d94063cdfd13c82368afd8588bac4ce360e4224ac399e769d6704e98"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '3.8'",
+ "version": "==23.10.0"
+ },
+ "click": {
+ "hashes": [
+ "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28",
+ "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"
+ ],
+ "markers": "python_version >= '3.7'",
+ "version": "==8.1.7"
+ },
"flake8": {
"hashes": [
"sha256:d5b3857f07c030bdb5bf41c7f53799571d75c4491748a3adcd47de929e34cd23",
@@ -193,6 +153,38 @@
"markers": "python_version >= '3.6'",
"version": "==0.7.0"
},
+ "mypy-extensions": {
+ "hashes": [
+ "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d",
+ "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"
+ ],
+ "markers": "python_version >= '3.5'",
+ "version": "==1.0.0"
+ },
+ "packaging": {
+ "hashes": [
+ "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5",
+ "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"
+ ],
+ "markers": "python_version >= '3.7'",
+ "version": "==23.2"
+ },
+ "pathspec": {
+ "hashes": [
+ "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20",
+ "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"
+ ],
+ "markers": "python_version >= '3.7'",
+ "version": "==0.11.2"
+ },
+ "platformdirs": {
+ "hashes": [
+ "sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3",
+ "sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e"
+ ],
+ "markers": "python_version >= '3.7'",
+ "version": "==3.11.0"
+ },
"pycodestyle": {
"hashes": [
"sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f",
@@ -208,6 +200,22 @@
],
"markers": "python_version >= '3.8'",
"version": "==3.1.0"
+ },
+ "tomli": {
+ "hashes": [
+ "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc",
+ "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"
+ ],
+ "markers": "python_version < '3.11'",
+ "version": "==2.0.1"
+ },
+ "typing-extensions": {
+ "hashes": [
+ "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0",
+ "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"
+ ],
+ "markers": "python_version < '3.11'",
+ "version": "==4.8.0"
}
}
}
From 6e6ed6ed1a757de2330f179d93775c03bb5f19b8 Mon Sep 17 00:00:00 2001
From: Lance Tan
Date: Sat, 21 Oct 2023 16:43:13 -0700
Subject: [PATCH 13/15] Fix pipeline
---
.github/workflows/backend-ci.yml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.github/workflows/backend-ci.yml b/.github/workflows/backend-ci.yml
index ef0bff2..f2da7cb 100644
--- a/.github/workflows/backend-ci.yml
+++ b/.github/workflows/backend-ci.yml
@@ -48,5 +48,7 @@ jobs:
pipenv run python manage.py check
- name: Run tests
+ env:
+ SECRET_KEY: ${{ secrets.DJANGO_SECRET }}
run: |
pipenv run python manage.py test
\ No newline at end of file
From 8377a1a8956eca3ab1505d74dde5a8c4f408462f Mon Sep 17 00:00:00 2001
From: Lance Tan
Date: Sat, 21 Oct 2023 17:07:19 -0700
Subject: [PATCH 14/15] Readme
---
README.md | 88 ++++++++++++++++++++++++++++++++++-
frontend/public/LogoIcon.png | Bin 0 -> 71007 bytes
2 files changed, 87 insertions(+), 1 deletion(-)
create mode 100644 frontend/public/LogoIcon.png
diff --git a/README.md b/README.md
index e28ae45..133d701 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,87 @@
-# microvan
\ No newline at end of file
+# Microvan Inc.
+
+
+
+
+
+
+
Labby
+
+
+
+
+ Table of Contents
+
+ -
+ About The Project
+
+
+ -
+ Getting Started
+
+
+ - Deployment
+ - Contributing
+
+
+
+
+
+## About The Project
+
+BC Cancer Lab Management System
+
+
+### Built With
+
+* React JS - Frontend
+* Express JS - Backend
+* MySQL - Database
+* AWS - Hosting
+
+
+
+## Getting Started
+
+To get a local copy up and running follow these simple steps.
+
+### Prerequisites
+
+* yarn
+
+### Installation
+#### Express Backend
+
+1. `cd` into backend folder
+2. run `yarn start`
+
+Backend will be exposed on port 3000
+
+#### React Frontend
+
+1. `cd` into frontend folder
+2. run `yarn` to install dependencies
+3. run `yarn start`
+
+#### Docker Setup
+1. run `docker-compose up --build -d`
+
+
+## Deployment
+
+TODO
+
+
+## Contributing
+
+Contributions are what make the community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**.
+
+1. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
+2. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)
+3. Push to the Branch (`git push origin feature/AmazingFeature`)
+4. Open a Pull Request
\ No newline at end of file
diff --git a/frontend/public/LogoIcon.png b/frontend/public/LogoIcon.png
new file mode 100644
index 0000000000000000000000000000000000000000..8438d3f44c9dc63c49a9dba379741716a11c90b6
GIT binary patch
literal 71007
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