feat: add rescue org create and change form

This commit is contained in:
2026-01-06 17:15:52 +01:00
parent 9a3cbffa42
commit f3f7131912
8 changed files with 106 additions and 9 deletions

View File

@@ -0,0 +1,19 @@
Tierschutzorganisation hinzufügen
=================================
Notfellchen führt eine Liste von Tierheime und anderer Tierschutzorganisationen. Die meisten Tierheime wurden von
OpenStreetMap importiert.
Ausnahmen stellen nicht-ortsgebunden Organisationen wie die Rattenhilfe Süd dar. Sie existieren nicht auf der Karte und
können dort auch nicht sinnvoll verzeichnet werden, daher werden sie nur in Notfellchen geführt.
.. warning::
Generell ist es besser eine Tierschutzorganisation in OpenStreetMap anzulegen, anstatt bei Notfellchen. Das
ermöglichtes anderen die Daten ebenfalls zu nutzen und sie werden ggf. durch die OpenStreetMap Community aktuell gehalten.
Hier erklären wir aber trotzdem wie Tierheime direkt in Notfellchen hinzugefügt werden können, damit es schneller geht
diese Anzulegen und ihnen Vermittlungen zuzuweisen.
Organisationen in Notfellchen hinzufügen
----------------------------------------

View File

@@ -201,3 +201,14 @@ class CloseAdoptionNoticeForm(forms.ModelForm):
class Meta:
model = AdoptionNotice
fields = ('adoption_notice_status',)
class RescueOrgForm(forms.ModelForm):
template_name = "fellchensammlung/forms/form_snippets.html"
class Meta:
model = RescueOrganization
fields = ('name', 'allows_using_materials', 'location_string', "email", "phone_number", "website", "instagram",
"facebook", "fediverse_profile", "internal_comment", "description", "external_source_identifier",
"external_object_identifier",
"parent_org")

View File

@@ -167,10 +167,12 @@ class RescueOrganization(models.Model):
internal_comment = models.TextField(verbose_name=_("Interner Kommentar"), null=True, blank=True, )
description = models.TextField(null=True, blank=True, verbose_name=_('Beschreibung')) # Markdown allowed
external_object_identifier = models.CharField(max_length=200, null=True, blank=True,
verbose_name=_('External Object Identifier'))
verbose_name=_('External Object Identifier'),
help_text=_("Id des Objekts in der externen Datenbank (kann leer gelassen werden)"))
external_source_identifier = models.CharField(max_length=200, null=True, blank=True,
choices=ExternalSourceChoices.choices,
verbose_name=_('External Source Identifier'))
verbose_name=_('External Source Identifier'),
help_text=_("Name der Datenbank aus der die Tierschutzorganisation importiert wurde (kann leer gelassen werden)"))
exclude_from_check = models.BooleanField(default=False, verbose_name=_('Von Prüfung ausschließen'),
help_text=_("Organisation von der manuellen Überprüfung ausschließen, "
"z.B. weil Tiere nicht online geführt werden"))
@@ -183,7 +185,7 @@ class RescueOrganization(models.Model):
ongoing_communication = models.BooleanField(default=False, verbose_name=_('In aktiver Kommunikation'),
help_text=_(
"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, verbose_name=_("Übergeordnete Organisation"))
# allows to specify if a rescue organization has a specialization for dedicated species
specializations = models.ManyToManyField(Species, blank=True)
twenty_id = models.UUIDField(verbose_name=_("Twenty-ID"), null=True, blank=True,

View File

@@ -24,11 +24,20 @@
<div class="block">
{% include "fellchensammlung/partials/rescue_orgs/partial-rescue-organization-contact.html" %}
</div>
{% trust_level "MODERATOR" as coordinator_trust_level %}
{% if request.user.trust_level >= coordinator_trust_level %}
<div class="block">
<a class="button is-primary is-fullwidth"
href="{% url 'rescue-organization-edit' rescue_organization_id=org.pk %}">
<i class="fa-solid fa-tools fa-fw"></i> {% translate 'Bearbeiten' %}
</a>
</div>
<div class="block">
<a class="button is-warning is-fullwidth" href="{% url org_meta|admin_urlname:'change' org.pk %}">
<i class="fa-solid fa-tools fa-fw"></i> Admin interface
</a>
</div>
{% endif %}
</div>
<div class="column">
{% include "fellchensammlung/partials/partial-map.html" %}

View File

@@ -102,6 +102,10 @@
<a class="nav-link " href="{% url "modtools" %}">
{% translate 'Moderationstools' %}
</a>
<br>
<a class="nav-link " href="{% url "rescue-organization-create" %}">
{% translate 'Tierschutzorganisation hinzufügen' %}
</a>
{% endif %}
<br/>
{% if request.user.is_superuser %}

View File

@@ -0,0 +1,19 @@
{% extends "fellchensammlung/base.html" %}
{% load i18n %}
{% load widget_tweaks %}
{% block content %}
<h1 class="title is-1">
{% if rescue_org %}
{{ rescue_org.name }}
{% else %}
{% translate 'Tierschutzorganisation hinzufügen' %}
{% endif %}
</h1>
<form method="post">
{% csrf_token %}
{{ form }}
<input class="button is-primary" type="submit" value="{% translate "Speichern" %}">
</form>
{% endblock %}

View File

@@ -47,6 +47,9 @@ urlpatterns = [
path("tierschutzorganisationen/", views.list_rescue_organizations, name="rescue-organizations"),
path("tierschutzorganisationen/<int:rescue_organization_id>/", views.detail_view_rescue_organization,
name="rescue-organization-detail"),
path("tierschutzorganisationen/add", views.rescue_org_create_or_update, name="rescue-organization-create"),
path("tierschutzorganisationen/<int:rescue_organization_id>/edit", views.rescue_org_create_or_update,
name="rescue-organization-edit"),
path("tierschutzorganisationen/<int:rescue_organization_id>/exkludieren", views.exclude_from_regular_check,
name="rescue-organization-exclude"),
path("tierschutzorganisationen/add-exclusion-reason", views.update_exclusion_reason,

View File

@@ -25,7 +25,8 @@ from .models import AdoptionNotice, Text, Animal, Rule, Image, Report, Moderatio
ImportantLocation, SpeciesSpecificURL, NotificationTypeChoices, SocialMediaPost
from .forms import AdoptionNoticeForm, ImageForm, ReportAdoptionNoticeForm, \
CommentForm, ReportCommentForm, AnimalForm, AdoptionNoticeFormAutoAnimal, SpeciesURLForm, RescueOrgInternalComment, \
UpdateRescueOrgRegularCheckStatus, UserModCommentForm, CloseAdoptionNoticeForm, RescueOrgSearchByNameForm
UpdateRescueOrgRegularCheckStatus, UserModCommentForm, CloseAdoptionNoticeForm, RescueOrgSearchByNameForm, \
RescueOrgForm
from .models import Language, Announcement
from .tools import i18n, img
from .tools.fedi import post_an_to_fedi
@@ -1045,3 +1046,32 @@ def adoption_notice_sharepic(request, adoption_notice_id):
adoption_notice = get_object_or_404(AdoptionNotice, pk=adoption_notice_id)
svg_data = img.export_svg(adoption_notice)
return HttpResponse(svg_data, content_type="image/svg+xml")
@login_required
def rescue_org_create_or_update(request, rescue_organization_id=None):
"""
Create or update a rescue organization
"""
# Only users that are mods to create or edit it
if not user_is_trust_level_or_above(request.user, TrustLevel.MODERATOR):
return HttpResponseForbidden()
if rescue_organization_id:
rescue_org = get_object_or_404(RescueOrganization, pk=rescue_organization_id)
else:
rescue_org = None
if request.method == 'POST':
form = RescueOrgForm(request.POST, instance=rescue_org)
if form.is_valid():
rescue_org = form.save()
"""Log"""
Log.objects.create(user=request.user, action="add_rescue_org",
text=f"{request.user} hat Tierschutzorganisation {rescue_org.pk} geändert")
return redirect(reverse("rescue-organization-detail", args=[rescue_org.pk], ))
else:
form = RescueOrgForm(instance=rescue_org)
return render(request, 'fellchensammlung/forms/form-rescue-organization.html',
context={"form": form, "rescue_org": rescue_org})