1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119 | from django import forms
from mywebsite.todos.models import Todo, List, todo_id_gen
from django.core.exceptions import ValidationError
# todo move these constants to their own file
EMPTY_ITEM_ERROR = "You can't have an empty list item"
DUPLICATE_ITEM_ERROR = "This item has already been entered"
TODO_TITLE_DUPE = "Can't save a todo that has the same text as title"
class GenericForm(forms.models.ModelForm):
placeholder_text = None
class Meta:
model = None
widgets = None
fields = ("text",)
labels = {
"text": "",
}
error_messages = {
"text": {"required": EMPTY_ITEM_ERROR},
}
def validate_unique(self) -> None:
try:
self.instance.validate_unique()
except ValidationError as e:
e.error_dict = {"text": [DUPLICATE_ITEM_ERROR]}
self._update_errors(e)
def create_widget(placeholder_text, extra_attr: dict = None):
attrs = {
"placeholder": f"{placeholder_text}",
"class": "form-control input-lg",
}
if extra_attr:
attrs = attrs | extra_attr
return {"text": forms.TextInput(attrs=attrs)}
class TodoForm(GenericForm):
def __init__(self, for_list=None, *args, **kwargs):
super().__init__(*args, **kwargs)
self.instance.list = for_list
# self.fields["text"].validators.append(validate_unique)
class Meta(GenericForm.Meta):
model = Todo
placeholder_text = "Enter a todo"
widgets = create_widget(placeholder_text)
def save(self, owner, pk):
if owner and pk:
return Todo.objects.create(
text=self.cleaned_data["text"],
list=owner.list_set.get(id=pk),
todo_id=todo_id_gen(),
)
def validate_unique(self) -> None:
try:
val = self.data.get("text")
todos_for_list = list(self.instance.list.todo_set.all())
if val == todos_for_list[0].text:
raise ValidationError(TODO_TITLE_DUPE)
for todo in todos_for_list[1:]:
if todo.text == val:
raise ValidationError(DUPLICATE_ITEM_ERROR)
except ValidationError as e:
self._update_errors(e)
class ListForm(GenericForm):
def __init__(self, queryset=None, *args, **kwargs):
self.queryset = queryset
super().__init__(*args, **kwargs)
class Meta(GenericForm.Meta):
model = Todo
widgets = create_widget("Enter a title for list. Press enter to submit.")
def save(self, owner):
if owner:
return List.create_new(text=self.cleaned_data["text"], owner=owner)
def validate_unique(self) -> None:
try:
val = self.data.get("text")
tmp_list = list(self.queryset)
all_lists_name = []
for list_obj in tmp_list:
try:
if list_obj.name:
all_lists_name.append(list_obj.name)
except AttributeError as e:
"""list_obj does not yet exist and thus does not have name"""
continue
if val in all_lists_name:
raise ValidationError(DUPLICATE_ITEM_ERROR)
except ValidationError as e:
self._update_errors(e)
class EditForm(GenericForm):
class Meta(GenericForm.Meta):
model = Todo
widgets = create_widget("Enter a new title", extra_attr={"id": "edit-form"})
class EditTodoForm(GenericForm):
class Meta(GenericForm.Meta):
model = Todo
widgets = create_widget("Edit Todo entry", extra_attr={"id": "edit-todo-form"})
|