From fd5caada23b4f8d50c8a2ea5b169a04f183f3c25 Mon Sep 17 00:00:00 2001 From: Timofey Date: Thu, 15 May 2025 19:34:32 +0300 Subject: [PATCH] create sitemanagement project and dynamic faqs --- backend/Pipfile | 1 + backend/Pipfile.lock | 90 +++++++++++++- backend/api/main/serializers.py | 2 +- backend/api/main/views.py | 2 +- backend/base/settings.py | 31 +---- backend/base/urls.py | 16 --- backend/routes/admin.py | 5 +- backend/routes/constants/__init__.py | 6 + backend/routes/migrations/0001_initial.py | 56 +++++++++ backend/routes/migrations/0002_route.py | 39 ++++++ backend/routes/models.py | 113 +++++++++++++++++- .../{mainpage => sitemanagement}/__init__.py | 0 backend/{mainpage => sitemanagement}/admin.py | 0 backend/{mainpage => sitemanagement}/apps.py | 4 +- .../migrations/0001_initial.py | 3 +- .../migrations/__init__.py | 0 .../{mainpage => sitemanagement}/models.py | 0 backend/{mainpage => sitemanagement}/tests.py | 0 18 files changed, 317 insertions(+), 51 deletions(-) create mode 100644 backend/routes/constants/__init__.py create mode 100644 backend/routes/migrations/0001_initial.py create mode 100644 backend/routes/migrations/0002_route.py rename backend/{mainpage => sitemanagement}/__init__.py (100%) rename backend/{mainpage => sitemanagement}/admin.py (100%) rename backend/{mainpage => sitemanagement}/apps.py (58%) rename backend/{mainpage => sitemanagement}/migrations/0001_initial.py (88%) rename backend/{mainpage => sitemanagement}/migrations/__init__.py (100%) rename backend/{mainpage => sitemanagement}/models.py (100%) rename backend/{mainpage => sitemanagement}/tests.py (100%) diff --git a/backend/Pipfile b/backend/Pipfile index 1353773..486997f 100644 --- a/backend/Pipfile +++ b/backend/Pipfile @@ -8,6 +8,7 @@ django = "*" djangorestframework = "*" python-dotenv = "*" psycopg2 = "*" +pillow = "*" [dev-packages] diff --git a/backend/Pipfile.lock b/backend/Pipfile.lock index 2bb3134..671f725 100644 --- a/backend/Pipfile.lock +++ b/backend/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "b373803326406c6ad8118054bb515b95be11d1fba2e9252d0914839e5c6ed309" + "sha256": "8058db5f6e1f333af30cffe6634e7d018110d8c2fc6601f3a9c84a72c2ac3110" }, "pipfile-spec": 6, "requires": { @@ -42,6 +42,94 @@ "markers": "python_version >= '3.9'", "version": "==3.16.0" }, + "pillow": { + "hashes": [ + "sha256:014ca0050c85003620526b0ac1ac53f56fc93af128f7546623cc8e31875ab928", + "sha256:036e53f4170e270ddb8797d4c590e6dd14d28e15c7da375c18978045f7e6c37b", + "sha256:062b7a42d672c45a70fa1f8b43d1d38ff76b63421cbbe7f88146b39e8a558d91", + "sha256:0c3e6d0f59171dfa2e25d7116217543310908dfa2770aa64b8f87605f8cacc97", + "sha256:0c7b29dbd4281923a2bfe562acb734cee96bbb129e96e6972d315ed9f232bef4", + "sha256:0f5c7eda47bf8e3c8a283762cab94e496ba977a420868cb819159980b6709193", + "sha256:127bf6ac4a5b58b3d32fc8289656f77f80567d65660bc46f72c0d77e6600cc95", + "sha256:14e33b28bf17c7a38eede290f77db7c664e4eb01f7869e37fa98a5aa95978941", + "sha256:14f73f7c291279bd65fda51ee87affd7c1e097709f7fdd0188957a16c264601f", + "sha256:191955c55d8a712fab8934a42bfefbf99dd0b5875078240943f913bb66d46d9f", + "sha256:1d535df14716e7f8776b9e7fee118576d65572b4aad3ed639be9e4fa88a1cad3", + "sha256:208653868d5c9ecc2b327f9b9ef34e0e42a4cdd172c2988fd81d62d2bc9bc044", + "sha256:21e1470ac9e5739ff880c211fc3af01e3ae505859392bf65458c224d0bf283eb", + "sha256:225c832a13326e34f212d2072982bb1adb210e0cc0b153e688743018c94a2681", + "sha256:25a5f306095c6780c52e6bbb6109624b95c5b18e40aab1c3041da3e9e0cd3e2d", + "sha256:2728567e249cdd939f6cc3d1f049595c66e4187f3c34078cbc0a7d21c47482d2", + "sha256:2b490402c96f907a166615e9a5afacf2519e28295f157ec3a2bb9bd57de638cb", + "sha256:312c77b7f07ab2139924d2639860e084ec2a13e72af54d4f08ac843a5fc9c79d", + "sha256:31df6e2d3d8fc99f993fd253e97fae451a8db2e7207acf97859732273e108406", + "sha256:35ca289f712ccfc699508c4658a1d14652e8033e9b69839edf83cbdd0ba39e70", + "sha256:3692b68c87096ac6308296d96354eddd25f98740c9d2ab54e1549d6c8aea9d79", + "sha256:36d6b82164c39ce5482f649b437382c0fb2395eabc1e2b1702a6deb8ad647d6e", + "sha256:39ad2e0f424394e3aebc40168845fee52df1394a4673a6ee512d840d14ab3013", + "sha256:3e645b020f3209a0181a418bffe7b4a93171eef6c4ef6cc20980b30bebf17b7d", + "sha256:3fe735ced9a607fee4f481423a9c36701a39719252a9bb251679635f99d0f7d2", + "sha256:4b835d89c08a6c2ee7781b8dd0a30209a8012b5f09c0a665b65b0eb3560b6f36", + "sha256:4d375eb838755f2528ac8cbc926c3e31cc49ca4ad0cf79cff48b20e30634a4a7", + "sha256:4eb92eca2711ef8be42fd3f67533765d9fd043b8c80db204f16c8ea62ee1a751", + "sha256:5119225c622403afb4b44bad4c1ca6c1f98eed79db8d3bc6e4e160fc6339d66c", + "sha256:562d11134c97a62fe3af29581f083033179f7ff435f78392565a1ad2d1c2c45c", + "sha256:598174aef4589af795f66f9caab87ba4ff860ce08cd5bb447c6fc553ffee603c", + "sha256:63b5dff3a68f371ea06025a1a6966c9a1e1ee452fc8020c2cd0ea41b83e9037b", + "sha256:6ebce70c3f486acf7591a3d73431fa504a4e18a9b97ff27f5f47b7368e4b9dd1", + "sha256:738db0e0941ca0376804d4de6a782c005245264edaa253ffce24e5a15cbdc7bd", + "sha256:7491cf8a79b8eb867d419648fff2f83cb0b3891c8b36da92cc7f1931d46108c8", + "sha256:74ee3d7ecb3f3c05459ba95eed5efa28d6092d751ce9bf20e3e253a4e497e691", + "sha256:750f96efe0597382660d8b53e90dd1dd44568a8edb51cb7f9d5d918b80d4de14", + "sha256:78092232a4ab376a35d68c4e6d5e00dfd73454bd12b230420025fbe178ee3b0b", + "sha256:78afba22027b4accef10dbd5eed84425930ba41b3ea0a86fa8d20baaf19d807f", + "sha256:7bdb5e09068332578214cadd9c05e3d64d99e0e87591be22a324bdbc18925be0", + "sha256:80f1df8dbe9572b4b7abdfa17eb5d78dd620b1d55d9e25f834efdbee872d3aed", + "sha256:85d27ea4c889342f7e35f6d56e7e1cb345632ad592e8c51b693d7b7556043ce0", + "sha256:8b02d8f9cb83c52578a0b4beadba92e37d83a4ef11570a8688bbf43f4ca50909", + "sha256:8ce2e8411c7aaef53e6bb29fe98f28cd4fbd9a1d9be2eeea434331aac0536b22", + "sha256:8f4f3724c068be008c08257207210c138d5f3731af6c155a81c2b09a9eb3a788", + "sha256:9622e3b6c1d8b551b6e6f21873bdcc55762b4b2126633014cea1803368a9aa16", + "sha256:9b7b0d4fd2635f54ad82785d56bc0d94f147096493a79985d0ab57aedd563156", + "sha256:9bc7ae48b8057a611e5fe9f853baa88093b9a76303937449397899385da06fad", + "sha256:9db98ab6565c69082ec9b0d4e40dd9f6181dab0dd236d26f7a50b8b9bfbd5076", + "sha256:9ee66787e095127116d91dea2143db65c7bb1e232f617aa5957c0d9d2a3f23a7", + "sha256:a0a6709b47019dff32e678bc12c63008311b82b9327613f534e496dacaefb71e", + "sha256:a64dd61998416367b7ef979b73d3a85853ba9bec4c2925f74e588879a58716b6", + "sha256:aa442755e31c64037aa7c1cb186e0b369f8416c567381852c63444dd666fb772", + "sha256:ad275964d52e2243430472fc5d2c2334b4fc3ff9c16cb0a19254e25efa03a155", + "sha256:b0e130705d568e2f43a17bcbe74d90958e8a16263868a12c3e0d9c8162690830", + "sha256:b10428b3416d4f9c61f94b494681280be7686bda15898a3a9e08eb66a6d92d67", + "sha256:b2dbea1012ccb784a65349f57bbc93730b96e85b42e9bf7b01ef40443db720b4", + "sha256:b4ba4be812c7a40280629e55ae0b14a0aafa150dd6451297562e1764808bbe61", + "sha256:b93a07e76d13bff9444f1a029e0af2964e654bfc2e2c2d46bfd080df5ad5f3d8", + "sha256:bf2c33d6791c598142f00c9c4c7d47f6476731c31081331664eb26d6ab583e01", + "sha256:c27476257b2fdcd7872d54cfd119b3a9ce4610fb85c8e32b70b42e3680a29a1e", + "sha256:c8bd62331e5032bc396a93609982a9ab6b411c05078a52f5fe3cc59234a3abd1", + "sha256:c97209e85b5be259994eb5b69ff50c5d20cca0f458ef9abd835e262d9d88b39d", + "sha256:cc1c3bc53befb6096b84165956e886b1729634a799e9d6329a0c512ab651e579", + "sha256:cc5d875d56e49f112b6def6813c4e3d3036d269c008bf8aef72cd08d20ca6df6", + "sha256:d189ba1bebfbc0c0e529159631ec72bb9e9bc041f01ec6d3233d6d82eb823bc1", + "sha256:d4e5c5edee874dce4f653dbe59db7c73a600119fbea8d31f53423586ee2aafd7", + "sha256:d57a75d53922fc20c165016a20d9c44f73305e67c351bbc60d1adaf662e74047", + "sha256:da3104c57bbd72948d75f6a9389e6727d2ab6333c3617f0a89d72d4940aa0443", + "sha256:dd6b20b93b3ccc9c1b597999209e4bc5cf2853f9ee66e3fc9a400a78733ffc9a", + "sha256:e0409af9f829f87a2dfb7e259f78f317a5351f2045158be321fd135973fff7bf", + "sha256:e0b55f27f584ed623221cfe995c912c61606be8513bfa0e07d2c674b4516d9dd", + "sha256:e616e7154c37669fc1dfc14584f11e284e05d1c650e1c0f972f281c4ccc53193", + "sha256:e6def7eed9e7fa90fde255afaf08060dc4b343bbe524a8f69bdd2a2f0018f600", + "sha256:ea926cfbc3957090becbcbbb65ad177161a2ff2ad578b5a6ec9bb1e1cd78753c", + "sha256:f0d3348c95b766f54b76116d53d4cb171b52992a1027e7ca50c81b43b9d9e363", + "sha256:f6b0c664ccb879109ee3ca702a9272d877f4fcd21e5eb63c26422fd6e415365e", + "sha256:f781dcb0bc9929adc77bad571b8621ecb1e4cdef86e940fe2e5b5ee24fd33b35", + "sha256:f91ebf30830a48c825590aede79376cb40f110b387c17ee9bd59932c961044f9", + "sha256:fdec757fea0b793056419bca3e9932eb2b0ceec90ef4813ea4c1e072c389eb28", + "sha256:fe15238d3798788d00716637b3d4e7bb6bde18b26e5d08335a96e88564a36b6b" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==11.2.1" + }, "psycopg2": { "hashes": [ "sha256:0435034157049f6846e95103bd8f5a668788dd913a7c30162ca9503fdf542cb4", diff --git a/backend/api/main/serializers.py b/backend/api/main/serializers.py index 560720e..32d006b 100644 --- a/backend/api/main/serializers.py +++ b/backend/api/main/serializers.py @@ -1,6 +1,6 @@ from rest_framework import serializers -from mainpage.models import FAQ +from sitemanagement.models import FAQ class FAQMainSerializer(serializers.ModelSerializer): class Meta: diff --git a/backend/api/main/views.py b/backend/api/main/views.py index 7b2cf38..30aafb6 100644 --- a/backend/api/main/views.py +++ b/backend/api/main/views.py @@ -4,7 +4,7 @@ from rest_framework.response import Response from api.utils.decorators import handle_exceptions from api.main.serializers import FAQMainSerializer -from mainpage.models import FAQ +from sitemanagement.models import FAQ class FAQView(APIView): @handle_exceptions diff --git a/backend/base/settings.py b/backend/base/settings.py index 6b3ed4e..67a63ee 100644 --- a/backend/base/settings.py +++ b/backend/base/settings.py @@ -5,15 +5,11 @@ from dotenv import load_dotenv BASE_DIR = Path(__file__).resolve().parent.parent load_dotenv(dotenv_path=BASE_DIR / './.env') - SECRET_KEY = os.environ.get("SECRET_KEY") DEBUG = os.environ.get("DEBUG_MODE") ALLOWED_HOSTS = [] - -# Application definition - INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', @@ -23,7 +19,7 @@ INSTALLED_APPS = [ 'django.contrib.staticfiles', 'api.apps.ApiConfig', 'routes.apps.RoutesConfig', - 'mainpage.apps.MainpageConfig', + 'sitemanagement.apps.SitemanagementConfig', 'rest_framework', ] @@ -56,10 +52,6 @@ TEMPLATES = [ WSGI_APPLICATION = 'base.wsgi.application' - -# Database -# https://docs.djangoproject.com/en/5.2/ref/settings/#databases - DATABASES = { "default": { "ENGINE": "django.db.backends.postgresql", @@ -72,9 +64,6 @@ DATABASES = { } -# Password validation -# https://docs.djangoproject.com/en/5.2/ref/settings/#auth-password-validators - AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', @@ -90,25 +79,13 @@ AUTH_PASSWORD_VALIDATORS = [ }, ] - -# Internationalization -# https://docs.djangoproject.com/en/5.2/topics/i18n/ - LANGUAGE_CODE = 'en-us' -TIME_ZONE = 'UTC' - -USE_I18N = True - +TIME_ZONE = 'Europe/Minsk' USE_TZ = True - - -# Static files (CSS, JavaScript, Images) -# https://docs.djangoproject.com/en/5.2/howto/static-files/ +USE_I18N = True +USE_L10N = True STATIC_URL = 'static/' -# Default primary key field type -# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field - DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' diff --git a/backend/base/urls.py b/backend/base/urls.py index ab9a035..9666b6b 100644 --- a/backend/base/urls.py +++ b/backend/base/urls.py @@ -1,19 +1,3 @@ -""" -URL configuration for base project. - -The `urlpatterns` list routes URLs to views. For more information please see: - https://docs.djangoproject.com/en/5.2/topics/http/urls/ -Examples: -Function views - 1. Add an import: from my_app import views - 2. Add a URL to urlpatterns: path('', views.home, name='home') -Class-based views - 1. Add an import: from other_app.views import Home - 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') -Including another URLconf - 1. Import the include() function: from django.urls import include, path - 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) -""" from django.contrib import admin from django.urls import path, include diff --git a/backend/routes/admin.py b/backend/routes/admin.py index 8c38f3f..bf26264 100644 --- a/backend/routes/admin.py +++ b/backend/routes/admin.py @@ -1,3 +1,6 @@ from django.contrib import admin +from .models import * -# Register your models here. +admin.site.register(Country) +admin.site.register(City) +admin.site.register(Route) diff --git a/backend/routes/constants/__init__.py b/backend/routes/constants/__init__.py new file mode 100644 index 0000000..77ee8c3 --- /dev/null +++ b/backend/routes/constants/__init__.py @@ -0,0 +1,6 @@ +from .routeChoices import ( + type_transport_choices, + transfer_location_choices, + cargo_type_choices, + owner_type_choices +) \ No newline at end of file diff --git a/backend/routes/migrations/0001_initial.py b/backend/routes/migrations/0001_initial.py new file mode 100644 index 0000000..739de24 --- /dev/null +++ b/backend/routes/migrations/0001_initial.py @@ -0,0 +1,56 @@ +# Generated by Django 5.2.1 on 2025-05-15 15:57 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Country', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('international_name', models.CharField(blank=True, max_length=250, null=True, verbose_name='Международное название')), + ('official_name', models.CharField(blank=True, max_length=250, null=True, verbose_name='Официальное название')), + ('short_code', models.CharField(max_length=2, verbose_name='Код страны по ISO3166-1:alpha2')), + ('code', models.CharField(max_length=3, verbose_name='Код страны по ISO3166-1:alpha3')), + ('num_code', models.CharField(blank=True, max_length=3, null=True, verbose_name='Код страны по ISO3166-1:numeric')), + ('flag_img_url', models.URLField(blank=True, null=True, verbose_name='Ссылка на изображение флага')), + ('geo_lat', models.CharField(blank=True, max_length=20, null=True, verbose_name='GPS широта')), + ('geo_lon', models.CharField(blank=True, max_length=20, null=True, verbose_name='GPS долгота')), + ('timezone', models.CharField(blank=True, max_length=250, null=True, verbose_name='Часовая зона')), + ('area_id', models.BigIntegerField(blank=True, null=True)), + ('parsing_finished_DT', models.DateTimeField(blank=True, null=True, verbose_name='Дата и время завершения парсинга')), + ('flag', models.ImageField(blank=True, null=True, upload_to='uploads/flags/', verbose_name='Флаг')), + ], + options={ + 'verbose_name': 'Страна', + 'verbose_name_plural': 'Страны', + 'ordering': ('international_name', 'code'), + }, + ), + migrations.CreateModel( + name='City', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(blank=True, max_length=30, null=True, verbose_name='Название города')), + ('geo_lat', models.CharField(blank=True, max_length=20, null=True, verbose_name='GPS широта')), + ('geo_lon', models.CharField(blank=True, max_length=20, null=True, verbose_name='GPS долгота')), + ('area_id', models.BigIntegerField(blank=True, null=True)), + ('timezone', models.CharField(blank=True, max_length=250, null=True, verbose_name='Часовая зона')), + ('parsing_finished_DT', models.DateTimeField(blank=True, null=True, verbose_name='Дата и время завершения парсинга')), + ('country', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='rel_cities_for_country', to='routes.country', verbose_name='Страна')), + ], + options={ + 'verbose_name': 'Город', + 'verbose_name_plural': 'Города', + 'ordering': ('name',), + }, + ), + ] diff --git a/backend/routes/migrations/0002_route.py b/backend/routes/migrations/0002_route.py new file mode 100644 index 0000000..2ce6f63 --- /dev/null +++ b/backend/routes/migrations/0002_route.py @@ -0,0 +1,39 @@ +# Generated by Django 5.2.1 on 2025-05-15 16:09 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('routes', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Route', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('owner_type', models.CharField(choices=[('customer', 'Заказчик'), ('mover', 'Перевозчик')], default='customer', verbose_name='Тип опреации')), + ('type_transport', models.CharField(blank=True, choices=[('road', 'Авто'), ('avia', 'Авиа'), ('both', 'Любой')], default='', verbose_name='Выберите способ перевозки')), + ('departure_DT', models.DateTimeField(blank=True, null=True, verbose_name='Дата и время выезда')), + ('arrival_DT', models.DateTimeField(verbose_name='Дата и время прибытия')), + ('cargo_type', models.CharField(choices=[('letter', 'Письмо или Документы'), ('package', 'Посылка (до 30кг)'), ('passenger', 'Попутчик'), ('parcel', 'Бандероль (до 5кг)'), ('cargo', 'Груз (свыше 30 кг)')], default='letter', verbose_name='Могу перевезти')), + ('receive_msg_by_email', models.BooleanField(default=False, verbose_name='Получать уведомления по E-mail')), + ('comment', models.TextField(blank=True, null=True, verbose_name='Примечания')), + ('rising_DT', models.DateTimeField(blank=True, null=True, verbose_name='Дата и время последнего поднятия')), + ('highlight_end_DT', models.DateTimeField(blank=True, null=True, verbose_name='Дата и время окончания выделения')), + ('from_city', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='rel_routes_for_cityFrom', to='routes.city', verbose_name='Город отправки')), + ('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='rel_routes_for_owner', to=settings.AUTH_USER_MODEL, verbose_name='Владелец')), + ('to_city', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='rel_routes_for_cityTo', to='routes.city', verbose_name='Город получения')), + ], + options={ + 'verbose_name': 'Маршрут', + 'verbose_name_plural': 'Маршруты', + 'ordering': ('id',), + }, + ), + ] diff --git a/backend/routes/models.py b/backend/routes/models.py index 71a8362..a1bff61 100644 --- a/backend/routes/models.py +++ b/backend/routes/models.py @@ -1,3 +1,114 @@ from django.db import models +from django.contrib.auth.models import User +from routes.constants.routeChoices import owner_type_choices, type_transport_choices, cargo_type_choices -# Create your models here. +class Country(models.Model): + international_name = models.CharField(max_length=250, verbose_name=('Международное название'), blank=True, null=True) + official_name = models.CharField(max_length=250, verbose_name=('Официальное название'), blank=True, null=True) + + short_code = models.CharField(max_length=2, verbose_name=('Код страны по ISO3166-1:alpha2')) + code = models.CharField(max_length=3, verbose_name=('Код страны по ISO3166-1:alpha3')) + num_code = models.CharField(max_length=3, verbose_name=('Код страны по ISO3166-1:numeric'), blank=True, null=True) + + flag_img_url = models.URLField(verbose_name=('Ссылка на изображение флага'), blank=True, null=True) + + geo_lat = models.CharField(max_length=20, verbose_name=('GPS широта'), blank=True, null=True) + geo_lon = models.CharField(max_length=20, verbose_name=('GPS долгота'), blank=True, null=True) + + timezone = models.CharField(max_length=250, verbose_name=('Часовая зона'), blank=True, null=True) + + area_id = models.BigIntegerField(blank=True, null=True) + + parsing_finished_DT = models.DateTimeField(verbose_name=('Дата и время завершения парсинга'), blank=True, null=True) + + flag = models.ImageField( + upload_to='uploads/flags/', verbose_name=('Флаг'), + null=True, blank=True, help_text=u'') + + def __str__(self): + if self.international_name: + return f'{self.international_name}' + elif self.official_name: + return f'{self.official_name}' + elif self.code: + return f'{self.code}' + + class Meta: + verbose_name = ('Страна') + verbose_name_plural = ('Страны') + ordering = ('international_name', 'code') + + +class City(models.Model): + + country = models.ForeignKey( + Country, verbose_name=('Страна'), related_name='rel_cities_for_country', on_delete=models.CASCADE) + + name = models.CharField(max_length=30, verbose_name=('Название города'), blank=True, null=True) + geo_lat = models.CharField(max_length=20, verbose_name=('GPS широта'), blank=True, null=True) + geo_lon = models.CharField(max_length=20, verbose_name=('GPS долгота'), blank=True, null=True) + + area_id = models.BigIntegerField(blank=True, null=True) + + timezone = models.CharField(max_length=250, verbose_name=('Часовая зона'), blank=True, null=True) + + parsing_finished_DT = models.DateTimeField(verbose_name=('Дата и время завершения парсинга'), blank=True, null=True) + + def __str__(self): + return f'{self.name}' + + class Meta: + verbose_name = ('Город') + verbose_name_plural = ('Города') + ordering = ('name',) + +class Route(models.Model): + owner_type = models.CharField( + choices=owner_type_choices, default='customer', verbose_name=('Тип опреации')) + + type_transport = models.CharField( + choices=type_transport_choices, default='', verbose_name=('Выберите способ перевозки'), + blank=True + ) + departure_DT = models.DateTimeField( + verbose_name=('Дата и время выезда'), null=True, blank=True + ) + arrival_DT = models.DateTimeField(verbose_name=('Дата и время прибытия')) + + from_city = models.ForeignKey( + City, verbose_name=('Город отправки'), related_name='rel_routes_for_cityFrom', on_delete=models.SET_NULL, + null=True, blank=True + ) + to_city = models.ForeignKey( + City, verbose_name=('Город получения'), related_name='rel_routes_for_cityTo', on_delete=models.SET_NULL, + null=True, blank=True + ) + cargo_type = models.CharField( + choices=cargo_type_choices, default='letter', verbose_name=('Могу перевезти') + ) + receive_msg_by_email = models.BooleanField(default=False, verbose_name=('Получать уведомления по E-mail')) + + owner = models.ForeignKey(User, verbose_name=('Владелец'), related_name='rel_routes_for_owner', on_delete=models.CASCADE) + + comment = models.TextField(verbose_name='Примечания', null=True, blank=True) + + rising_DT = models.DateTimeField( + verbose_name=('Дата и время последнего поднятия'), + blank=True, null=True + ) + + highlight_end_DT = models.DateTimeField( + verbose_name=('Дата и время окончания выделения'), + blank=True, null=True + ) + + def __str__(self): + if self.owner: + return f'{self.owner}' + else: + return str(self.owner_type) + + class Meta: + verbose_name = (u'Маршрут') + verbose_name_plural = (u'Маршруты') + ordering = ('id',) diff --git a/backend/mainpage/__init__.py b/backend/sitemanagement/__init__.py similarity index 100% rename from backend/mainpage/__init__.py rename to backend/sitemanagement/__init__.py diff --git a/backend/mainpage/admin.py b/backend/sitemanagement/admin.py similarity index 100% rename from backend/mainpage/admin.py rename to backend/sitemanagement/admin.py diff --git a/backend/mainpage/apps.py b/backend/sitemanagement/apps.py similarity index 58% rename from backend/mainpage/apps.py rename to backend/sitemanagement/apps.py index 2eb9b04..8ccff00 100644 --- a/backend/mainpage/apps.py +++ b/backend/sitemanagement/apps.py @@ -1,6 +1,6 @@ from django.apps import AppConfig -class MainpageConfig(AppConfig): +class SitemanagementConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' - name = 'mainpage' + name = 'sitemanagement' diff --git a/backend/mainpage/migrations/0001_initial.py b/backend/sitemanagement/migrations/0001_initial.py similarity index 88% rename from backend/mainpage/migrations/0001_initial.py rename to backend/sitemanagement/migrations/0001_initial.py index 7816116..d304162 100644 --- a/backend/mainpage/migrations/0001_initial.py +++ b/backend/sitemanagement/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 5.2.1 on 2025-05-15 14:16 +# Generated by Django 5.2.1 on 2025-05-15 16:24 from django.db import migrations, models @@ -21,6 +21,7 @@ class Migration(migrations.Migration): options={ 'verbose_name': 'FAQ', 'verbose_name_plural': 'FAQs', + 'ordering': ['id'], }, ), ] diff --git a/backend/mainpage/migrations/__init__.py b/backend/sitemanagement/migrations/__init__.py similarity index 100% rename from backend/mainpage/migrations/__init__.py rename to backend/sitemanagement/migrations/__init__.py diff --git a/backend/mainpage/models.py b/backend/sitemanagement/models.py similarity index 100% rename from backend/mainpage/models.py rename to backend/sitemanagement/models.py diff --git a/backend/mainpage/tests.py b/backend/sitemanagement/tests.py similarity index 100% rename from backend/mainpage/tests.py rename to backend/sitemanagement/tests.py