From 8e29a715a5d497da3981425c20c23f3c3711e6c2 Mon Sep 17 00:00:00 2001 From: Bartosz Karwacki Date: Sat, 15 Jan 2022 17:40:16 +0100 Subject: [PATCH] endpoint, frontend --- backend/backend/settings.py | 6 +- backend/cars/migrations/0001_initial.py | 27 ++++++++ backend/cars/models.py | 6 +- backend/cars/urls.py | 9 +-- backend/cars/utils.py | 25 +++++++ backend/cars/views.py | 32 ++++----- dev.env | 1 + frontend/package-lock.json | 32 +++++---- frontend/package.json | 1 + frontend/src/components/Search.vue | 89 +++++++++++++++---------- frontend/src/components/Table.vue | 12 ++-- frontend/src/store/index.js | 15 ++++- 12 files changed, 168 insertions(+), 87 deletions(-) create mode 100644 backend/cars/migrations/0001_initial.py create mode 100644 backend/cars/utils.py diff --git a/backend/backend/settings.py b/backend/backend/settings.py index 0df86be..3486fe2 100644 --- a/backend/backend/settings.py +++ b/backend/backend/settings.py @@ -50,6 +50,7 @@ INSTALLED_APPS = [ "corsheaders", "django_filters", # apps + 'cars' ] MIDDLEWARE = [ @@ -154,7 +155,4 @@ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" # CORS -CORS_ALLOWED_ORIGINS = env( - "ALLOWED_ORIGINS", - default="http://localhost:3000", -).split() +CORS_ALLOW_ALL_ORIGINS = True diff --git a/backend/cars/migrations/0001_initial.py b/backend/cars/migrations/0001_initial.py new file mode 100644 index 0000000..2e51cf3 --- /dev/null +++ b/backend/cars/migrations/0001_initial.py @@ -0,0 +1,27 @@ +# Generated by Django 3.2.9 on 2022-01-15 15:58 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Car', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('mark', models.CharField(max_length=150)), + ('model', models.CharField(max_length=150)), + ('mileage', models.PositiveIntegerField()), + ('production_year', models.PositiveSmallIntegerField()), + ('engine_capacity', models.DecimalField(decimal_places=2, max_digits=16)), + ('combustion', models.DecimalField(decimal_places=2, max_digits=16)), + ('price', models.DecimalField(decimal_places=2, max_digits=16)), + ], + ), + ] diff --git a/backend/cars/models.py b/backend/cars/models.py index 32e7ce3..60f60c8 100644 --- a/backend/cars/models.py +++ b/backend/cars/models.py @@ -5,9 +5,9 @@ class Car(models.Model): model = models.CharField(max_length=150) mileage = models.PositiveIntegerField() production_year = models.PositiveSmallIntegerField() - engine_capacity = models.DecimalField() - combustion = models.DecimalField() - price = models.DecimalField() + engine_capacity = models.DecimalField(decimal_places=2, max_digits=16) + combustion = models.DecimalField(decimal_places=2, max_digits=16) + price = models.DecimalField(decimal_places=2, max_digits=16) def __str__(self) -> str: return "Car" \ No newline at end of file diff --git a/backend/cars/urls.py b/backend/cars/urls.py index e144d6f..feaadf0 100644 --- a/backend/cars/urls.py +++ b/backend/cars/urls.py @@ -1,12 +1,7 @@ from django.urls import path, include -from rest_framework.routers import DefaultRouter -from .views import CarViews - -# Create a router and register our viewsets with it. -router = DefaultRouter() -router.register(r'cars', CarViews.as_view(), name="cars") +from .views import CarList # The API URLs are now determined automatically by the router. urlpatterns = [ - path('', include(router.urls)), + path('cars', CarList.as_view()), ] \ No newline at end of file diff --git a/backend/cars/utils.py b/backend/cars/utils.py new file mode 100644 index 0000000..7aa12bc --- /dev/null +++ b/backend/cars/utils.py @@ -0,0 +1,25 @@ +VALUES = ['low', 'mid', 'high'] + + +def production_year_to_value(production_year): + return VALUES[["Dawno", "Średnio", "Niedawno"].index(production_year)] + +def mileage_to_value(mileage): + return VALUES[["Niski", "Średni", "Duży"].index(mileage)] + +def engine_capacity_to_value(engine_capacity): + return VALUES[["Mała", "Średnia", "Ogromna"].index(engine_capacity)] + +def combustion_to_value(combustion): + return VALUES[["Niskie", "Średnie", "Wysokie"].index(combustion)] + + +def map_query_params(query_params): + values = {} + params = ['production_year', 'mileage', 'engine_capacity', 'combustion'] + funcs = [production_year_to_value, mileage_to_value, engine_capacity_to_value, combustion_to_value] + for param, func in zip(params, funcs): + if (query_param := query_params.get(param)): + values[param] = func(query_param) + return values + \ No newline at end of file diff --git a/backend/cars/views.py b/backend/cars/views.py index bd32589..9538698 100644 --- a/backend/cars/views.py +++ b/backend/cars/views.py @@ -1,19 +1,15 @@ -from rest_framework.views import APIView -from .models import Car +from rest_framework import generics from rest_framework.response import Response - - -class CarViews(APIView): - def get(self, request, format=None): - """ - Returns car list based on fuzzy_logic filters. - """ - combustion = request.query_params.get('combustion') - mileage = request.query_params.get('mileage') - production_year = request.query_params.get('production_year') - engine_capacity = request.query_params.get('engine_capacity') - - print(combustion, mileage, production_year, engine_capacity) - - cars = list(Car.objects.all()) - return Response(cars) \ No newline at end of file +from .models import Car +from .serializers import CarSerializer +from .utils import map_query_params +class CarList(generics.ListAPIView): + queryset = Car.objects.all() + serializer_class = CarSerializer + + + def list(self, request): + values = map_query_params(request.query_params) + queryset = self.get_queryset() + serializer = CarSerializer(queryset, many=True) + return Response(serializer.data) \ No newline at end of file diff --git a/dev.env b/dev.env index a6f2121..8bab705 100644 --- a/dev.env +++ b/dev.env @@ -1,3 +1,4 @@ SECRET_KEY=SECRET_KEY DEBUG=1 ALLOWED_HOSTS=localhost 127.0.0.1 +ALLOWED_ORIGINS=http://localhost:8080 http://127.0.01:8080 \ No newline at end of file diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 38efff5..7896405 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -7,6 +7,7 @@ "": { "version": "0.1.0", "dependencies": { + "axios": "^0.24.0", "core-js": "^3.6.5", "vue": "^2.6.11", "vue-router": "^3.2.0", @@ -2610,7 +2611,6 @@ "thread-loader": "^2.1.3", "url-loader": "^2.2.0", "vue-loader": "^15.9.2", - "vue-loader-v16": "npm:vue-loader@^16.1.0", "vue-style-loader": "^4.1.2", "webpack": "^4.0.0", "webpack-bundle-analyzer": "^3.8.0", @@ -3394,6 +3394,14 @@ "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", "dev": true }, + "node_modules/axios": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz", + "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==", + "dependencies": { + "follow-redirects": "^1.14.4" + } + }, "node_modules/babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", @@ -3711,7 +3719,6 @@ "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", - "fsevents": "^2.3.2", "graceful-fs": "^4.2.4", "jest-regex-util": "^27.0.6", "jest-serializer": "^27.0.6", @@ -4862,7 +4869,6 @@ "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", - "fsevents": "~2.3.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", @@ -7207,8 +7213,7 @@ "esprima": "^4.0.1", "estraverse": "^4.2.0", "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" + "optionator": "^0.8.1" }, "bin": { "escodegen": "bin/escodegen.js", @@ -8224,7 +8229,6 @@ "version": "1.14.5", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.5.tgz", "integrity": "sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==", - "dev": true, "engines": { "node": ">=4.0" } @@ -10509,7 +10513,6 @@ "@jest/types": "^24.9.0", "anymatch": "^2.0.0", "fb-watchman": "^2.0.0", - "fsevents": "^1.2.7", "graceful-fs": "^4.1.15", "invariant": "^2.2.4", "jest-serializer": "^24.9.0", @@ -18092,8 +18095,7 @@ "dependencies": { "chokidar": "^3.4.1", "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0", - "watchpack-chokidar2": "^2.0.1" + "neo-async": "^2.5.0" }, "optionalDependencies": { "watchpack-chokidar2": "^2.0.1" @@ -18467,7 +18469,6 @@ "anymatch": "^2.0.0", "async-each": "^1.0.1", "braces": "^2.3.2", - "fsevents": "^1.2.7", "glob-parent": "^3.1.0", "inherits": "^2.0.3", "is-binary-path": "^1.0.0", @@ -22093,6 +22094,14 @@ "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", "dev": true }, + "axios": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz", + "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==", + "requires": { + "follow-redirects": "^1.14.4" + } + }, "babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", @@ -26185,8 +26194,7 @@ "follow-redirects": { "version": "1.14.5", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.5.tgz", - "integrity": "sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==", - "dev": true + "integrity": "sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==" }, "for-in": { "version": "1.0.2", diff --git a/frontend/package.json b/frontend/package.json index 0193f14..132df9c 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -9,6 +9,7 @@ "lint": "vue-cli-service lint" }, "dependencies": { + "axios": "^0.24.0", "core-js": "^3.6.5", "vue": "^2.6.11", "vue-router": "^3.2.0", diff --git a/frontend/src/components/Search.vue b/frontend/src/components/Search.vue index 9bc58c3..b453fa4 100644 --- a/frontend/src/components/Search.vue +++ b/frontend/src/components/Search.vue @@ -1,48 +1,63 @@ diff --git a/frontend/src/components/Table.vue b/frontend/src/components/Table.vue index d40e9dc..3d9f4a8 100644 --- a/frontend/src/components/Table.vue +++ b/frontend/src/components/Table.vue @@ -2,13 +2,14 @@ - + diff --git a/frontend/src/store/index.js b/frontend/src/store/index.js index ba2f84a..b3c425d 100644 --- a/frontend/src/store/index.js +++ b/frontend/src/store/index.js @@ -4,8 +4,19 @@ import Vuex from "vuex"; Vue.use(Vuex); export default new Vuex.Store({ - state: {}, - mutations: {}, + state: { + cars: [] + }, + mutations: { + setCars(state, cars) { + state.cars = cars + } + }, + getters: { + getCars: state => { + return state.cars + } + }, actions: {}, modules: {}, });