Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Generated by Django 4.0.5 on 2022-07-01 10:03
# Generated by Django 4.0.5 on 2022-07-01 13:24

import datetime
from django.db import migrations, models
Expand All @@ -17,7 +17,7 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='Account',
fields=[
('iban', models.UUIDField(default=uuid.UUID('c52094dc-82ce-46f7-9618-54c285d4bd75'), primary_key=True, serialize=False)),
('iban', models.UUIDField(default=uuid.UUID('198fb542-5ea9-4a3f-b82b-5ecc45664d72'), primary_key=True, serialize=False)),
('sum', models.PositiveIntegerField(default=0)),
],
options={
Expand All @@ -29,7 +29,7 @@ class Migration(migrations.Migration):
fields=[
('name', models.CharField(max_length=255)),
('age', models.IntegerField()),
('uuid', models.UUIDField(default=uuid.UUID('53bb4abc-4c2f-4c7f-9045-1c611c6eadfa'), primary_key=True, serialize=False)),
('uuid', models.UUIDField(default=uuid.UUID('52e6c374-1d6d-4904-85ac-cdc04fc08780'), primary_key=True, serialize=False)),
],
options={
'db_table': 'users',
Expand All @@ -39,9 +39,9 @@ class Migration(migrations.Migration):
name='Card',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('number', models.PositiveBigIntegerField(max_length=16)),
('number', models.PositiveBigIntegerField()),
('expiration_date', models.DateField(default=datetime.date(2025, 7, 1))),
('cvv', models.IntegerField(max_length=3)),
('cvv', models.IntegerField()),
('account', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cards.account')),
('user_name', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cards.user')),
],
Expand Down
4 changes: 2 additions & 2 deletions Shops/beauty_saloon/homeworks/djando_hw/bank/cards/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@

# Create your models here.
class Card(models.Model):
number = models.PositiveBigIntegerField(max_length=16, null=False)
number = models.PositiveBigIntegerField(null=False)
expiration_date = models.DateField(default=(date.today() + relativedelta(years=3)))
user_name = models.ForeignKey('User', on_delete=models.CASCADE, null=False)
account = models.ForeignKey('Account', on_delete=models.CASCADE, null=False)
cvv = models.IntegerField(null=False, max_length=3)
cvv = models.IntegerField(null=False)

class Meta:
db_table = 'cards'
Expand Down
18 changes: 18 additions & 0 deletions Shops/beauty_saloon/homeworks/djando_hw/todo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# TODO приложение
Небольшое приложение, позволяющее следить за своей продуктивностью, однако в нем есть несколько мест, которые стоит исправить. Бэкэнд написан на Django, стили на фронтенд сделаны при помощи фреймворка Bootstrap 5, про него не принципиально читать, но для некоторых заданий надо будет погуглить, благо у него очень большая и понятная документация.

### 1. EASY
1. Запустите приложение, создайте несколько событий с разными статусами.
2. Добавьте сохранение данных не в sqlite3, а в postrgesql.
3. Почему-то перестал работать метод удаления событий, надо что-то с этим сделать...

### 2. MEDIUM
1. Есть возможность добавить дэдлайн события вчерашним днем, а также до старта события... Надо сделать, чтобы нельзя было.
2. Сделать так, чтобы нельзя было поставить дэдлайн позже чем старт более чем на 2 недели. Если пользователь например выбрал 10.08.2022 как старт, то максимальный дэдлайн, который он может поставить, должен быть 24.08.2022.
3. При создании события, когда выбираешь "зависит от", показаны какие-то цифры... Было бы круто если бы там были названия других событий.
4. Классно было бы подсвечивать в общем списке событий желтым те, что IN PROGRESS.
5. Было бы классно если бы над списком всех событий стояли кнопочки in progress, finished, is waiting, expired, blocked, при нажатии на которые показывались бы только события с этим статусом.

### 3. HARD
1. Было бы классно иметь какую-то вкладку аналитики, где бы в процентном соотношении показывалось соотношение событий с разными статусами к общему количеству событий. Круто было бы еще иметь вверху, там где можно посмотреть все события и создать новое, кнопку "Аналитика" :)
2. Добавить логику, что если, событие, от которого зависит текущее, не в статусе FINISHED, то не позволять завершать и текущее.
22 changes: 22 additions & 0 deletions Shops/beauty_saloon/homeworks/djando_hw/todo/manage.py
Original file line number Diff line number Diff line change
@@ -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.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()
Empty file.
3 changes: 3 additions & 0 deletions Shops/beauty_saloon/homeworks/djando_hw/todo/plan/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.contrib import admin

# Register your models here.
6 changes: 6 additions & 0 deletions Shops/beauty_saloon/homeworks/djando_hw/todo/plan/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class PlanConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'plan'
50 changes: 50 additions & 0 deletions Shops/beauty_saloon/homeworks/djando_hw/todo/plan/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from datetime import date, timedelta

from django import forms

from .models import Event


class EventForm(forms.ModelForm):
class Meta:
model = Event
fields = [
'started_at', 'finished_at', 'title',
'description', 'depends_on', 'status',
]
widgets = {
'title': forms.TextInput(attrs={
'class': 'form-control',
}),
'description': forms.Textarea(attrs={
'class': 'form-control',
}),
'finished_at': forms.DateInput(attrs={
'type': 'date',
'class': 'form-control',
}),
'started_at': forms.DateInput(attrs={
'type': 'date',
'class': 'form-control',
}),
'status': forms.Select(attrs={
'class': 'form-select',
}),
'depends_on': forms.Select(attrs={
'class': 'form-select',
})
}

def clean_started_at(self):
started_at = self.cleaned_data['started_at']
finished_at = self.cleaned_data['finished_at']

if started_at < date.today():
raise forms.ValidationError("Вы не можете создать событие, которое начась в прошлом!")
elif finished_at < date.today():
raise forms.ValidationError("Вы не можете создать событие, которое закончилось до начала!")
elif finished_at > date.today() + timedelta(days=14):
raise forms.ValidationError("Дедлайн не может быть дальше чем через 14 дней от начала события!")

return started_at

Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Generated by Django 4.0.6 on 2022-07-26 07:12

import datetime
from django.db import migrations, models
import django.db.models.deletion
import plan.models
import uuid


class Migration(migrations.Migration):

initial = True

dependencies = [
]

operations = [
migrations.CreateModel(
name='Event',
fields=[
('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
('created_at', models.DateField(default=datetime.date.today)),
('started_at', models.DateField(default=datetime.date.today)),
('finished_at', models.DateField(default=datetime.date.today)),
('title', models.CharField(max_length=200)),
('description', models.TextField()),
('status', models.CharField(choices=[('is waiting', 'IS_WAITING'), ('in progress', 'IN_PROGRESS'), ('finished', 'FINISHED'), ('expired', 'EXPIRED'), ('blocked', 'BLOCKED')], default=plan.models.Status['IN_PROGRESS'], max_length=20)),
('depends_on', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='plan.event')),
],
options={
'db_table': 'events',
},
),
]
Empty file.
31 changes: 31 additions & 0 deletions Shops/beauty_saloon/homeworks/djando_hw/todo/plan/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from turtle import color
from django.db import models
from datetime import date
from enum import Enum
from uuid import uuid4


class Status(Enum):
IS_WAITING = "is waiting"
IN_PROGRESS = "in progress"
FINISHED = "finished"
EXPIRED = "expired"
BLOCKED = "blocked"

@classmethod
def choices(cls):
return [(item.value, item.name) for item in cls]


class Event(models.Model):
id = models.UUIDField(primary_key=True, default=uuid4)
created_at = models.DateField(default=date.today)
started_at = models.DateField(default=date.today)
finished_at = models.DateField(default=date.today)
title = models.CharField(max_length=200, null=False, blank=False)
description = models.TextField()
depends_on = models.ForeignKey('Event', on_delete=models.CASCADE, null=True, blank=True)
status = models.CharField(max_length=20, choices=Status.choices(), default=Status.IN_PROGRESS)

class Meta:
db_table = "events"
3 changes: 3 additions & 0 deletions Shops/beauty_saloon/homeworks/djando_hw/todo/plan/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.test import TestCase

# Create your tests here.
17 changes: 17 additions & 0 deletions Shops/beauty_saloon/homeworks/djando_hw/todo/plan/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from django.urls import path
from .views import (
EventCreateView,
EventListView,
EventDetailView,
EventDeleteView,
EventUpdateView,
)

urlpatterns = [
path("", view=EventCreateView.as_view(), name="event-add"),
path("add/", view=EventCreateView.as_view(), name="event-add"),
path("list/", view=EventListView.as_view(), name="event-list"),
path("<str:pk>/", view=EventDetailView.as_view(), name="event-detail"),
path("<str:pk>/delete", view=EventDeleteView.as_view(), name="event-delete"),
path("<str:pk>/update", view=EventUpdateView.as_view(), name="event-update"),
]
47 changes: 47 additions & 0 deletions Shops/beauty_saloon/homeworks/djando_hw/todo/plan/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from django.views.generic import (
CreateView,
DetailView,
DeleteView,
ListView,
UpdateView,
)
from django.urls import reverse

from .forms import EventForm
from .models import Event


class EventCreateView(CreateView):
template_name: str = "plan/event_add.html"
form_class: type = EventForm

def get_success_url(self):
return reverse('event-list')


class EventListView(ListView):
template_name: str = "plan/event_list.html"
model: type = Event


class EventDetailView(DetailView):
template_name: str = "plan/event_detail.html"
model: type = Event


class EventDeleteView(DeleteView):
template_name: str = "plan/event_delete.html"
model: type = Event
success_url: str = "#"

def get_success_url(self):
return reverse('event-list')


class EventUpdateView(UpdateView):
template_name: str = "plan/event_update.html"
form_class: type = EventForm
model = Event

def get_success_url(self):
return reverse('event-list')
31 changes: 31 additions & 0 deletions Shops/beauty_saloon/homeworks/djando_hw/todo/templates/base.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<!-- Кодировка веб-страницы -->
<meta charset="utf-8">
<!-- Настройка viewport -->
<meta name="viewport" content="width=device-width, initial-scale=1">
{% block title %}<title>Base title</title>{% endblock %}
<!-- Bootstrap CSS (jsDelivr CDN) -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<!-- Bootstrap Bundle JS (jsDelivr CDN) -->
<script defer src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
</head>

<body>
<div class="center-block ">

<nav class="navbar navbar-expand-lg navbar-light bg-light justify-content-center nav-pills nav-fill">
<div class="nav-item">
<a {% block bar_list %}class="nav-link"{% endblock %} href="{% url 'event-list' %}">Все события</a>
</div>
<div class="nav-item">
<a {% block bar_add %}class="nav-link" {% endblock %} href="{% url 'event-add' %}">Добавить событие</a>
</div>
</nav>

{% block sidebar %}<!-- insert default navigation text for every page -->{% endblock %}
{% block content %}<!-- default content text (typically empty) -->{% endblock %}
</div>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{% extends "base.html" %}

{% block bar_add %}class="nav-link active" {% endblock %}


{% block content %}

<form action="" method="post">
{% csrf_token %}

<div class="d-grid gap-2 col-6 mx-auto">
<h3 class="h2 my-3">Добавить событие</h3>

<div class="input-group input-group-sm mb-3">
<span class="input-group-text">Название</span>
{{ form.title }}
</div>

<div class="input-group input-group-sm mb-3">
<span class="input-group-text" >Описание</span>
{{ form.description }}
</div>

<div class="input-group input-group-sm mb-3">
<span class="input-group-text" >Статус</span>
{{ form.status }}
</div>

<div class="input-group input-group-sm mb-3">
<span class="input-group-text" >Зависит от</span>
{{ form.depends_on }}
</div>

<div class="input-group input-group-sm mb-3">
<span class="input-group-text" id="title-descr">Старт</span>
{{ form.started_at }}
<span class="input-group-text" id="title-descr">Дэдлайн</span>
{{ form.finished_at }}
</div>

{{form.started_at.errors}}
{{form.finished_at.errors}}

<button class="btn btn-primary" type="submit">
Создать событие
</button>

</div>
</form>

{% endblock %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{% extends "base.html" %}
{% csrf_token %}

{% block content %}


<form method="post">
{% csrf_token %}
<div class="d-grid gap-2 col-6 mx-auto">
<h3 class="h4 my-4">А ты уверен, что хочешь удалить событие "{{ object.title }}"?</h3>

{{ form }}

<button class="btn btn-primary btn-danger" type="submit">
Удалить событие
</button>

</div>
</form>

{% endblock %}
Loading