From 5d6fc82eb98393ce1bc17010a99153f1edd5a5e4 Mon Sep 17 00:00:00 2001 From: Caitlin Barnard Date: Thu, 14 Nov 2024 15:19:04 +0000 Subject: [PATCH 1/4] Add validation for charFields and update error messaging --- payroll/forms.py | 41 +++++++++++++++---- .../templates/payroll/page/add_vacancy.html | 19 ++++++++- payroll/validators.py | 10 +++++ 3 files changed, 60 insertions(+), 10 deletions(-) create mode 100644 payroll/validators.py diff --git a/payroll/forms.py b/payroll/forms.py index 29760637..acc72724 100644 --- a/payroll/forms.py +++ b/payroll/forms.py @@ -1,9 +1,33 @@ from django import forms from payroll.models import Vacancy +from payroll.validators import validate_only_letters_numbers_spaces class VacancyForm(forms.ModelForm): + + appointee_name = forms.CharField( + validators=[ + lambda value: validate_only_letters_numbers_spaces(value, "Appointee name") + ], + widget=forms.TextInput(attrs={"class": "govuk-input govuk-input--width-20"}), + required=False, + ) + hiring_manager = forms.CharField( + validators=[ + lambda value: validate_only_letters_numbers_spaces(value, "Hiring manager") + ], + widget=forms.TextInput(attrs={"class": "govuk-input govuk-input--width-20"}), + required=False, + ) + hr_ref = forms.CharField( + validators=[ + lambda value: validate_only_letters_numbers_spaces(value, "HR ref") + ], + widget=forms.TextInput(attrs={"class": "govuk-input govuk-input--width-20"}), + required=False, + ) + class Meta: model = Vacancy fields = "__all__" @@ -13,13 +37,12 @@ class Meta: "grade": forms.Select(attrs={"class": "govuk-select"}), "recruitment_stage": forms.Select(attrs={"class": "govuk-select"}), "programme_code": forms.Select(attrs={"class": "govuk-select"}), - "appointee_name": forms.TextInput( - attrs={"class": "govuk-input govuk-input--width-20"} - ), - "hiring_manager": forms.TextInput( - attrs={"class": "govuk-input govuk-input--width-20"} - ), - "hr_ref": forms.TextInput( - attrs={"class": "govuk-input govuk-input--width-20"} - ), + } + error_messages = { + "grade": { + "required": "Grade is a required field.", + }, + "programme_code": { + "required": "Programme code is a required field.", + }, } diff --git a/payroll/templates/payroll/page/add_vacancy.html b/payroll/templates/payroll/page/add_vacancy.html index 7df2ae8f..b111db36 100644 --- a/payroll/templates/payroll/page/add_vacancy.html +++ b/payroll/templates/payroll/page/add_vacancy.html @@ -13,7 +13,24 @@ {% block content %}

Create Vacancy

-
+ {% if form.errors %} + + {% endif %} + + {% csrf_token %}
{% include "_form_field.html" with field=form.recruitment_type %} diff --git a/payroll/validators.py b/payroll/validators.py new file mode 100644 index 00000000..6672d9a2 --- /dev/null +++ b/payroll/validators.py @@ -0,0 +1,10 @@ +import re + +from django.forms import ValidationError + + +def validate_only_letters_numbers_spaces(value, field): + if not re.match(r"^[a-zA-Z0-9\s]*$", value): + raise ValidationError( + f"{ field } can only contain letters, numbers and spaces." + ) From 948af946860c9a45db8626cec173dbb3db2e15e6 Mon Sep 17 00:00:00 2001 From: Caitlin Barnard Date: Mon, 18 Nov 2024 12:17:49 +0000 Subject: [PATCH 2/4] Rework validation --- payroll/forms.py | 40 +++---------- ...0_alter_vacancy_appointee_name_and_more.py | 59 +++++++++++++++++++ payroll/models.py | 41 +++++++++++-- .../templates/payroll/page/add_vacancy.html | 31 +++------- .../payroll/partials/_error_summary.html | 26 ++++++++ .../{ => payroll/partials}/_form_field.html | 0 6 files changed, 137 insertions(+), 60 deletions(-) create mode 100644 payroll/migrations/0010_alter_vacancy_appointee_name_and_more.py create mode 100644 payroll/templates/payroll/partials/_error_summary.html rename payroll/templates/{ => payroll/partials}/_form_field.html (100%) diff --git a/payroll/forms.py b/payroll/forms.py index acc72724..d0efbc5a 100644 --- a/payroll/forms.py +++ b/payroll/forms.py @@ -5,29 +5,6 @@ class VacancyForm(forms.ModelForm): - - appointee_name = forms.CharField( - validators=[ - lambda value: validate_only_letters_numbers_spaces(value, "Appointee name") - ], - widget=forms.TextInput(attrs={"class": "govuk-input govuk-input--width-20"}), - required=False, - ) - hiring_manager = forms.CharField( - validators=[ - lambda value: validate_only_letters_numbers_spaces(value, "Hiring manager") - ], - widget=forms.TextInput(attrs={"class": "govuk-input govuk-input--width-20"}), - required=False, - ) - hr_ref = forms.CharField( - validators=[ - lambda value: validate_only_letters_numbers_spaces(value, "HR ref") - ], - widget=forms.TextInput(attrs={"class": "govuk-input govuk-input--width-20"}), - required=False, - ) - class Meta: model = Vacancy fields = "__all__" @@ -37,12 +14,13 @@ class Meta: "grade": forms.Select(attrs={"class": "govuk-select"}), "recruitment_stage": forms.Select(attrs={"class": "govuk-select"}), "programme_code": forms.Select(attrs={"class": "govuk-select"}), - } - error_messages = { - "grade": { - "required": "Grade is a required field.", - }, - "programme_code": { - "required": "Programme code is a required field.", - }, + "appointee_name": forms.TextInput( + attrs={"class": "govuk-input govuk-input--width-20"} + ), + "hiring_manager": forms.TextInput( + attrs={"class": "govuk-input govuk-input--width-20"} + ), + "hr_ref": forms.TextInput( + attrs={"class": "govuk-input govuk-input--width-20"} + ), } diff --git a/payroll/migrations/0010_alter_vacancy_appointee_name_and_more.py b/payroll/migrations/0010_alter_vacancy_appointee_name_and_more.py new file mode 100644 index 00000000..23dd74ba --- /dev/null +++ b/payroll/migrations/0010_alter_vacancy_appointee_name_and_more.py @@ -0,0 +1,59 @@ +# Generated by Django 4.2.16 on 2024-11-18 12:07 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("payroll", "0009_remove_vacancy_programme_switch_vacancy"), + ] + + operations = [ + migrations.AlterField( + model_name="vacancy", + name="appointee_name", + field=models.CharField( + blank=True, + max_length=255, + null=True, + validators=[ + django.core.validators.RegexValidator( + message="Only letters, spaces, - and ' are allowed", + regex="^[a-zA-Z '-]*$", + ) + ], + ), + ), + migrations.AlterField( + model_name="vacancy", + name="hiring_manager", + field=models.CharField( + blank=True, + max_length=255, + null=True, + validators=[ + django.core.validators.RegexValidator( + message="Only letters, spaces, - and ' are allowed", + regex="^[a-zA-Z '-]*$", + ) + ], + ), + ), + migrations.AlterField( + model_name="vacancy", + name="hr_ref", + field=models.CharField( + blank=True, + max_length=255, + null=True, + validators=[ + django.core.validators.RegexValidator( + message="Only letters, spaces, - and ' are allowed", + regex="^[a-zA-Z '-]*$", + ) + ], + ), + ), + ] diff --git a/payroll/models.py b/payroll/models.py index 9ce1e5e9..a9f998f2 100644 --- a/payroll/models.py +++ b/payroll/models.py @@ -1,4 +1,5 @@ from django.db import models +from django.core.validators import RegexValidator class Employee(models.Model): @@ -142,9 +143,7 @@ class Meta: cost_centre = models.ForeignKey("costcentre.CostCentre", models.PROTECT) grade = models.ForeignKey("gifthospitality.Grade", models.PROTECT) - programme_code = models.ForeignKey( - "chartofaccountDIT.ProgrammeCode", models.PROTECT - ) + programme_code = models.ForeignKey("chartofaccountDIT.ProgrammeCode", models.PROTECT) recruitment_type = models.CharField( max_length=29, choices=RecruitmentType.choices, @@ -154,6 +153,36 @@ class Meta: choices=RecruitmentStage.choices, default=RecruitmentStage.PREPARING ) - appointee_name = models.CharField(max_length=255, null=True, blank=True) - hiring_manager = models.CharField(max_length=255, null=True, blank=True) - hr_ref = models.CharField(max_length=255, null=True, blank=True) + appointee_name = models.CharField( + max_length=255, + null=True, + blank=True, + validators=[ + RegexValidator( + regex=r"^[a-zA-Z '-]*$", + message="Only letters, spaces, - and ' are allowed", + ) + ], + ) + hiring_manager = models.CharField( + max_length=255, + null=True, + blank=True, + validators=[ + RegexValidator( + regex=r"^[a-zA-Z '-]*$", + message="Only letters, spaces, - and ' are allowed", + ) + ], + ) + hr_ref = models.CharField( + max_length=255, + null=True, + blank=True, + validators=[ + RegexValidator( + regex=r"^[a-zA-Z '-]*$", + message="Only letters, spaces, - and ' are allowed", + ) + ], + ) diff --git a/payroll/templates/payroll/page/add_vacancy.html b/payroll/templates/payroll/page/add_vacancy.html index b111db36..e824fa8e 100644 --- a/payroll/templates/payroll/page/add_vacancy.html +++ b/payroll/templates/payroll/page/add_vacancy.html @@ -13,33 +13,18 @@ {% block content %}

Create Vacancy

- {% if form.errors %} - - {% endif %} + {% include "payroll/partials/_error_summary.html" with form=form %} {% csrf_token %}
- {% include "_form_field.html" with field=form.recruitment_type %} - {% include "_form_field.html" with field=form.grade %} - {% include "_form_field.html" with field=form.recruitment_stage %} - {% include "_form_field.html" with field=form.programme_code %} - {% include "_form_field.html" with field=form.appointee_name %} - {% include "_form_field.html" with field=form.hiring_manager %} - {% include "_form_field.html" with field=form.hr_ref %} + {% include "payroll/partials/_form_field.html" with field=form.recruitment_type %} + {% include "payroll/partials/_form_field.html" with field=form.grade %} + {% include "payroll/partials/_form_field.html" with field=form.recruitment_stage %} + {% include "payroll/partials/_form_field.html" with field=form.programme_code %} + {% include "payroll/partials/_form_field.html" with field=form.appointee_name %} + {% include "payroll/partials/_form_field.html" with field=form.hiring_manager %} + {% include "payroll/partials/_form_field.html" with field=form.hr_ref %}
Back diff --git a/payroll/templates/payroll/partials/_error_summary.html b/payroll/templates/payroll/partials/_error_summary.html new file mode 100644 index 00000000..e0864dfb --- /dev/null +++ b/payroll/templates/payroll/partials/_error_summary.html @@ -0,0 +1,26 @@ +{% if form.errors %} + +{% endif %} \ No newline at end of file diff --git a/payroll/templates/_form_field.html b/payroll/templates/payroll/partials/_form_field.html similarity index 100% rename from payroll/templates/_form_field.html rename to payroll/templates/payroll/partials/_form_field.html From 956fd1d2299284913553e2ddc2229226a3e733fd Mon Sep 17 00:00:00 2001 From: Caitlin Barnard Date: Mon, 18 Nov 2024 13:50:14 +0000 Subject: [PATCH 3/4] Remove validator --- payroll/forms.py | 1 - payroll/models.py | 6 ++++-- payroll/validators.py | 10 ---------- 3 files changed, 4 insertions(+), 13 deletions(-) delete mode 100644 payroll/validators.py diff --git a/payroll/forms.py b/payroll/forms.py index d0efbc5a..29760637 100644 --- a/payroll/forms.py +++ b/payroll/forms.py @@ -1,7 +1,6 @@ from django import forms from payroll.models import Vacancy -from payroll.validators import validate_only_letters_numbers_spaces class VacancyForm(forms.ModelForm): diff --git a/payroll/models.py b/payroll/models.py index a9f998f2..dbce930e 100644 --- a/payroll/models.py +++ b/payroll/models.py @@ -1,5 +1,5 @@ -from django.db import models from django.core.validators import RegexValidator +from django.db import models class Employee(models.Model): @@ -143,7 +143,9 @@ class Meta: cost_centre = models.ForeignKey("costcentre.CostCentre", models.PROTECT) grade = models.ForeignKey("gifthospitality.Grade", models.PROTECT) - programme_code = models.ForeignKey("chartofaccountDIT.ProgrammeCode", models.PROTECT) + programme_code = models.ForeignKey( + "chartofaccountDIT.ProgrammeCode", models.PROTECT + ) recruitment_type = models.CharField( max_length=29, choices=RecruitmentType.choices, diff --git a/payroll/validators.py b/payroll/validators.py deleted file mode 100644 index 6672d9a2..00000000 --- a/payroll/validators.py +++ /dev/null @@ -1,10 +0,0 @@ -import re - -from django.forms import ValidationError - - -def validate_only_letters_numbers_spaces(value, field): - if not re.match(r"^[a-zA-Z0-9\s]*$", value): - raise ValidationError( - f"{ field } can only contain letters, numbers and spaces." - ) From 068279bbfb243d52b457a82a8bedf421d0a91dc6 Mon Sep 17 00:00:00 2001 From: Caitlin Barnard Date: Mon, 18 Nov 2024 13:54:05 +0000 Subject: [PATCH 4/4] Update validation method --- ...1_alter_vacancy_appointee_name_and_more.py | 59 +++++++++++++++++++ payroll/models.py | 6 +- 2 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 payroll/migrations/0011_alter_vacancy_appointee_name_and_more.py diff --git a/payroll/migrations/0011_alter_vacancy_appointee_name_and_more.py b/payroll/migrations/0011_alter_vacancy_appointee_name_and_more.py new file mode 100644 index 00000000..61a1897a --- /dev/null +++ b/payroll/migrations/0011_alter_vacancy_appointee_name_and_more.py @@ -0,0 +1,59 @@ +# Generated by Django 4.2.16 on 2024-11-18 13:52 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("payroll", "0010_alter_vacancy_appointee_name_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="vacancy", + name="appointee_name", + field=models.CharField( + blank=True, + max_length=255, + null=True, + validators=[ + django.core.validators.RegexValidator( + message="Only letters, spaces, - and ' are allowed.", + regex="^[a-zA-Z '-]*$", + ) + ], + ), + ), + migrations.AlterField( + model_name="vacancy", + name="hiring_manager", + field=models.CharField( + blank=True, + max_length=255, + null=True, + validators=[ + django.core.validators.RegexValidator( + message="Only letters, spaces, - and ' are allowed.", + regex="^[a-zA-Z '-]*$", + ) + ], + ), + ), + migrations.AlterField( + model_name="vacancy", + name="hr_ref", + field=models.CharField( + blank=True, + max_length=255, + null=True, + validators=[ + django.core.validators.RegexValidator( + message="Only letters, spaces, - and ' are allowed.", + regex="^[a-zA-Z '-]*$", + ) + ], + ), + ), + ] diff --git a/payroll/models.py b/payroll/models.py index dbce930e..807c36d6 100644 --- a/payroll/models.py +++ b/payroll/models.py @@ -162,7 +162,7 @@ class Meta: validators=[ RegexValidator( regex=r"^[a-zA-Z '-]*$", - message="Only letters, spaces, - and ' are allowed", + message="Only letters, spaces, - and ' are allowed.", ) ], ) @@ -173,7 +173,7 @@ class Meta: validators=[ RegexValidator( regex=r"^[a-zA-Z '-]*$", - message="Only letters, spaces, - and ' are allowed", + message="Only letters, spaces, - and ' are allowed.", ) ], ) @@ -184,7 +184,7 @@ class Meta: validators=[ RegexValidator( regex=r"^[a-zA-Z '-]*$", - message="Only letters, spaces, - and ' are allowed", + message="Only letters, spaces, - and ' are allowed.", ) ], )