diff --git a/Shops/household_shop/homeworks/django_todo_front/manage.py b/Shops/household_shop/homeworks/django_todo_front/manage.py new file mode 100644 index 0000000..1729a26 --- /dev/null +++ b/Shops/household_shop/homeworks/django_todo_front/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'todo_service.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main() diff --git a/Shops/household_shop/homeworks/django_todo_front/templates/base.html b/Shops/household_shop/homeworks/django_todo_front/templates/base.html new file mode 100644 index 0000000..6f60e3f --- /dev/null +++ b/Shops/household_shop/homeworks/django_todo_front/templates/base.html @@ -0,0 +1,31 @@ + + + + + + + + {% block title %}Base title{% endblock %} + + + + + + + +
+ + + + {% block sidebar %}{% endblock %} + {% block content %}{% endblock %} +
+ + \ No newline at end of file diff --git a/Shops/household_shop/homeworks/django_todo_front/templates/plan/event_add.html b/Shops/household_shop/homeworks/django_todo_front/templates/plan/event_add.html new file mode 100644 index 0000000..ffbf2d7 --- /dev/null +++ b/Shops/household_shop/homeworks/django_todo_front/templates/plan/event_add.html @@ -0,0 +1,52 @@ +{% extends "base.html" %} + +{% block bar_add %}class="nav-link active" {% endblock %} + + +{% block content %} + +
+ {% csrf_token %} + +
+

Добавить событие

+ +
+ Название + {{ form.title }} +
+ +
+ Описание + {{ form.description }} +
+ +
+ Статус + {{ form.status }} +
+ +
+ Зависит от + {{ form.depends_on }} +
+ +
+ Старт + {{ form.started_at }} + Дэдлайн + {{ form.finished_at }} +
+ + {{form.started_at.errors}} + {{form.finished_at.errors}} + {{form.status.errors}} + + + +
+
+ +{% endblock %} \ No newline at end of file diff --git a/Shops/household_shop/homeworks/django_todo_front/templates/plan/event_analytics.html b/Shops/household_shop/homeworks/django_todo_front/templates/plan/event_analytics.html new file mode 100644 index 0000000..1944b0b --- /dev/null +++ b/Shops/household_shop/homeworks/django_todo_front/templates/plan/event_analytics.html @@ -0,0 +1,19 @@ +{% extends "base.html" %} + +{% block bar_analitics %} class="nav-link active" {% endblock %} + +{% block content %} +
+ +

Аналитика событий:

+ +
+ + {% for status, percentage in events.items %} + {{ status }} - {{ percentage }}% + {% endfor %} + +
+ +
+{% endblock %} diff --git a/Shops/household_shop/homeworks/django_todo_front/templates/plan/event_delete.html b/Shops/household_shop/homeworks/django_todo_front/templates/plan/event_delete.html new file mode 100644 index 0000000..d5bd79a --- /dev/null +++ b/Shops/household_shop/homeworks/django_todo_front/templates/plan/event_delete.html @@ -0,0 +1,20 @@ +{% extends "base.html" %} + + +{% block content %} + + +
{% csrf_token %} +
+

А ты уверен, что хочешь удалить событие "{{ object.title }}"?

+ + {{ form }} + + + +
+
+ +{% endblock %} \ No newline at end of file diff --git a/Shops/household_shop/homeworks/django_todo_front/templates/plan/event_detail.html b/Shops/household_shop/homeworks/django_todo_front/templates/plan/event_detail.html new file mode 100644 index 0000000..e32c3e6 --- /dev/null +++ b/Shops/household_shop/homeworks/django_todo_front/templates/plan/event_detail.html @@ -0,0 +1,48 @@ +{% extends "base.html" %} + +{% block content %} + +
+ +

{{ object.title }} ({{ object.status }})

+ + +
+
+
+

{{ object.description }}

+ +
+ + +
+
+
+
Старт: {{ object.started_at }}
+
+
+
Истекает: {{ object.finished_at }}
+
+
+
+ + {% if object.depends_on %} +
+

Зависит от {{ object.depends_on.title }}

+
+ {% endif %} +
+
+ + + +
+ +{% endblock %} \ No newline at end of file diff --git a/Shops/household_shop/homeworks/django_todo_front/templates/plan/event_list.html b/Shops/household_shop/homeworks/django_todo_front/templates/plan/event_list.html new file mode 100644 index 0000000..969f30f --- /dev/null +++ b/Shops/household_shop/homeworks/django_todo_front/templates/plan/event_list.html @@ -0,0 +1,39 @@ +{% extends "base.html" %} + +{% block bar_list %}class="nav-link active" {% endblock %} + +{% block content %} +
+ +

Твои события:

+ +
+ + In progress + Finished + Waiting + Expired + Blocked + +
+ +
+ + {% for event in events %} + {% if event.status == "expired" %} + {{ event.title }} + {% elif event.status == "finished" %} + {{ event.title }} + {% elif event.status == "in progress" %} + {{ event.title }} + {% else %} + {{ event.title }} + {% endif %} + {% empty %} + Попробуй добавь какое-нибудь событие... + {% endfor %} + +
+ +
+{% endblock %} diff --git a/Shops/household_shop/homeworks/django_todo_front/templates/plan/event_update.html b/Shops/household_shop/homeworks/django_todo_front/templates/plan/event_update.html new file mode 100644 index 0000000..e98aef7 --- /dev/null +++ b/Shops/household_shop/homeworks/django_todo_front/templates/plan/event_update.html @@ -0,0 +1,52 @@ +{% extends "base.html" %} + +{% block bar_add %}class="nav-link active" {% endblock %} + + +{% block content %} + +
+ {% csrf_token %} + +
+ +

Обновить событие

+ +
+ Название + {{ form.title }} +
+ +
+ Описание + {{ form.description }} +
+ +
+ Статус + {{ form.status }} +
+ +
+ Зависит от + {{ form.depends_on }} +
+ +
+ Старт + {{ form.started_at }} + Дэдлайн + {{ form.finished_at }} +
+ + {{form.started_at.errors}} + {{form.finished_at.errors}} + {{form.status.errors}} + + +
+
+ +{% endblock %} \ No newline at end of file diff --git a/Shops/household_shop/homeworks/django_todo_front/todo_front/__init__.py b/Shops/household_shop/homeworks/django_todo_front/todo_front/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Shops/household_shop/homeworks/django_todo_front/todo_front/admin.py b/Shops/household_shop/homeworks/django_todo_front/todo_front/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/Shops/household_shop/homeworks/django_todo_front/todo_front/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/Shops/household_shop/homeworks/django_todo_front/todo_front/apps.py b/Shops/household_shop/homeworks/django_todo_front/todo_front/apps.py new file mode 100644 index 0000000..0733e16 --- /dev/null +++ b/Shops/household_shop/homeworks/django_todo_front/todo_front/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class TodoFrontConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'todo_front' diff --git a/Shops/household_shop/homeworks/django_todo_front/todo_front/migrations/__init__.py b/Shops/household_shop/homeworks/django_todo_front/todo_front/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Shops/household_shop/homeworks/django_todo_front/todo_front/models.py b/Shops/household_shop/homeworks/django_todo_front/todo_front/models.py new file mode 100644 index 0000000..4865a2d --- /dev/null +++ b/Shops/household_shop/homeworks/django_todo_front/todo_front/models.py @@ -0,0 +1,13 @@ +from pydantic import BaseModel +from typing import Optional + + +class Event(BaseModel): + id: str + created_at: str + started_at: str + finished_at: str + title: str + description: str + depends_on: Optional[str] = '' + status: str diff --git a/Shops/household_shop/homeworks/django_todo_front/todo_front/request_service.py b/Shops/household_shop/homeworks/django_todo_front/todo_front/request_service.py new file mode 100644 index 0000000..2a57263 --- /dev/null +++ b/Shops/household_shop/homeworks/django_todo_front/todo_front/request_service.py @@ -0,0 +1,22 @@ +import requests + + +class ConnectService: + def __init__(self, url) -> None: + self.url = url + self.headers = {"Content-type": "application/json"} + + def get_list_events(self): + return requests.get(url=self.url).json() + + def add_event(self, data): + return requests.post(url=self.url, data=data, headers=self.headers) + + def get_event_detail(self): + return requests.get(url=self.url).json() + + def delete_event(self): + return requests.delete(url=self.url) + + def update_event(self, data): + return requests.put(url=self.url, data=data, headers=self.headers) diff --git a/Shops/household_shop/homeworks/django_todo_front/todo_front/tests.py b/Shops/household_shop/homeworks/django_todo_front/todo_front/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/Shops/household_shop/homeworks/django_todo_front/todo_front/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/Shops/household_shop/homeworks/django_todo_front/todo_front/urls.py b/Shops/household_shop/homeworks/django_todo_front/todo_front/urls.py new file mode 100644 index 0000000..8742061 --- /dev/null +++ b/Shops/household_shop/homeworks/django_todo_front/todo_front/urls.py @@ -0,0 +1,11 @@ +from django.urls import path +from .views import get_events_list, create_new_event, get_event_detail, delete_event, update_event + + +urlpatterns = [ + path('list/', get_events_list, name='event-list'), + path('add/', create_new_event, name='event-add'), + path('/', get_event_detail, name='event-detail'), + path('/delete/', delete_event, name='event-delete'), + path('/update/', update_event, name='event-update'), +] diff --git a/Shops/household_shop/homeworks/django_todo_front/todo_front/views.py b/Shops/household_shop/homeworks/django_todo_front/todo_front/views.py new file mode 100644 index 0000000..def4c86 --- /dev/null +++ b/Shops/household_shop/homeworks/django_todo_front/todo_front/views.py @@ -0,0 +1,49 @@ +import json +from .models import Event +from .forms import EventForm +from django.conf import settings +from django.shortcuts import render +from .request_service import ConnectService + + +def get_events_list(request): + template_name = 'plan/event_list.html' + data = ConnectService(settings.SERVICE_URL).get_list_events() + context = {'events': [Event(**item) for item in data]} + + return render(request=request, template_name=template_name, context=context) + + +def create_new_event(request): + template_name = 'plan/event_add.html' + context = {"form": EventForm} + + if request.method == "POST": + event = json.dumps(request.POST) + ConnectService(settings.SERVICE_URL).add_event(event) + + return render(request=request, template_name=template_name, context=context) + + +def get_event_detail(request, pk): + template_name = 'plan/event_detail.html' + data = ConnectService(settings.SERVICE_URL + pk).get_event_detail() + context = {"object": Event(**data)} + + return render(request=request, template_name=template_name, context=context) + + +def delete_event(request, pk): + template_name = 'plan/event_delete.html' + ConnectService(settings.SERVICE_URL + pk).delete_event() + + return render(request=request, template_name=template_name) + + +def update_event(request, pk): + template_name = 'plan/event_update.html' + context = {"form": EventForm} + event = json.dumps(request.POST) + ConnectService(settings.SERVICE_URL + pk).update_event(event) + + return render(request=request, template_name=template_name, context=context) diff --git a/Shops/household_shop/homeworks/django_todo_front/todo_service/__init__.py b/Shops/household_shop/homeworks/django_todo_front/todo_service/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Shops/household_shop/homeworks/django_todo_front/todo_service/asgi.py b/Shops/household_shop/homeworks/django_todo_front/todo_service/asgi.py new file mode 100644 index 0000000..11f79e8 --- /dev/null +++ b/Shops/household_shop/homeworks/django_todo_front/todo_service/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for todo_service project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/4.1/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'todo_service.settings') + +application = get_asgi_application() diff --git a/Shops/household_shop/homeworks/django_todo_front/todo_service/settings.py b/Shops/household_shop/homeworks/django_todo_front/todo_service/settings.py new file mode 100644 index 0000000..9a122e6 --- /dev/null +++ b/Shops/household_shop/homeworks/django_todo_front/todo_service/settings.py @@ -0,0 +1,126 @@ +""" +Django settings for todo_service project. + +Generated by 'django-admin startproject' using Django 4.1. + +For more information on this file, see +https://docs.djangoproject.com/en/4.1/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/4.1/ref/settings/ +""" + +from pathlib import Path + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'django-insecure-y8y(9i5!pake(in$ass%-)50dq3(eoinpvj9x8fd9u@p7r2pj9' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'todo_front', +] + +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', +] + +ROOT_URLCONF = 'todo_service.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [BASE_DIR.joinpath('templates')], + '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 = 'todo_service.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/4.1/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', + } +} + + +# Password validation +# https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/4.1/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/4.1/howto/static-files/ + +STATIC_URL = 'static/' + +# Default primary key field type +# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' + +SERVICE_URL = 'http://127.0.0.1:5000/api/events/' diff --git a/Shops/household_shop/homeworks/django_todo_front/todo_service/urls.py b/Shops/household_shop/homeworks/django_todo_front/todo_service/urls.py new file mode 100644 index 0000000..df5749a --- /dev/null +++ b/Shops/household_shop/homeworks/django_todo_front/todo_service/urls.py @@ -0,0 +1,22 @@ +"""todo_service URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/4.1/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 + +urlpatterns = [ + path('admin/', admin.site.urls), + path('', include('todo_front.urls')), +] diff --git a/Shops/household_shop/homeworks/django_todo_front/todo_service/wsgi.py b/Shops/household_shop/homeworks/django_todo_front/todo_service/wsgi.py new file mode 100644 index 0000000..c645aaa --- /dev/null +++ b/Shops/household_shop/homeworks/django_todo_front/todo_service/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for todo_service project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/4.1/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'todo_service.settings') + +application = get_wsgi_application()