Add initial Django project structure with cleaning app

- Created .gitignore to exclude Python-generated files and virtual environments.
- Added .python-version to specify Python version 3.13.
- Implemented models for Client, Brigade, Service, Order, and CompletedWork.
- Created Django admin configurations for managing models.
- Added management command to seed the database with test data.
- Created initial migrations for the models.
- Developed views and templates for listing and detailing orders, clients, and brigades.
- Set up URL routing for the cleaning app.
- Configured Django settings and WSGI/ASGI entry points.
- Added basic test structure in tests.py.
- Included project metadata in pyproject.toml and uv.lock.
This commit is contained in:
Dmitry
2026-05-16 16:09:37 +03:00
commit 97591a71ea
30 changed files with 867 additions and 0 deletions
+23
View File
@@ -0,0 +1,23 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}Клининг{% endblock %}</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css"
rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container">
<a class="navbar-brand" href="{% url 'cleaning:index' %}">Клининг</a>
<div>
<a class="nav-link text-white d-inline" href="{% url 'cleaning:order_list' %}">Заказы</a>
</div>
</div>
</nav>
<div class="container mt-4"> {% comment %} mt-4 - mergin-top {% endcomment %}
{% block content %}{% endblock %}
</div>
</body>
</html>
@@ -0,0 +1,43 @@
{% extends 'cleaning/base.html' %}
{% block title %}О бригаде{% endblock %}
{% block content %}
{# mb-4 — отступ снизу, чтобы карточка не прилипала к таблицам #}
<div class="card mb-4">
<div class="card-header"><h4>{{ brigade.name }}</h4></div>
<div class="card-body">
<p><strong>Руководитель:</strong> {{ brigade.supervisor }}</p>
<p><strong>Сотрудников:</strong> {{ brigade.employee_count }}</p>
<p><strong>Специализация:</strong> {{ brigade.specialization }}</p>
</div>
</div>
<h5>Активные заказы</h5>
<table class="table table-hover">
<thead><tr><th>Заказ</th><th>Клиент</th><th>Дата</th></tr></thead>
<tbody>
{% for order in active %}
<tr>
<td><a href="{% url 'cleaning:order_detail' order.pk %}">Заказ №{{ order.pk }}</a></td>
<td>{{ order.client }}</td>
<td>{{ order.date }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<h5 class="mt-4">Выполненные заказы</h5>
<table class="table table-hover">
<thead><tr><th>Заказ</th><th>Клиент</th><th>Дата</th></tr></thead>
<tbody>
{% for order in completed %}
<tr>
<td><a href="{% url 'cleaning:order_detail' order.pk %}">Заказ №{{ order.pk }}</a></td>
<td>{{ order.client }}</td>
<td>{{ order.date }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
@@ -0,0 +1,30 @@
{% extends 'cleaning/base.html' %}
{% block title %}О клиенте{% endblock %}
{% block content %}
{# card — карточка с основной информацией о клиенте #}
<div class="card mb-4">
<div class="card-header"><h4>{{ client.full_name }}</h4></div>
<div class="card-body">
<p><strong>Адрес:</strong> {{ client.address }}</p>
<p><strong>Телефон:</strong> {{ client.phone }}</p>
{# get_preferred_time_display — возвращает читаемое значение choices ('morning' → 'Утро') #}
<p><strong>Предпочтительное время:</strong> {{ client.get_preferred_time_display }}</p>
</div>
</div>
<h5>Заказы клиента</h5>
<table class="table table-hover">
<thead><tr><th>Заказ</th><th>Бригада</th><th>Дата</th></tr></thead>
<tbody>
{% for order in client.order_set.all %}
<tr>
<td><a href="{% url 'cleaning:order_detail' order.pk %}">Заказ №{{ order.pk }}</a></td>
<td>{{ order.brigade }}</td>
<td>{{ order.date }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
@@ -0,0 +1,36 @@
{% extends 'cleaning/base.html' %}
{% block title %}Детали заказа{% endblock %}
{% block content %}
{# card — Bootstrap-компонент для группировки информации #}
<div class="card">
<div class="card-header"><h4>Заказ №{{ order.pk }}</h4></div>
<div class="card-body">
<p><strong>Клиент:</strong> <a href="{% url 'cleaning:client_detail' order.client.pk %}">{{ order.client }}</a></p>
<p><strong>Бригада:</strong> <a href="{% url 'cleaning:brigade_detail' order.brigade.pk %}">{{ order.brigade }}</a></p>
<p><strong>Дата:</strong> {{ order.date }}</p>
<p><strong>Время:</strong> {{ order.start_time }} — {{ order.end_time }}</p>
</div>
</div>
<h5 class="mt-4">Выполненные работы</h5> {# mt-4 — отступ сверху #}
<table class="table table-striped">
<thead>
<tr><th>Услуга</th><th>Площадь, м²</th><th>Стоимость, руб.</th></tr>
</thead>
<tbody>
{% for work in order.completedwork_set.all %}
<tr>
<td>{{ work.service.name }}</td>
<td>{{ work.area }}</td>
<td>{{ work.cost }}</td>
</tr>
{% endfor %}
</tbody>
{# tfoot с table-group-divider — отделяет итоговую строку чертой #}
<tfoot class="table-group-divider">
<tr><td colspan="2"><strong>Итого</strong></td><td><strong>{{ order.total_cost }} руб.</strong></td></tr>
</tfoot>
</table>
{% endblock %}
@@ -0,0 +1,31 @@
{% extends 'cleaning/base.html' %}
{% block title %}Заказы{% endblock %}
{% block content %}
<h1>Список заказов</h1>
{# table-striped — чередование цвета строк, table-hover — подсветка при наведении #}
<table class="table table-striped table-hover">
<thead>
<tr>
<th></th>
<th>Клиент</th>
<th>Бригада</th>
<th>Детали</th>
<th>Дата</th>
</tr>
</thead>
<tbody>
{% for order in orders %}
<tr>
<td>{{ forloop.counter }}</td>
{# ссылки ведут на детали клиента, бригады и заказа #}
<td><a href="{% url 'cleaning:client_detail' order.client.pk %}">{{ order.client }}</a></td>
<td><a href="{% url 'cleaning:brigade_detail' order.brigade.pk %}">{{ order.brigade }}</a></td>
<td><a href="{% url 'cleaning:order_detail' order.pk %}">Заказ №{{ order.pk }}</a></td>
<td>{{ order.date }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}