dajanga2 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. dajanga2-0.1.0/Dajanga2/__init__.py +2 -0
  2. dajanga2-0.1.0/Dajanga2/cli.py +46 -0
  3. dajanga2-0.1.0/Dajanga2/template/ggggg/manage.py +3 -0
  4. dajanga2-0.1.0/MANIFEST.in +3 -0
  5. dajanga2-0.1.0/PKG-INFO +34 -0
  6. dajanga2-0.1.0/README.md +19 -0
  7. dajanga2-0.1.0/dajanga2.egg-info/PKG-INFO +34 -0
  8. dajanga2-0.1.0/dajanga2.egg-info/SOURCES.txt +31 -0
  9. dajanga2-0.1.0/dajanga2.egg-info/dependency_links.txt +1 -0
  10. dajanga2-0.1.0/dajanga2.egg-info/entry_points.txt +2 -0
  11. dajanga2-0.1.0/dajanga2.egg-info/top_level.txt +1 -0
  12. dajanga2-0.1.0/korochki_starter/template/korochki/asgi.py +6 -0
  13. dajanga2-0.1.0/korochki_starter/template/korochki/settings.py +64 -0
  14. dajanga2-0.1.0/korochki_starter/template/korochki/urls.py +7 -0
  15. dajanga2-0.1.0/korochki_starter/template/korochki/wsgi.py +6 -0
  16. dajanga2-0.1.0/korochki_starter/template/main/admin.py +13 -0
  17. dajanga2-0.1.0/korochki_starter/template/main/apps.py +6 -0
  18. dajanga2-0.1.0/korochki_starter/template/main/forms.py +65 -0
  19. dajanga2-0.1.0/korochki_starter/template/main/models.py +39 -0
  20. dajanga2-0.1.0/korochki_starter/template/main/static/main/style.css +9 -0
  21. dajanga2-0.1.0/korochki_starter/template/main/templates/main/admin_login.html +11 -0
  22. dajanga2-0.1.0/korochki_starter/template/main/templates/main/admin_panel.html +36 -0
  23. dajanga2-0.1.0/korochki_starter/template/main/templates/main/applications.html +17 -0
  24. dajanga2-0.1.0/korochki_starter/template/main/templates/main/base.html +32 -0
  25. dajanga2-0.1.0/korochki_starter/template/main/templates/main/create_application.html +10 -0
  26. dajanga2-0.1.0/korochki_starter/template/main/templates/main/index.html +6 -0
  27. dajanga2-0.1.0/korochki_starter/template/main/templates/main/login.html +13 -0
  28. dajanga2-0.1.0/korochki_starter/template/main/templates/main/register.html +10 -0
  29. dajanga2-0.1.0/korochki_starter/template/main/urls.py +14 -0
  30. dajanga2-0.1.0/korochki_starter/template/main/views.py +101 -0
  31. dajanga2-0.1.0/korochki_starter/template/manage.py +21 -0
  32. dajanga2-0.1.0/pyproject.toml +30 -0
  33. dajanga2-0.1.0/setup.cfg +4 -0
@@ -0,0 +1,2 @@
1
+ """Dajanga2 package - simple copier of bundled `ggggg` template."""
2
+ __version__ = "0.1.0"
@@ -0,0 +1,46 @@
1
+ """CLI that copies the bundled `ggggg` folder to the current working directory.
2
+
3
+ Usage: dajanga-start
4
+
5
+ The command will copy the packaged `template/ggggg` directory into the
6
+ current working directory. If a folder with the same name already exists,
7
+ the command will abort.
8
+ """
9
+ from __future__ import annotations
10
+
11
+ import shutil
12
+ import sys
13
+ from pathlib import Path
14
+
15
+
16
+ TEMPLATE_NAME = "ggggg"
17
+
18
+
19
+ def main(argv: list[str] | None = None) -> int:
20
+ """Entry point for the CLI. Copies template into cwd/TEMPLATE_NAME."""
21
+ argv = list(argv) if argv is not None else []
22
+
23
+ dest = Path.cwd() / TEMPLATE_NAME
24
+ if dest.exists():
25
+ print(f"Error: destination '{dest}' already exists. Aborting.")
26
+ return 2
27
+
28
+ # locate package template directory
29
+ this_dir = Path(__file__).resolve().parent
30
+ template_dir = this_dir / "template" / TEMPLATE_NAME
31
+ if not template_dir.exists():
32
+ print("Error: packaged template not found inside the package.")
33
+ return 3
34
+
35
+ try:
36
+ print(f"Copying template '{TEMPLATE_NAME}' to: {dest}")
37
+ shutil.copytree(template_dir, dest)
38
+ print("Copy finished successfully.")
39
+ return 0
40
+ except Exception as exc:
41
+ print(f"Error while copying template: {exc}")
42
+ return 1
43
+
44
+
45
+ if __name__ == "__main__":
46
+ raise SystemExit(main())
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env python
2
+ """Placeholder manage.py inside packaged template."""
3
+ print("This is a packaged template file placeholder. Replace with real project files.")
@@ -0,0 +1,3 @@
1
+ recursive-include korochki_starter/template *
2
+ recursive-include Dajanga2/template *
3
+ include README.md
@@ -0,0 +1,34 @@
1
+ Metadata-Version: 2.1
2
+ Name: dajanga2
3
+ Version: 0.1.0
4
+ Summary: CLI tool to copy bundled ggggg folder into current directory
5
+ Author: Auto Generated
6
+ License: MIT
7
+ Keywords: django,template,starter,cli
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3 :: Only
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Topic :: Software Development :: Build Tools
13
+ Requires-Python: >=3.10
14
+ Description-Content-Type: text/markdown
15
+
16
+ korochki-starter
17
+ =================
18
+
19
+ Утилита CLI для разворачивания шаблона Django-проекта из пакета.
20
+
21
+ Сборка и установка локально:
22
+
23
+ ```powershell
24
+ python -m build
25
+ pip install dist\korochki_starter-0.1.0-py3-none-any.whl
26
+ ```
27
+
28
+ После установки доступна команда:
29
+
30
+ ```powershell
31
+ korochki-start myproject
32
+ ```
33
+
34
+ Это создаст папку `myproject/` с шаблоном и выполнит замену всех вхождений `korochki` на `myproject`.
@@ -0,0 +1,19 @@
1
+ korochki-starter
2
+ =================
3
+
4
+ Утилита CLI для разворачивания шаблона Django-проекта из пакета.
5
+
6
+ Сборка и установка локально:
7
+
8
+ ```powershell
9
+ python -m build
10
+ pip install dist\korochki_starter-0.1.0-py3-none-any.whl
11
+ ```
12
+
13
+ После установки доступна команда:
14
+
15
+ ```powershell
16
+ korochki-start myproject
17
+ ```
18
+
19
+ Это создаст папку `myproject/` с шаблоном и выполнит замену всех вхождений `korochki` на `myproject`.
@@ -0,0 +1,34 @@
1
+ Metadata-Version: 2.1
2
+ Name: dajanga2
3
+ Version: 0.1.0
4
+ Summary: CLI tool to copy bundled ggggg folder into current directory
5
+ Author: Auto Generated
6
+ License: MIT
7
+ Keywords: django,template,starter,cli
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3 :: Only
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Topic :: Software Development :: Build Tools
13
+ Requires-Python: >=3.10
14
+ Description-Content-Type: text/markdown
15
+
16
+ korochki-starter
17
+ =================
18
+
19
+ Утилита CLI для разворачивания шаблона Django-проекта из пакета.
20
+
21
+ Сборка и установка локально:
22
+
23
+ ```powershell
24
+ python -m build
25
+ pip install dist\korochki_starter-0.1.0-py3-none-any.whl
26
+ ```
27
+
28
+ После установки доступна команда:
29
+
30
+ ```powershell
31
+ korochki-start myproject
32
+ ```
33
+
34
+ Это создаст папку `myproject/` с шаблоном и выполнит замену всех вхождений `korochki` на `myproject`.
@@ -0,0 +1,31 @@
1
+ MANIFEST.in
2
+ README.md
3
+ pyproject.toml
4
+ Dajanga2/__init__.py
5
+ Dajanga2/cli.py
6
+ Dajanga2/template/ggggg/manage.py
7
+ dajanga2.egg-info/PKG-INFO
8
+ dajanga2.egg-info/SOURCES.txt
9
+ dajanga2.egg-info/dependency_links.txt
10
+ dajanga2.egg-info/entry_points.txt
11
+ dajanga2.egg-info/top_level.txt
12
+ korochki_starter/template/manage.py
13
+ korochki_starter/template/korochki/asgi.py
14
+ korochki_starter/template/korochki/settings.py
15
+ korochki_starter/template/korochki/urls.py
16
+ korochki_starter/template/korochki/wsgi.py
17
+ korochki_starter/template/main/admin.py
18
+ korochki_starter/template/main/apps.py
19
+ korochki_starter/template/main/forms.py
20
+ korochki_starter/template/main/models.py
21
+ korochki_starter/template/main/urls.py
22
+ korochki_starter/template/main/views.py
23
+ korochki_starter/template/main/static/main/style.css
24
+ korochki_starter/template/main/templates/main/admin_login.html
25
+ korochki_starter/template/main/templates/main/admin_panel.html
26
+ korochki_starter/template/main/templates/main/applications.html
27
+ korochki_starter/template/main/templates/main/base.html
28
+ korochki_starter/template/main/templates/main/create_application.html
29
+ korochki_starter/template/main/templates/main/index.html
30
+ korochki_starter/template/main/templates/main/login.html
31
+ korochki_starter/template/main/templates/main/register.html
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ dajanga-start = Dajanga2.cli:main
@@ -0,0 +1 @@
1
+ Dajanga2
@@ -0,0 +1,6 @@
1
+ import os
2
+ from django.core.asgi import get_asgi_application
3
+
4
+ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "korochki.settings")
5
+
6
+ application = get_asgi_application()
@@ -0,0 +1,64 @@
1
+ from pathlib import Path
2
+
3
+ # Basic settings copied from example template
4
+ BASE_DIR = Path(__file__).resolve().parent.parent
5
+
6
+ SECRET_KEY = "replace-me"
7
+ DEBUG = True
8
+ ALLOWED_HOSTS = []
9
+
10
+ INSTALLED_APPS = [
11
+ "django.contrib.admin",
12
+ "django.contrib.auth",
13
+ "django.contrib.contenttypes",
14
+ "django.contrib.sessions",
15
+ "django.contrib.messages",
16
+ "django.contrib.staticfiles",
17
+ "main",
18
+ ]
19
+
20
+ MIDDLEWARE = [
21
+ "django.middleware.security.SecurityMiddleware",
22
+ "django.contrib.sessions.middleware.SessionMiddleware",
23
+ "django.middleware.common.CommonMiddleware",
24
+ "django.middleware.csrf.CsrfViewMiddleware",
25
+ "django.contrib.auth.middleware.AuthenticationMiddleware",
26
+ "django.contrib.messages.middleware.MessageMiddleware",
27
+ "django.middleware.clickjacking.XFrameOptionsMiddleware",
28
+ ]
29
+
30
+ ROOT_URLCONF = "korochki.urls"
31
+
32
+ TEMPLATES = [
33
+ {
34
+ "BACKEND": "django.template.backends.django.DjangoTemplates",
35
+ "DIRS": [],
36
+ "APP_DIRS": True,
37
+ "OPTIONS": {
38
+ "context_processors": [
39
+ "django.template.context_processors.debug",
40
+ "django.template.context_processors.request",
41
+ "django.contrib.auth.context_processors.auth",
42
+ "django.contrib.messages.context_processors.messages",
43
+ ],
44
+ },
45
+ },
46
+ ]
47
+
48
+ WSGI_APPLICATION = "korochki.wsgi.application"
49
+
50
+ DATABASES = {
51
+ "default": {
52
+ "ENGINE": "django.db.backends.sqlite3",
53
+ "NAME": BASE_DIR / "db.sqlite3",
54
+ }
55
+ }
56
+
57
+ LANGUAGE_CODE = "ru-ru"
58
+ TIME_ZONE = "UTC"
59
+ USE_I18N = True
60
+ USE_TZ = True
61
+
62
+ STATIC_URL = "static/"
63
+
64
+ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
@@ -0,0 +1,7 @@
1
+ from django.contrib import admin
2
+ from django.urls import path, include
3
+
4
+ urlpatterns = [
5
+ path("admin/", admin.site.urls),
6
+ path("", include("main.urls")),
7
+ ]
@@ -0,0 +1,6 @@
1
+ import os
2
+ from django.core.wsgi import get_wsgi_application
3
+
4
+ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "korochki.settings")
5
+
6
+ application = get_wsgi_application()
@@ -0,0 +1,13 @@
1
+ from django.contrib import admin
2
+ from .models import Profile, Application
3
+
4
+
5
+ @admin.register(Profile)
6
+ class ProfileAdmin(admin.ModelAdmin):
7
+ list_display = ("user", "full_name", "phone")
8
+
9
+
10
+ @admin.register(Application)
11
+ class ApplicationAdmin(admin.ModelAdmin):
12
+ list_display = ("user", "course_name", "start_date", "payment_method", "status", "created_at")
13
+ list_filter = ("status", "payment_method")
@@ -0,0 +1,6 @@
1
+ from django.apps import AppConfig
2
+
3
+
4
+ class MainConfig(AppConfig):
5
+ default_auto_field = "django.db.models.BigAutoField"
6
+ name = "main"
@@ -0,0 +1,65 @@
1
+ from django import forms
2
+ from django.contrib.auth.models import User
3
+ from .models import Application
4
+ import re
5
+
6
+
7
+ class RegistrationForm(forms.Form):
8
+ username = forms.CharField(label="Логин", max_length=150)
9
+ password1 = forms.CharField(label="Пароль", widget=forms.PasswordInput)
10
+ password2 = forms.CharField(label="Повтор пароля", widget=forms.PasswordInput)
11
+ full_name = forms.CharField(label="ФИО", max_length=200)
12
+ phone = forms.CharField(label="Телефон", max_length=20)
13
+ email = forms.EmailField(label="Email")
14
+
15
+ def clean_username(self):
16
+ username = self.cleaned_data["username"]
17
+ if not re.match(r"^[A-Za-z0-9]{6,}$", username):
18
+ raise forms.ValidationError("Логин должен содержать латиницу и цифры, не менее 6 символов")
19
+ if User.objects.filter(username=username).exists():
20
+ raise forms.ValidationError("Пользователь с таким логином уже существует")
21
+ return username
22
+
23
+ def clean_password1(self):
24
+ p = self.cleaned_data["password1"]
25
+ if len(p) < 8:
26
+ raise forms.ValidationError("Пароль минимум 8 символов")
27
+ return p
28
+
29
+ def clean(self):
30
+ cleaned = super().clean()
31
+ p1 = cleaned.get("password1")
32
+ p2 = cleaned.get("password2")
33
+ if p1 and p2 and p1 != p2:
34
+ raise forms.ValidationError("Пароли не совпадают")
35
+ full = cleaned.get("full_name")
36
+ if full and not re.match(r"^[А-Яа-яЁё\s]+$", full):
37
+ self.add_error("full_name", "ФИО должно содержать только кириллицу и пробелы")
38
+ phone = cleaned.get("phone")
39
+ if phone and not re.match(r"^8\(\d{3}\)\d{3}-\d{2}-\d{2}$", phone):
40
+ self.add_error("phone", "Телефон в формате 8(XXX)XXX-XX-XX")
41
+
42
+ def save(self):
43
+ data = self.cleaned_data
44
+ user = User.objects.create_user(username=data["username"], email=data["email"])
45
+ user.set_password(data["password1"])
46
+ user.save()
47
+ # create profile
48
+ from .models import Profile
49
+
50
+ Profile.objects.create(user=user, full_name=data["full_name"], phone=data["phone"])
51
+ return user
52
+
53
+
54
+ class LoginForm(forms.Form):
55
+ username = forms.CharField(label="Логин")
56
+ password = forms.CharField(label="Пароль", widget=forms.PasswordInput)
57
+
58
+
59
+ class ApplicationForm(forms.ModelForm):
60
+ class Meta:
61
+ model = Application
62
+ fields = ["course_name", "start_date", "payment_method"]
63
+ widgets = {
64
+ "start_date": forms.DateInput(attrs={"type": "date"}),
65
+ }
@@ -0,0 +1,39 @@
1
+ from django.db import models
2
+ from django.contrib.auth.models import User
3
+
4
+
5
+ class Profile(models.Model):
6
+ user = models.OneToOneField(User, on_delete=models.CASCADE)
7
+ full_name = models.CharField(max_length=200)
8
+ phone = models.CharField(max_length=20)
9
+
10
+ def __str__(self):
11
+ return f"{self.user.username} - {self.full_name}"
12
+
13
+
14
+ class Application(models.Model):
15
+ PAYMENT_CHOICES = [
16
+ ("cash", "Наличными"),
17
+ ("phone", "Перевод по номеру телефона"),
18
+ ]
19
+
20
+ STATUS_NEW = "NEW"
21
+ STATUS_IN_PROGRESS = "IN_PROGRESS"
22
+ STATUS_COMPLETED = "COMPLETED"
23
+
24
+ STATUS_CHOICES = [
25
+ (STATUS_NEW, "Новая"),
26
+ (STATUS_IN_PROGRESS, "Идет обучение"),
27
+ (STATUS_COMPLETED, "Обучение завершено"),
28
+ ]
29
+
30
+ user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="applications")
31
+ course_name = models.CharField(max_length=200)
32
+ start_date = models.DateField()
33
+ payment_method = models.CharField(max_length=20, choices=PAYMENT_CHOICES)
34
+ status = models.CharField(max_length=20, choices=STATUS_CHOICES, default=STATUS_NEW)
35
+ review = models.TextField(blank=True, null=True)
36
+ created_at = models.DateTimeField(auto_now_add=True)
37
+
38
+ def __str__(self):
39
+ return f"{self.course_name} ({self.user.username}) - {self.status}"
@@ -0,0 +1,9 @@
1
+ body{font-family: Arial, sans-serif; margin:20px; color:#222}
2
+ header{border-bottom:1px solid #ddd; padding-bottom:10px; margin-bottom:20px}
3
+ nav a{margin-right:10px}
4
+ form{max-width:480px}
5
+ input,select,textarea{display:block;margin:6px 0;padding:6px;width:100%;box-sizing:border-box}
6
+ button{padding:8px 12px}
7
+ table{border-collapse:collapse;width:100%}
8
+ table th,table td{border:1px solid #ccc;padding:6px}
9
+ .error{color:#900}
@@ -0,0 +1,11 @@
1
+ {% extends 'main/base.html' %}
2
+ {% block content %}
3
+ <h2>Вход в панель администратора</h2>
4
+ {% if error %}<div class="error">{{ error }}</div>{% endif %}
5
+ <form method="post">
6
+ {% csrf_token %}
7
+ <p><label>Логин: <input name="username" value="Admin"></label></p>
8
+ <p><label>Пароль: <input type="password" name="password"></label></p>
9
+ <button type="submit">Войти</button>
10
+ </form>
11
+ {% endblock %}
@@ -0,0 +1,36 @@
1
+ {% extends 'main/base.html' %}
2
+ {% block content %}
3
+ <h2>Панель администратора</h2>
4
+ <p><a href="{% url 'admin_logout' %}">Выйти из панели</a></p>
5
+ {% if applications %}
6
+ <table>
7
+ <thead><tr><th>ID</th><th>Пользователь</th><th>Курс</th><th>Дата</th><th>Оплата</th><th>Статус</th><th>Действия</th></tr></thead>
8
+ <tbody>
9
+ {% for a in applications %}
10
+ <tr>
11
+ <td>{{ a.id }}</td>
12
+ <td>{{ a.user.username }}</td>
13
+ <td>{{ a.course_name }}</td>
14
+ <td>{{ a.start_date }}</td>
15
+ <td>{{ a.get_payment_method_display }}</td>
16
+ <td>{{ a.get_status_display }}</td>
17
+ <td>
18
+ <form method="post" style="display:inline">
19
+ {% csrf_token %}
20
+ <input type="hidden" name="app_id" value="{{ a.id }}">
21
+ <select name="status">
22
+ <option value="NEW" {% if a.status == 'NEW' %}selected{% endif %}>Новая</option>
23
+ <option value="IN_PROGRESS" {% if a.status == 'IN_PROGRESS' %}selected{% endif %}>Идет обучение</option>
24
+ <option value="COMPLETED" {% if a.status == 'COMPLETED' %}selected{% endif %}>Обучение завершено</option>
25
+ </select>
26
+ <button type="submit">Сменить</button>
27
+ </form>
28
+ </td>
29
+ </tr>
30
+ {% endfor %}
31
+ </tbody>
32
+ </table>
33
+ {% else %}
34
+ <p>Заявок нет.</p>
35
+ {% endif %}
36
+ {% endblock %}
@@ -0,0 +1,17 @@
1
+ {% extends 'main/base.html' %}
2
+ {% block content %}
3
+ <h2>Мои заявки</h2>
4
+ {% if applications %}
5
+ <ul>
6
+ {% for a in applications %}
7
+ <li>
8
+ <strong>{{ a.course_name }}</strong> — {{ a.get_status_display }} — начало {{ a.start_date }}
9
+ <div>Оплата: {{ a.get_payment_method_display }}</div>
10
+ <div>Отзыв: {{ a.review|default:"(пока нет)" }}</div>
11
+ </li>
12
+ {% endfor %}
13
+ </ul>
14
+ {% else %}
15
+ <p>Заявок нет. <a href="{% url 'create_application' %}">Создать заявку</a></p>
16
+ {% endif %}
17
+ {% endblock %}
@@ -0,0 +1,32 @@
1
+ <!DOCTYPE html>
2
+ <html lang="ru">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>Корочки.есть</title>
7
+ <link rel="stylesheet" href="/static/main/style.css">
8
+ </head>
9
+ <body>
10
+ <header>
11
+ <h1>Портал «Корочки.есть»</h1>
12
+ <nav>
13
+ <a href="/">Главная</a>
14
+ {% if user.is_authenticated %}
15
+ <a href="{% url 'applications' %}">Мои заявки</a>
16
+ <a href="{% url 'create_application' %}">Новая заявка</a>
17
+ <a href="{% url 'logout' %}">Выход</a>
18
+ {% else %}
19
+ <a href="{% url 'login' %}">Вход</a>
20
+ <a href="{% url 'register' %}">Регистрация</a>
21
+ {% endif %}
22
+ <a href="{% url 'admin_login' %}">Панель администратора</a>
23
+ </nav>
24
+ </header>
25
+ <main>
26
+ {% block content %}{% endblock %}
27
+ </main>
28
+ <footer>
29
+ <p>Учебный проект — минимальный шаблон информационной системы</p>
30
+ </footer>
31
+ </body>
32
+ </html>
@@ -0,0 +1,10 @@
1
+ {% extends 'main/base.html' %}
2
+ {% block content %}
3
+ <h2>Новая заявка</h2>
4
+ <form method="post">
5
+ {% csrf_token %}
6
+ {{ form.as_p }}
7
+ <button type="submit">Отправить</button>
8
+ <p>Способ оплаты: Наличными или Перевод по номеру телефона</p>
9
+ </form>
10
+ {% endblock %}
@@ -0,0 +1,6 @@
1
+ {% extends 'main/base.html' %}
2
+ {% block content %}
3
+ <h2>Добро пожаловать</h2>
4
+ <p>Это минимальный шаблон портала для записи на курсы.</p>
5
+ <p>Зарегистрируйтесь и оставьте заявку на обучение.</p>
6
+ {% endblock %}
@@ -0,0 +1,13 @@
1
+ {% extends 'main/base.html' %}
2
+ {% block content %}
3
+ <h2>Авторизация</h2>
4
+ <form method="post">
5
+ {% csrf_token %}
6
+ {{ form.as_p }}
7
+ <button type="submit">Войти</button>
8
+ {% if form.non_field_errors %}
9
+ <div class="error">{{ form.non_field_errors }}</div>
10
+ {% endif %}
11
+ </form>
12
+ <p>Еще не зарегистрированы? <a href="{% url 'register' %}">Регистрация</a></p>
13
+ {% endblock %}
@@ -0,0 +1,10 @@
1
+ {% extends 'main/base.html' %}
2
+ {% block content %}
3
+ <h2>Регистрация</h2>
4
+ <form method="post">
5
+ {% csrf_token %}
6
+ {{ form.as_p }}
7
+ <button type="submit">Создать пользователя</button>
8
+ </form>
9
+ <p>Уже зарегистрированы? <a href="{% url 'login' %}">Вход</a></p>
10
+ {% endblock %}
@@ -0,0 +1,14 @@
1
+ from django.urls import path
2
+ from . import views
3
+
4
+ urlpatterns = [
5
+ path("", views.index, name="index"),
6
+ path("register/", views.register_view, name="register"),
7
+ path("login/", views.login_view, name="login"),
8
+ path("logout/", views.logout_view, name="logout"),
9
+ path("applications/", views.applications_view, name="applications"),
10
+ path("application/new/", views.create_application, name="create_application"),
11
+ path("admin-login/", views.admin_login, name="admin_login"),
12
+ path("admin-panel/", views.admin_panel, name="admin_panel"),
13
+ path("admin-logout/", views.admin_logout, name="admin_logout"),
14
+ ]
@@ -0,0 +1,101 @@
1
+ from django.shortcuts import render, redirect, get_object_or_404
2
+ from django.contrib.auth import authenticate, login, logout
3
+ from django.contrib.auth.decorators import login_required, user_passes_test
4
+ from .forms import RegistrationForm, LoginForm, ApplicationForm
5
+ from .models import Application
6
+
7
+
8
+ def index(request):
9
+ return render(request, "main/index.html")
10
+
11
+
12
+ def register_view(request):
13
+ if request.method == "POST":
14
+ form = RegistrationForm(request.POST)
15
+ if form.is_valid():
16
+ form.save()
17
+ return redirect("login")
18
+ else:
19
+ form = RegistrationForm()
20
+ return render(request, "main/register.html", {"form": form})
21
+
22
+
23
+ def login_view(request):
24
+ if request.method == "POST":
25
+ form = LoginForm(request.POST)
26
+ if form.is_valid():
27
+ user = authenticate(request, username=form.cleaned_data["username"], password=form.cleaned_data["password"])
28
+ if user:
29
+ login(request, user)
30
+ return redirect("applications")
31
+ else:
32
+ form.add_error(None, "Неверный логин или пароль")
33
+ else:
34
+ form = LoginForm()
35
+ return render(request, "main/login.html", {"form": form})
36
+
37
+
38
+ def logout_view(request):
39
+ logout(request)
40
+ return redirect("index")
41
+
42
+
43
+ @login_required
44
+ def applications_view(request):
45
+ apps = request.user.applications.all()
46
+ return render(request, "main/applications.html", {"applications": apps})
47
+
48
+
49
+ @login_required
50
+ def create_application(request):
51
+ if request.method == "POST":
52
+ form = ApplicationForm(request.POST)
53
+ if form.is_valid():
54
+ app = form.save(commit=False)
55
+ app.user = request.user
56
+ app.save()
57
+ return redirect("applications")
58
+ else:
59
+ form = ApplicationForm()
60
+ return render(request, "main/create_application.html", {"form": form})
61
+
62
+
63
+ def is_admin(user):
64
+ return user.is_superuser or (user.username == "Admin")
65
+
66
+
67
+ @user_passes_test(is_admin)
68
+ def admin_panel(request):
69
+ apps = Application.objects.all().order_by("-created_at")
70
+ if request.method == "POST":
71
+ app_id = request.POST.get("app_id")
72
+ status = request.POST.get("status")
73
+ app = get_object_or_404(Application, id=app_id)
74
+ app.status = status
75
+ app.save()
76
+ return render(request, "main/admin_panel.html", {"applications": apps})
77
+
78
+
79
+ def admin_login(request):
80
+ error = None
81
+ if request.method == "POST":
82
+ login_input = request.POST.get("username")
83
+ password_input = request.POST.get("password")
84
+ if login_input == "Admin" and password_input == "KorokNET":
85
+ from django.contrib.auth.models import User
86
+
87
+ user, created = User.objects.get_or_create(username="Admin", defaults={"is_staff": True, "is_superuser": True})
88
+ if created:
89
+ user.set_password("KorokNET")
90
+ user.save()
91
+ user = authenticate(request, username="Admin", password="KorokNET")
92
+ if user:
93
+ login(request, user)
94
+ return redirect("admin_panel")
95
+ error = "Неверный логин или пароль администратора"
96
+ return render(request, "main/admin_login.html", {"error": error})
97
+
98
+
99
+ def admin_logout(request):
100
+ logout(request)
101
+ return redirect("index")
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env python
2
+ """Django's command-line utility for administrative tasks."""
3
+ import os
4
+ import sys
5
+
6
+
7
+ def main():
8
+ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "korochki.settings")
9
+ try:
10
+ from django.core.management import execute_from_command_line
11
+ except ImportError as exc:
12
+ raise ImportError(
13
+ "Couldn't import Django. Are you sure it's installed and "
14
+ "available on your PYTHONPATH environment variable? Did you "
15
+ "forget to activate a virtual environment?"
16
+ ) from exc
17
+ execute_from_command_line(sys.argv)
18
+
19
+
20
+ if __name__ == "__main__":
21
+ main()
@@ -0,0 +1,30 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel", "build"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "dajanga2"
7
+ version = "0.1.0"
8
+ description = "CLI tool to copy bundled ggggg folder into current directory"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ authors = [ {name = "Auto Generated"} ]
12
+ license = {text = "MIT"}
13
+ classifiers = [
14
+ "License :: OSI Approved :: MIT License",
15
+ "Programming Language :: Python :: 3",
16
+ "Programming Language :: Python :: 3 :: Only",
17
+ "Programming Language :: Python :: 3.10",
18
+ "Topic :: Software Development :: Build Tools",
19
+ ]
20
+ keywords = ["django", "template", "starter", "cli"]
21
+
22
+ [project.scripts]
23
+ dajanga-start = "Dajanga2.cli:main"
24
+
25
+ [tool.setuptools]
26
+ include-package-data = true
27
+
28
+ [tool.setuptools.packages.find]
29
+ where = ["."]
30
+ include = ["Dajanga2*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+