Skip to content

Commit e27e64f

Browse files
committed
update apps
1 parent 79195d9 commit e27e64f

File tree

21 files changed

+457
-118
lines changed

21 files changed

+457
-118
lines changed

db.sqlite3

56 KB
Binary file not shown.

labels/forms.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
2+
from django.contrib.auth.models import User
3+
from django import forms
4+
from .models import Label
5+
6+
7+
class LabelForm(forms.ModelForm):
8+
class Meta:
9+
model = Label
10+
fields = ['name']

labels/migrations/0001_initial.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Generated by Django 5.2.1 on 2025-06-18 13:45
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
initial = True
9+
10+
dependencies = [
11+
]
12+
13+
operations = [
14+
migrations.CreateModel(
15+
name='Label',
16+
fields=[
17+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
18+
('name', models.CharField(max_length=100, unique=True)),
19+
('created_at', models.DateTimeField(auto_now_add=True)),
20+
],
21+
),
22+
]

labels/tests.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,31 @@
1+
# tasks/tests/test_labels.py
12
from django.test import TestCase
3+
from django.urls import reverse
4+
from labels.models import Label
5+
from tasks.models import Task
6+
from django.contrib.auth import get_user_model
27

3-
# Create your tests here.
8+
User = get_user_model()
9+
10+
class LabelCRUDTest(TestCase):
11+
def setUp(self):
12+
self.label = Label.objects.create(name='Bug')
13+
self.user = User.objects.create_user(username='testuser', password='12345')
14+
self.client.login(username='testuser', password='12345')
15+
16+
def test_label_list(self):
17+
response = self.client.get(reverse('label-list'))
18+
self.assertEqual(response.status_code, 200)
19+
self.assertContains(response, 'Bug')
20+
21+
def test_label_create(self):
22+
response = self.client.post(reverse('label-create'), {'name': 'Feature'})
23+
self.assertEqual(response.status_code, 302)
24+
self.assertTrue(Label.objects.filter(name='Feature').exists())
25+
26+
def test_label_delete_with_tasks(self):
27+
task = Task.objects.create(title='Test', author=self.user)
28+
task.labels.add(self.label)
29+
response = self.client.post(reverse('label-delete', args=[self.label.id]))
30+
self.assertEqual(response.status_code, 302)
31+
self.assertTrue(Label.objects.filter(id=self.label.id).exists()) # Метка не удалена

labels/urls.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from django.contrib import admin
2+
from django.contrib.auth.views import LogoutView
3+
from django.urls import path
4+
from django.views.generic import TemplateView
5+
from labels.views import LabelListView, LabelCreateView, LabelUpdateView, LabelDeleteView
6+
7+
8+
urlpatterns = [
9+
path('labels/', LabelListView.as_view(), name='label-list'),
10+
path('labels/create/', LabelCreateView.as_view(), name='label-create'),
11+
path('labels/<int:pk>/update/', LabelUpdateView.as_view(), name='label-update'),
12+
path('labels/<int:pk>/delete/', LabelDeleteView.as_view(), name='label-delete'),
13+
]

labels/views.py

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
from django.contrib.auth.mixins import LoginRequiredMixin
22
from django.views.generic import ListView, CreateView, UpdateView, DeleteView
3-
from django.urls import reverse_lazy
3+
from django.urls import reverse_lazy, reverse
44
from django.contrib import messages
55
from .models import Label
66
from .forms import LabelForm
7+
from django.shortcuts import render, redirect
8+
from django.contrib.messages.views import SuccessMessageMixin
9+
710

811
class LabelListView(LoginRequiredMixin, ListView):
912
model = Label
@@ -20,4 +23,37 @@ def form_valid(self, form):
2023
messages.success(self.request, "Метка успешно создана")
2124
return super().form_valid(form)
2225

23-
# Добавьте другие представления для меток (обновление, удаление и т.д.)
26+
27+
class LabelListView(LoginRequiredMixin, ListView):
28+
model = Label
29+
template_name = 'labels/label_list.html'
30+
context_object_name = 'labels'
31+
32+
33+
class LabelCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView):
34+
model = Label
35+
form_class = LabelForm
36+
template_name = 'labels/label_form.html'
37+
success_url = reverse_lazy('label-list')
38+
success_message = "Метка успешно создана"
39+
40+
41+
class LabelUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView):
42+
model = Label
43+
form_class = LabelForm
44+
template_name = 'labels/label_form.html'
45+
success_url = reverse_lazy('label-list')
46+
success_message = "Метка успешно изменена"
47+
48+
49+
class LabelDeleteView(LoginRequiredMixin, DeleteView):
50+
model = Label
51+
template_name = 'labels/label_confirm_delete.html'
52+
success_url = reverse_lazy('label-list')
53+
54+
def form_valid(self, form):
55+
if self.object.tasks.exists():
56+
messages.error(self.request, "Нельзя удалить метку, связанную с задачами")
57+
return redirect(reverse('label-list'))
58+
messages.success(self.request, "Метка успешно удалена")
59+
return super().form_valid(form)

statuses/forms.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
2+
from django.contrib.auth.models import User
3+
from django import forms
4+
from statuses.models import Status
5+
6+
7+
class StatusForm(forms.ModelForm):
8+
class Meta:
9+
model = Status
10+
fields = ['name']
11+
12+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Generated by Django 5.2.1 on 2025-06-18 13:45
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
initial = True
9+
10+
dependencies = [
11+
]
12+
13+
operations = [
14+
migrations.CreateModel(
15+
name='Status',
16+
fields=[
17+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
18+
('name', models.CharField(max_length=100, unique=True)),
19+
('created_at', models.DateTimeField(auto_now_add=True)),
20+
],
21+
),
22+
]

statuses/models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from django.db import models
2+
from django.contrib.auth.models import User
23

34
class Status(models.Model):
45
name = models.CharField(max_length=100, unique=True)

statuses/tests.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,25 @@
11
from django.test import TestCase
2+
from django.urls import reverse
3+
from django.contrib.messages import get_messages
4+
from django.contrib.auth import get_user_model
5+
from statuses.models import Status
26

3-
# Create your tests here.
7+
class StatusUpdateTest(TestCase):
8+
def setUp(self):
9+
self.user = get_user_model().objects.create_user(username='testuser', password='12345')
10+
self.client.force_login(self.user)
11+
self.status = Status.objects.create(name='Initial Status')
12+
13+
def test_status_update(self):
14+
url = reverse('status-update', args=[self.status.id])
15+
data = {'name': 'Обновлённый статус'}
16+
response = self.client.post(url, data)
17+
self.assertEqual(response.status_code, 302) # редирект
18+
19+
# Следующий запрос — страница списка, куда редиректит
20+
response = self.client.get(reverse('status-list'))
21+
messages = list(get_messages(response.wsgi_request))
22+
23+
print('Сообщения:', [str(m) for m in messages]) # Для отладки
24+
25+
self.assertTrue(any('Статус успешно обновлен.' in str(m) for m in messages))

0 commit comments

Comments
 (0)