defined Meta ordering of the Item() model in apps.dashboard.models; Item() also now returns a __str__ result; in .forms, defined a specific use-case of is_valid() method; a pair of new UTs in .tests.test_models help confirm str representation and list order of items; .test_forms now ensures the .is-invalid bootstrap class is tested as a css class attr; migrations run; full UT & FT suite back to passing state (tho a refactor of flimsy form customizations is desperately needed)
This commit is contained in:
@@ -19,6 +19,12 @@ class ItemForm(forms.models.ModelForm):
|
|||||||
}
|
}
|
||||||
error_messages = {"text": {"required": EMPTY_ITEM_ERROR}}
|
error_messages = {"text": {"required": EMPTY_ITEM_ERROR}}
|
||||||
|
|
||||||
|
def is_valid(self):
|
||||||
|
result = super().is_valid()
|
||||||
|
if not result:
|
||||||
|
self.fields["text"].widget.attrs["class"] += " is-invalid"
|
||||||
|
return result
|
||||||
|
|
||||||
def save(self, for_list):
|
def save(self, for_list):
|
||||||
self.instance.list = for_list
|
self.instance.list = for_list
|
||||||
return super().save()
|
return super().save()
|
||||||
|
|||||||
17
src/apps/dashboard/migrations/0005_alter_item_options.py
Normal file
17
src/apps/dashboard/migrations/0005_alter_item_options.py
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# Generated by Django 6.0 on 2026-01-24 17:54
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('dashboard', '0004_alter_item_unique_together'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='item',
|
||||||
|
options={'ordering': ('id',)},
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -4,11 +4,15 @@ from django.urls import reverse
|
|||||||
class List(models.Model):
|
class List(models.Model):
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse("view_list", args=[self.id])
|
return reverse("view_list", args=[self.id])
|
||||||
|
|
||||||
|
|
||||||
class Item(models.Model):
|
class Item(models.Model):
|
||||||
text = models.TextField(default="")
|
text = models.TextField(default="")
|
||||||
list = models.ForeignKey(List, default=None, on_delete=models.CASCADE)
|
list = models.ForeignKey(List, default=None, on_delete=models.CASCADE)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
ordering = ("id",)
|
||||||
unique_together = ("list", "text")
|
unique_together = ("list", "text")
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.text
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,15 @@ class ItemFormTest(TestCase):
|
|||||||
self.assertFalse(form.is_valid())
|
self.assertFalse(form.is_valid())
|
||||||
self.assertEqual(form.errors["text"], [EMPTY_ITEM_ERROR])
|
self.assertEqual(form.errors["text"], [EMPTY_ITEM_ERROR])
|
||||||
|
|
||||||
|
def test_invalid_form_has_bootstrap_is_invalid_css_class(self):
|
||||||
|
form = ItemForm(data={"text": ""})
|
||||||
|
self.assertFalse(form.is_valid())
|
||||||
|
field = form.fields["text"]
|
||||||
|
self.assertEqual(
|
||||||
|
field.widget.attrs["class"],
|
||||||
|
"form-control form-control-lg is-invalid",
|
||||||
|
)
|
||||||
|
|
||||||
def test_form_save_handles_saving_to_a_list(self):
|
def test_form_save_handles_saving_to_a_list(self):
|
||||||
mylist = List.objects.create()
|
mylist = List.objects.create()
|
||||||
form = ItemForm(data={"text": "do re mi"})
|
form = ItemForm(data={"text": "do re mi"})
|
||||||
|
|||||||
@@ -41,7 +41,21 @@ class ItemModelTest(TestCase):
|
|||||||
item = Item(list=list2, text="nojk")
|
item = Item(list=list2, text="nojk")
|
||||||
item.full_clean() # should not raise
|
item.full_clean() # should not raise
|
||||||
|
|
||||||
|
def test_string_representation(self):
|
||||||
|
item = Item(text="sample text")
|
||||||
|
self.assertEqual(str(item), "sample text")
|
||||||
|
|
||||||
class ListModelTest(TestCase):
|
class ListModelTest(TestCase):
|
||||||
def test_get_absolute_url(self):
|
def test_get_absolute_url(self):
|
||||||
mylist = List.objects.create()
|
mylist = List.objects.create()
|
||||||
self.assertEqual(mylist.get_absolute_url(), f"/apps/dashboard/{mylist.id}/")
|
self.assertEqual(mylist.get_absolute_url(), f"/apps/dashboard/{mylist.id}/")
|
||||||
|
|
||||||
|
def test_list_items_order(self):
|
||||||
|
list1 = List.objects.create()
|
||||||
|
item1 = Item.objects.create(list=list1, text="i1")
|
||||||
|
item2 = Item.objects.create(list=list1, text="item 2")
|
||||||
|
item3 = Item.objects.create(list=list1, text="3")
|
||||||
|
self.assertEqual(
|
||||||
|
list(list1.item_set.all()),
|
||||||
|
[item1, item2, item3],
|
||||||
|
)
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
from django.core.exceptions import ValidationError
|
|
||||||
from django.shortcuts import redirect, render
|
from django.shortcuts import redirect, render
|
||||||
from .forms import ExistingListItemForm, ItemForm
|
from .forms import ExistingListItemForm, ItemForm
|
||||||
from .models import Item, List
|
from .models import Item, List
|
||||||
|
|
||||||
def home_page(request):
|
def home_page(request):
|
||||||
return render(request, 'apps/dashboard/home.html', {"form": ItemForm()})
|
return render(request, "apps/dashboard/home.html", {"form": ItemForm()})
|
||||||
|
|
||||||
def new_list(request):
|
def new_list(request):
|
||||||
form = ItemForm(data=request.POST)
|
form = ItemForm(data=request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
nulist = List.objects.create()
|
nulist = List.objects.create()
|
||||||
Item.objects.create(text=request.POST["text"], list=nulist)
|
form.save(for_list=nulist)
|
||||||
return redirect(nulist)
|
return redirect(nulist)
|
||||||
else:
|
else:
|
||||||
return render(request, "apps/dashboard/home.html", {"form": form})
|
return render(request, "apps/dashboard/home.html", {"form": form})
|
||||||
@@ -24,5 +23,5 @@ def view_list(request, list_id):
|
|||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
form.save()
|
||||||
return redirect(our_list)
|
return redirect(our_list)
|
||||||
return render(request, 'apps/dashboard/list.html', {'list': our_list, "form": form})
|
return render(request, "apps/dashboard/list.html", {"list": our_list, "form": form})
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user