Coverage for src/django_resume/plugins/projects.py: 47%
68 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-10-13 13:17 +0200
« prev ^ index » next coverage.py v7.6.1, created at 2024-10-13 13:17 +0200
1import json
3from typing import Type, Any
5from django import forms
7from .base import ListPlugin, ListItemFormMixin, ListTemplates, ListInline
10class ProjectItemForm(ListItemFormMixin, forms.Form):
11 title = forms.CharField(widget=forms.TextInput())
12 url = forms.URLField(widget=forms.URLInput(), required=False, assume_scheme="https")
13 description = forms.CharField(widget=forms.Textarea())
14 initial_badges = ["Some Badge", "Another Badge"]
15 badges = forms.JSONField(
16 widget=forms.TextInput(), required=False, initial=initial_badges
17 )
18 position = forms.IntegerField(widget=forms.NumberInput(), required=False)
20 def __init__(self, *args, **kwargs):
21 super().__init__(*args, **kwargs)
22 self.set_initial_position()
24 def badges_as_json(self):
25 """
26 Return the initial badges which should already be a normal list of strings
27 or the initial_badged list for the first render of the form encoded as json.
28 """
29 existing_badges = self.initial.get("badges")
30 if existing_badges is not None:
31 return json.dumps(existing_badges)
32 return json.dumps(self.initial_badges)
34 @staticmethod
35 def get_initial() -> dict[str, Any]:
36 """Just some default values."""
37 return {
38 "title": "Project Title",
39 "url": "https://example.com/project/",
40 "description": "description",
41 "badges": ProjectItemForm.initial_badges,
42 }
44 def set_context(self, item: dict, context: dict[str, Any]) -> dict[str, Any]:
45 context["project"] = {
46 "id": item["id"],
47 "url": item["url"],
48 "title": item["title"],
49 "description": item["description"],
50 "badges": item["badges"],
51 "edit_url": context["edit_url"],
52 "delete_url": context["delete_url"],
53 }
54 return context
56 def set_initial_badges(self):
57 """Transform the list of badges into a comma-separated string."""
58 if "badges" in self.initial and isinstance(self.initial["badges"], list):
59 self.initial["badges"] = ",".join(self.initial["badges"])
61 @staticmethod
62 def get_max_position(items):
63 """Return the maximum position value from the existing items."""
64 positions = [item.get("position", 0) for item in items]
65 return max(positions) if positions else -1
67 def set_initial_position(self):
68 """Set the position to the next available position."""
69 if "position" not in self.initial:
70 self.initial["position"] = self.get_max_position(self.existing_items) + 1
72 def clean_title(self):
73 title = self.cleaned_data["title"]
74 if title == "Senor Developer":
75 print("No Senor! Validation Error!")
76 raise forms.ValidationError("No Senor!")
77 return title
79 def clean_position(self):
80 position = self.cleaned_data.get("position", 0)
81 if position < 0:
82 raise forms.ValidationError("Position must be a positive integer.")
83 for item in self.existing_items:
84 if item["id"] == self.cleaned_data["id"]:
85 # updating the existing item, so we can skip checking its position
86 continue
87 if item.get("position") == position:
88 max_position = self.get_max_position(self.existing_items)
89 raise forms.ValidationError(
90 f"Position must be unique - take {max_position + 1} instead."
91 )
92 return position
95class ProjectFlatForm(forms.Form):
96 title = forms.CharField(
97 widget=forms.TextInput(), required=False, max_length=50, initial="Projects"
98 )
100 @staticmethod
101 def set_context(item: dict, context: dict[str, Any]) -> dict[str, Any]:
102 context["projects"] = {"title": item.get("title", "")}
103 context["projects"]["edit_flat_url"] = context["edit_flat_url"]
104 return context
107class ProjectsPlugin(ListPlugin):
108 name: str = "projects"
109 verbose_name: str = "Projects"
110 inline: ListInline
111 templates = ListTemplates(
112 main="django_resume/projects/plain/content.html",
113 flat="django_resume/projects/plain/flat.html",
114 flat_form="django_resume/projects/plain/flat_form.html",
115 item="django_resume/projects/plain/item.html",
116 item_form="django_resume/projects/plain/item_form.html",
117 )
118 flat_form_class = ProjectFlatForm
120 @staticmethod
121 def get_form_classes() -> dict[str, Type[forms.Form]]:
122 return {"item": ProjectItemForm, "flat": ProjectFlatForm}