From db94ec41edd1204a76856eddab7291ffd19df094 Mon Sep 17 00:00:00 2001 From: moanos Date: Thu, 14 Nov 2024 18:28:55 +0100 Subject: [PATCH] feat: Add organization affiliation to user --- .../0017_user_organization_affiliation.py | 19 ++ src/fellchensammlung/models.py | 165 +++++++++--------- 2 files changed, 102 insertions(+), 82 deletions(-) create mode 100644 src/fellchensammlung/migrations/0017_user_organization_affiliation.py diff --git a/src/fellchensammlung/migrations/0017_user_organization_affiliation.py b/src/fellchensammlung/migrations/0017_user_organization_affiliation.py new file mode 100644 index 0000000..d5b271a --- /dev/null +++ b/src/fellchensammlung/migrations/0017_user_organization_affiliation.py @@ -0,0 +1,19 @@ +# Generated by Django 5.1.1 on 2024-11-14 06:42 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('fellchensammlung', '0016_rescueorganization_phone_number'), + ] + + operations = [ + migrations.AddField( + model_name='user', + name='organization_affiliation', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='fellchensammlung.rescueorganization', verbose_name='Organisation'), + ), + ] diff --git a/src/fellchensammlung/models.py b/src/fellchensammlung/models.py index 36428c4..8419b09 100644 --- a/src/fellchensammlung/models.py +++ b/src/fellchensammlung/models.py @@ -34,86 +34,6 @@ class Language(models.Model): verbose_name_plural = _('Sprachen') -class User(AbstractUser): - """ - Model that holds a user's profile, including the django user model - - The trust levels act as permission system and can be displayed as a badge for the user - """ - - # Admins can perform all actions and have the highest trust associated with them - # Moderators can make moderation decisions regarding the deletion of content - # Coordinators can create adoption notices without them being checked - # Members can create adoption notices that must be activated - ADMIN = "admin" - MODERATOR = "Moderator" - COORDINATOR = "Koordinator*in" - MEMBER = "Mitglied" - TRUST_LEVEL = { - ADMIN: 4, - MODERATOR: 3, - COORDINATOR: 2, - MEMBER: 1, - } - - preferred_language = models.ForeignKey(Language, on_delete=models.PROTECT, null=True, blank=True, - verbose_name=_('Bevorzugte Sprache')) - trust_level = models.IntegerField(choices=TRUST_LEVEL, default=TRUST_LEVEL[MEMBER]) - updated_at = models.DateTimeField(auto_now=True) - - class Meta: - verbose_name = _('Nutzer*in') - verbose_name_plural = _('Nutzer*innen') - - def get_absolute_url(self): - return reverse("user-detail", args=[str(self.pk)]) - - def get_notifications_url(self): - return self.get_absolute_url() - - def get_num_unread_notifications(self): - return BaseNotification.objects.filter(user=self, read=False).count() - - @property - def adoption_notices(self): - return AdoptionNotice.objects.filter(owner=self) - - @property - def owner(self): - return self - - -class Image(models.Model): - image = models.ImageField(upload_to='images') - alt_text = models.TextField(max_length=2000) - owner = models.ForeignKey(User, on_delete=models.CASCADE) - updated_at = models.DateTimeField(auto_now=True) - created_at = models.DateTimeField(auto_now_add=True) - - def __str__(self): - return self.alt_text - - @property - def as_html(self): - return f'{self.alt_text}' - - -class Species(models.Model): - """Model representing a species of animal.""" - name = models.CharField(max_length=200, help_text=_('Name der Tierart'), - verbose_name=_('Name')) - updated_at = models.DateTimeField(auto_now=True) - created_at = models.DateTimeField(auto_now_add=True) - - def __str__(self): - """String for representing the Model object.""" - return self.name - - class Meta: - verbose_name = _('Tierart') - verbose_name_plural = _('Tierarten') - - class Location(models.Model): place_id = models.IntegerField() latitude = models.FloatField() @@ -190,7 +110,89 @@ class RescueOrganization(models.Model): website = models.URLField(null=True, blank=True, verbose_name=_('Website')) updated_at = models.DateTimeField(auto_now=True) created_at = models.DateTimeField(auto_now_add=True) - comment = models.TextField(verbose_name=_("Kommentar"), null=True, blank=True,) + comment = models.TextField(verbose_name=_("Kommentar"), null=True, blank=True, ) + + +class User(AbstractUser): + """ + Model that holds a user's profile, including the django user model + + The trust levels act as permission system and can be displayed as a badge for the user + """ + + # Admins can perform all actions and have the highest trust associated with them + # Moderators can make moderation decisions regarding the deletion of content + # Coordinators can create adoption notices without them being checked + # Members can create adoption notices that must be activated + ADMIN = "admin" + MODERATOR = "Moderator" + COORDINATOR = "Koordinator*in" + MEMBER = "Mitglied" + TRUST_LEVEL = { + ADMIN: 4, + MODERATOR: 3, + COORDINATOR: 2, + MEMBER: 1, + } + + preferred_language = models.ForeignKey(Language, on_delete=models.PROTECT, null=True, blank=True, + verbose_name=_('Bevorzugte Sprache')) + trust_level = models.IntegerField(choices=TRUST_LEVEL, default=TRUST_LEVEL[MEMBER]) + updated_at = models.DateTimeField(auto_now=True) + organization_affiliation = models.ForeignKey(RescueOrganization, on_delete=models.PROTECT, null=True, blank=True, + verbose_name=_('Organisation')) + + class Meta: + verbose_name = _('Nutzer*in') + verbose_name_plural = _('Nutzer*innen') + + def get_absolute_url(self): + return reverse("user-detail", args=[str(self.pk)]) + + def get_notifications_url(self): + return self.get_absolute_url() + + def get_num_unread_notifications(self): + return BaseNotification.objects.filter(user=self, read=False).count() + + @property + def adoption_notices(self): + return AdoptionNotice.objects.filter(owner=self) + + @property + def owner(self): + return self + + +class Image(models.Model): + image = models.ImageField(upload_to='images') + alt_text = models.TextField(max_length=2000) + owner = models.ForeignKey(User, on_delete=models.CASCADE) + updated_at = models.DateTimeField(auto_now=True) + created_at = models.DateTimeField(auto_now_add=True) + + def __str__(self): + return self.alt_text + + @property + def as_html(self): + return f'{self.alt_text}' + + +class Species(models.Model): + """Model representing a species of animal.""" + name = models.CharField(max_length=200, help_text=_('Name der Tierart'), + verbose_name=_('Name')) + updated_at = models.DateTimeField(auto_now=True) + created_at = models.DateTimeField(auto_now_add=True) + + def __str__(self): + """String for representing the Model object.""" + return self.name + + class Meta: + verbose_name = _('Tierart') + verbose_name_plural = _('Tierarten') class AdoptionNotice(models.Model): @@ -240,7 +242,6 @@ class AdoptionNotice(models.Model): else: return "mixed" - @property def comments(self): return Comment.objects.filter(adoption_notice=self)