feat: use simpler m2m relationship for specialization
This commit is contained in:
		@@ -8,7 +8,7 @@ from django.urls import reverse
 | 
				
			|||||||
from django.utils.http import urlencode
 | 
					from django.utils.http import urlencode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .models import User, Language, Text, ReportComment, ReportAdoptionNotice, Log, Timestamp, SearchSubscription, \
 | 
					from .models import User, Language, Text, ReportComment, ReportAdoptionNotice, Log, Timestamp, SearchSubscription, \
 | 
				
			||||||
    SpeciesSpecificURL, ImportantLocation, SpeciesSpecialization
 | 
					    SpeciesSpecificURL, ImportantLocation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .models import Animal, Species, RescueOrganization, AdoptionNotice, Location, Rule, Image, ModerationAction, \
 | 
					from .models import Animal, Species, RescueOrganization, AdoptionNotice, Location, Rule, Image, ModerationAction, \
 | 
				
			||||||
    Comment, Report, Announcement, AdoptionNoticeStatus, User, Subscriptions, Notification
 | 
					    Comment, Report, Announcement, AdoptionNoticeStatus, User, Subscriptions, Notification
 | 
				
			||||||
@@ -100,11 +100,6 @@ class SpeciesSpecificURLInline(admin.StackedInline):
 | 
				
			|||||||
    model = SpeciesSpecificURL
 | 
					    model = SpeciesSpecificURL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SpeciesSpecializationInline(admin.StackedInline):
 | 
					 | 
				
			||||||
    model = SpeciesSpecialization
 | 
					 | 
				
			||||||
    extra = 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@admin.register(RescueOrganization)
 | 
					@admin.register(RescueOrganization)
 | 
				
			||||||
class RescueOrganizationAdmin(admin.ModelAdmin):
 | 
					class RescueOrganizationAdmin(admin.ModelAdmin):
 | 
				
			||||||
    search_fields = ("name", "description", "internal_comment", "location_string", "location__city")
 | 
					    search_fields = ("name", "description", "internal_comment", "location_string", "location__city")
 | 
				
			||||||
@@ -112,7 +107,6 @@ class RescueOrganizationAdmin(admin.ModelAdmin):
 | 
				
			|||||||
    list_filter = ("allows_using_materials", "trusted", ("external_source_identifier", EmptyFieldListFilter))
 | 
					    list_filter = ("allows_using_materials", "trusted", ("external_source_identifier", EmptyFieldListFilter))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    inlines = [
 | 
					    inlines = [
 | 
				
			||||||
        SpeciesSpecializationInline,
 | 
					 | 
				
			||||||
        SpeciesSpecificURLInline,
 | 
					        SpeciesSpecificURLInline,
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					# Generated by Django 5.2.1 on 2025-07-14 05:12
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db import migrations, models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('fellchensammlung', '0055_rescueorganization_ongoing_communication_and_more'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.AlterModelOptions(
 | 
				
			||||||
 | 
					            name='rescueorganization',
 | 
				
			||||||
 | 
					            options={'ordering': ['name']},
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AddField(
 | 
				
			||||||
 | 
					            model_name='rescueorganization',
 | 
				
			||||||
 | 
					            name='specializations',
 | 
				
			||||||
 | 
					            field=models.ManyToManyField(to='fellchensammlung.species'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
@@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					# Generated by Django 5.2.1 on 2025-07-14 05:15
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db import migrations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('fellchensammlung', '0056_alter_rescueorganization_options_and_more'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.DeleteModel(
 | 
				
			||||||
 | 
					            name='SpeciesSpecialization',
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
@@ -123,6 +123,23 @@ class AllowUseOfMaterialsChices(models.TextChoices):
 | 
				
			|||||||
    USE_MATERIALS_NOT_ASKED = "not_asked", _("Not asked")
 | 
					    USE_MATERIALS_NOT_ASKED = "not_asked", _("Not asked")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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 RescueOrganization(models.Model):
 | 
					class RescueOrganization(models.Model):
 | 
				
			||||||
    name = models.CharField(max_length=200)
 | 
					    name = models.CharField(max_length=200)
 | 
				
			||||||
    trusted = models.BooleanField(default=False, verbose_name=_('Vertrauenswürdig'))
 | 
					    trusted = models.BooleanField(default=False, verbose_name=_('Vertrauenswürdig'))
 | 
				
			||||||
@@ -155,6 +172,8 @@ class RescueOrganization(models.Model):
 | 
				
			|||||||
                                                help_text=_(
 | 
					                                                help_text=_(
 | 
				
			||||||
                                                    "Es findet gerade Kommunikation zwischen Notfellchen und der Organisation statt."))
 | 
					                                                    "Es findet gerade Kommunikation zwischen Notfellchen und der Organisation statt."))
 | 
				
			||||||
    parent_org = models.ForeignKey("RescueOrganization", on_delete=models.PROTECT, blank=True, null=True)
 | 
					    parent_org = models.ForeignKey("RescueOrganization", on_delete=models.PROTECT, blank=True, null=True)
 | 
				
			||||||
 | 
					    # allows to specify if a rescue organization has a specialization for dedicated species
 | 
				
			||||||
 | 
					    specializations = models.ManyToManyField(Species)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        unique_together = ('external_object_identifier', 'external_source_identifier',)
 | 
					        unique_together = ('external_object_identifier', 'external_source_identifier',)
 | 
				
			||||||
@@ -297,22 +316,6 @@ class Image(models.Model):
 | 
				
			|||||||
        return f'<img src="{MEDIA_URL}/{self.image}" alt="{self.alt_text}">'
 | 
					        return f'<img src="{MEDIA_URL}/{self.image}" alt="{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):
 | 
					class AdoptionNotice(models.Model):
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        permissions = [
 | 
					        permissions = [
 | 
				
			||||||
@@ -1015,15 +1018,3 @@ class SpeciesSpecificURL(models.Model):
 | 
				
			|||||||
    rescue_organization = models.ForeignKey(RescueOrganization, on_delete=models.CASCADE,
 | 
					    rescue_organization = models.ForeignKey(RescueOrganization, on_delete=models.CASCADE,
 | 
				
			||||||
                                            verbose_name=_("Tierschutzorganisation"))
 | 
					                                            verbose_name=_("Tierschutzorganisation"))
 | 
				
			||||||
    url = models.URLField(verbose_name=_("Tierartspezifische URL"))
 | 
					    url = models.URLField(verbose_name=_("Tierartspezifische URL"))
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class SpeciesSpecialization(models.Model):
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    Model that allows to specify if a rescue organization has a specialization for dedicated species
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    species = models.ForeignKey(Species, on_delete=models.CASCADE, verbose_name=_("Tierart"))
 | 
					 | 
				
			||||||
    rescue_organization = models.ForeignKey(RescueOrganization, on_delete=models.CASCADE,
 | 
					 | 
				
			||||||
                                            verbose_name=_("Tierschutzorganisation"))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __str__(self):
 | 
					 | 
				
			||||||
        return f"{_('Spezialisierung')} {self.species}"
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user