update validators and wording
This commit is contained in:
@@ -34,7 +34,10 @@ class MemberForm(forms.ModelForm):
|
|||||||
}
|
}
|
||||||
|
|
||||||
help_texts = {
|
help_texts = {
|
||||||
"image": _("Mindestgröße: 150*150 px, Verwendbare Formate: ..."),
|
"image": _(
|
||||||
|
"Mindestdimension: 150*150 px, maximale Größe: 10MB, "
|
||||||
|
"erlaubtes Format: Bildformat"
|
||||||
|
),
|
||||||
"mailaccount": _("Die Mailadresse mit '@fet.at' angeben."),
|
"mailaccount": _("Die Mailadresse mit '@fet.at' angeben."),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,6 +75,7 @@ class JobGroupForm(forms.ModelForm):
|
|||||||
"shortterm": _("Kürzel des Tätigkeitsbereichs"),
|
"shortterm": _("Kürzel des Tätigkeitsbereichs"),
|
||||||
"description": _("Beschreibung des Tätigkeitsbereichs"),
|
"description": _("Beschreibung des Tätigkeitsbereichs"),
|
||||||
"is_pinned": _(
|
"is_pinned": _(
|
||||||
"Dieser Tätigkeitsbereich soll im Fachschaftsbereich angeheftet werden, damit es sofort ersichtlich ist."
|
"Dieser Tätigkeitsbereich soll im Fachschaftsbereich angeheftet werden, "
|
||||||
|
"damit es sofort ersichtlich ist."
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|||||||
36
fet2020/members/migrations/0003_auto_20210506_1808.py
Normal file
36
fet2020/members/migrations/0003_auto_20210506_1808.py
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
# Generated by Django 3.1.5 on 2021-05-06 16:08
|
||||||
|
|
||||||
|
import django.core.validators
|
||||||
|
from django.db import migrations, models
|
||||||
|
import easy_thumbnails.fields
|
||||||
|
import members.validators
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('members', '0002_auto_20210412_2158'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='member',
|
||||||
|
name='image',
|
||||||
|
field=easy_thumbnails.fields.ThumbnailerImageField(upload_to='uploads/members/image/', validators=[members.validators.validate_file_size, members.validators.validate_image_dimension]),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='member',
|
||||||
|
name='mailaccount',
|
||||||
|
field=models.CharField(error_messages={'unique': 'Diese Mailadresse existiert schon.'}, max_length=128, unique=True, validators=[django.core.validators.EmailValidator(), members.validators.validate_domainonly_email], verbose_name='Mailadresse'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='member',
|
||||||
|
name='phone',
|
||||||
|
field=models.CharField(blank=True, max_length=17, validators=[members.validators.PhoneNumberValidator()]),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='member',
|
||||||
|
name='username',
|
||||||
|
field=models.CharField(blank=True, max_length=128, verbose_name='fet.at Benutzername'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.core.validators import RegexValidator, ValidationError
|
from django.core.validators import ValidationError, validate_email
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.text import slugify
|
from django.utils.text import slugify
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from easy_thumbnails.fields import ThumbnailerImageField
|
from easy_thumbnails.fields import ThumbnailerImageField
|
||||||
|
|
||||||
from .managers import (
|
from .managers import (
|
||||||
ActiveJobMemberManager,
|
ActiveJobMemberManager,
|
||||||
InactiveJobMemberManager,
|
InactiveJobMemberManager,
|
||||||
@@ -14,6 +14,12 @@ from .managers import (
|
|||||||
JobGroupManager,
|
JobGroupManager,
|
||||||
MemberManager,
|
MemberManager,
|
||||||
)
|
)
|
||||||
|
from .validators import (
|
||||||
|
PhoneNumberValidator,
|
||||||
|
validate_domainonly_email,
|
||||||
|
validate_file_size,
|
||||||
|
validate_image_dimension,
|
||||||
|
)
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -24,10 +30,18 @@ class Member(models.Model):
|
|||||||
nickname = models.CharField("Spitzname", max_length=128)
|
nickname = models.CharField("Spitzname", max_length=128)
|
||||||
|
|
||||||
# LDAP Username
|
# LDAP Username
|
||||||
username = models.CharField("Benutzername", blank=True, max_length=128)
|
username = models.CharField("fet.at Benutzername", max_length=128, blank=True)
|
||||||
|
|
||||||
# fet mail account
|
# fet mail account
|
||||||
mailaccount = models.CharField("Mailadresse", unique=True, max_length=128)
|
mailaccount = models.CharField(
|
||||||
|
"Mailadresse",
|
||||||
|
unique=True,
|
||||||
|
max_length=128,
|
||||||
|
validators=[validate_email, validate_domainonly_email],
|
||||||
|
error_messages={
|
||||||
|
'unique': _("Diese Mailadresse existiert schon."),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
class MemberRole(models.TextChoices):
|
class MemberRole(models.TextChoices):
|
||||||
ACTIVE = "A", _("Active")
|
ACTIVE = "A", _("Active")
|
||||||
@@ -41,17 +55,19 @@ class Member(models.Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
description = models.TextField(null=True, blank=True)
|
description = models.TextField(null=True, blank=True)
|
||||||
image = ThumbnailerImageField(upload_to="uploads/members/image/")
|
|
||||||
|
image = ThumbnailerImageField(
|
||||||
|
upload_to="uploads/members/image/",
|
||||||
|
validators=[validate_file_size, validate_image_dimension],
|
||||||
|
)
|
||||||
|
|
||||||
birthday = models.DateField(null=True, blank=True)
|
birthday = models.DateField(null=True, blank=True)
|
||||||
|
|
||||||
phone_error_msg = _(
|
phone = models.CharField(
|
||||||
(
|
max_length=17,
|
||||||
"Phone number must be entered in the format: +999999999'. Up to 15 digits allowed."
|
blank=True,
|
||||||
)
|
validators=[PhoneNumberValidator()],
|
||||||
)
|
)
|
||||||
phone_regex = RegexValidator(regex=r"^\+?1?\d{9,15}$", message=phone_error_msg)
|
|
||||||
phone = models.CharField(validators=[phone_regex], max_length=17, blank=True)
|
|
||||||
|
|
||||||
address = models.TextField(null=True, blank=True)
|
address = models.TextField(null=True, blank=True)
|
||||||
|
|
||||||
@@ -70,16 +86,6 @@ class Member(models.Model):
|
|||||||
if not self.image:
|
if not self.image:
|
||||||
raise ValidationError(_("Es fehlt das Profilbild."))
|
raise ValidationError(_("Es fehlt das Profilbild."))
|
||||||
|
|
||||||
if self.image.height < 150 or self.image.width < 150:
|
|
||||||
raise ValidationError(
|
|
||||||
_("Das Bild ist zu klein. (Höhe: {}, Breite: {})").format(
|
|
||||||
self.image.height, self.image.width
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if not "@fet.at" in self.mailaccount:
|
|
||||||
raise ValidationError(_("In der Mailadresse fehlt die Domäne."))
|
|
||||||
|
|
||||||
if self.username:
|
if self.username:
|
||||||
try:
|
try:
|
||||||
user = User.objects.get(username=self.username.lower())
|
user = User.objects.get(username=self.username.lower())
|
||||||
@@ -140,15 +146,15 @@ class Job(models.Model):
|
|||||||
verbose_name = "Tätigkeit"
|
verbose_name = "Tätigkeit"
|
||||||
verbose_name_plural = "Tätigkeiten"
|
verbose_name_plural = "Tätigkeiten"
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
if not self.slug:
|
if not self.slug:
|
||||||
self.slug = slugify(self.shortterm)
|
self.slug = slugify(self.shortterm)
|
||||||
|
|
||||||
super().save(*args, **kwargs)
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.name
|
|
||||||
|
|
||||||
|
|
||||||
class JobMember(models.Model):
|
class JobMember(models.Model):
|
||||||
member = models.ForeignKey(
|
member = models.ForeignKey(
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ from .models import Member, Job, JobGroup
|
|||||||
from .forms import MemberForm, JobForm, JobGroupForm
|
from .forms import MemberForm, JobForm, JobGroupForm
|
||||||
|
|
||||||
|
|
||||||
|
image_path = os.path.join(os.path.dirname(__file__), "tests/files/peter.jpg")
|
||||||
|
|
||||||
class MemberTestCase(TestCase):
|
class MemberTestCase(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
member = Member()
|
member = Member()
|
||||||
@@ -24,12 +26,10 @@ class MemberTestCase(TestCase):
|
|||||||
|
|
||||||
|
|
||||||
class MemberFormTestCase(TestCase):
|
class MemberFormTestCase(TestCase):
|
||||||
def test_form(self):
|
def test_basic_form(self):
|
||||||
image = SimpleUploadedFile(
|
image = SimpleUploadedFile(
|
||||||
name="peter.jpg",
|
name="peter.jpg",
|
||||||
content=open(
|
content=open(image_path, "rb").read(),
|
||||||
os.path.join(os.path.dirname(__file__), "tests/files/peter.jpg"), "rb"
|
|
||||||
).read(),
|
|
||||||
content_type="image/jpeg",
|
content_type="image/jpeg",
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -50,6 +50,32 @@ class MemberFormTestCase(TestCase):
|
|||||||
member = Member.objects.get(firstname="Peter")
|
member = Member.objects.get(firstname="Peter")
|
||||||
self.assertEqual(member.__str__(), "Peter Traunmüller")
|
self.assertEqual(member.__str__(), "Peter Traunmüller")
|
||||||
|
|
||||||
|
def test_advanced_form(self):
|
||||||
|
# test blank fields, like phone number
|
||||||
|
image = SimpleUploadedFile(
|
||||||
|
name="peter.jpg",
|
||||||
|
content=open(image_path, "rb").read(),
|
||||||
|
content_type="image/jpeg",
|
||||||
|
)
|
||||||
|
|
||||||
|
form = MemberForm(
|
||||||
|
data={
|
||||||
|
"firstname": "Peter",
|
||||||
|
"surname": "Traunmüller",
|
||||||
|
"nickname": "Pet",
|
||||||
|
"mailaccount": "peter@fet.at",
|
||||||
|
"role": "A",
|
||||||
|
"phone": "+4364412345678",
|
||||||
|
},
|
||||||
|
files={"image": image},
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertTrue(form.is_valid())
|
||||||
|
form.save()
|
||||||
|
|
||||||
|
member = Member.objects.get(firstname="Peter")
|
||||||
|
self.assertEqual(member.phone, "+4364412345678")
|
||||||
|
|
||||||
def test_form_error_no_image(self):
|
def test_form_error_no_image(self):
|
||||||
form = MemberForm(
|
form = MemberForm(
|
||||||
data={
|
data={
|
||||||
@@ -62,7 +88,84 @@ class MemberFormTestCase(TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.assertFalse(form.is_valid())
|
self.assertFalse(form.is_valid())
|
||||||
self.assertEqual(form.errors.as_data()['__all__'][0].message, "Es fehlt das Profilbild.")
|
self.assertEqual(
|
||||||
|
form.errors.as_data()['__all__'][0].message,
|
||||||
|
"Es fehlt das Profilbild."
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_form_wrong_mailaccount(self):
|
||||||
|
image = SimpleUploadedFile(
|
||||||
|
name="peter.jpg",
|
||||||
|
content=open(image_path, "rb").read(),
|
||||||
|
content_type="image/jpeg",
|
||||||
|
)
|
||||||
|
|
||||||
|
form = MemberForm(
|
||||||
|
data={
|
||||||
|
"firstname": "Peter",
|
||||||
|
"surname": "Traunmüller",
|
||||||
|
"nickname": "Pet",
|
||||||
|
"mailaccount": "peter@feet.at",
|
||||||
|
"role": "A",
|
||||||
|
},
|
||||||
|
files={"image": image},
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertFalse(form.is_valid())
|
||||||
|
self.assertEqual(
|
||||||
|
form.errors.as_data()['mailaccount'][0].message,
|
||||||
|
"In der Mailadresse fehlt die richtige Domäne."
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_form_wrong_domain(self):
|
||||||
|
image = SimpleUploadedFile(
|
||||||
|
name="peter.jpg",
|
||||||
|
content=open(image_path, "rb").read(),
|
||||||
|
content_type="image/jpeg",
|
||||||
|
)
|
||||||
|
|
||||||
|
form = MemberForm(
|
||||||
|
data={
|
||||||
|
"firstname": "Peter",
|
||||||
|
"surname": "Traunmüller",
|
||||||
|
"nickname": "Pet",
|
||||||
|
"mailaccount": "peterfet.at",
|
||||||
|
"role": "A",
|
||||||
|
},
|
||||||
|
files={"image": image},
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertFalse(form.is_valid())
|
||||||
|
self.assertEqual(
|
||||||
|
form.errors.as_data()['mailaccount'][0].message,
|
||||||
|
"Gib eine gültige E-Mail Adresse an."
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_form_wrong_phone_number(self):
|
||||||
|
image = SimpleUploadedFile(
|
||||||
|
name="peter.jpg",
|
||||||
|
content=open(image_path, "rb").read(),
|
||||||
|
content_type="image/jpeg",
|
||||||
|
)
|
||||||
|
|
||||||
|
form = MemberForm(
|
||||||
|
data={
|
||||||
|
"firstname": "Peter",
|
||||||
|
"surname": "Traunmüller",
|
||||||
|
"nickname": "Pet",
|
||||||
|
"mailaccount": "peter@fet.at",
|
||||||
|
"role": "A",
|
||||||
|
"phone": "+43644+12345678",
|
||||||
|
},
|
||||||
|
files={"image": image},
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertFalse(form.is_valid())
|
||||||
|
self.assertEqual(
|
||||||
|
form.errors.as_data()['phone'][0].message,
|
||||||
|
"Telefonnummer muss in diesem Format +999999999999 eingegeben werden. "
|
||||||
|
"Bis zu 15 Zahlen sind erlaubt."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class JobGroupFormTestCase(TestCase):
|
class JobGroupFormTestCase(TestCase):
|
||||||
|
|||||||
31
fet2020/members/validators.py
Normal file
31
fet2020/members/validators.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
from django.core.validators import RegexValidator, ValidationError
|
||||||
|
from django.utils.deconstruct import deconstructible
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
|
@deconstructible
|
||||||
|
class PhoneNumberValidator(RegexValidator):
|
||||||
|
regex = r"^\+?1?\d{9,15}$"
|
||||||
|
message = _(
|
||||||
|
"Telefonnummer muss in diesem Format +999999999999 eingegeben werden. "
|
||||||
|
"Bis zu 15 Zahlen sind erlaubt."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def validate_domainonly_email(value):
|
||||||
|
if not "fet.at" in value:
|
||||||
|
raise ValidationError(_("In der Mailadresse fehlt die richtige Domäne."))
|
||||||
|
|
||||||
|
def validate_file_size(value):
|
||||||
|
if value.size > 10 * 1024 * 1024:
|
||||||
|
raise ValidationError(_("Die maximale Dateigröße ist 10MB."))
|
||||||
|
|
||||||
|
def validate_image_dimension(value):
|
||||||
|
if value.height < 150 or value.width < 150:
|
||||||
|
raise ValidationError(
|
||||||
|
_("Das Bild ist zu klein. (Höhe: %(height)s, Breite: %(width)s)"),
|
||||||
|
params={
|
||||||
|
"height": value.height,
|
||||||
|
"width": value.width,
|
||||||
|
}
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user