From c209b2eb8694ccff9ab30b810881b889d34df120 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Thu, 14 Oct 2021 14:12:33 +0200 Subject: [PATCH] Database performance * optimizes the db fetching for all index views and detail views * introduces usage of managers.py in all necessary apps for wrapping basic fetch settings * moves comment.html to comment_card.html under /konova/templates/konova/ * adds/updates translations * fixes document typos * drops comment rendering in public reports * opens public reports in new tabs if button is clicked from the detail view --- compensation/managers.py | 73 +++++++++++++++ compensation/models.py | 12 +++ compensation/tables.py | 16 ++-- .../compensation/includes/controls.html | 2 +- .../detail/compensation/view.html | 2 +- .../detail/eco_account/includes/actions.html | 12 +-- .../detail/eco_account/includes/comment.html | 23 ----- .../detail/eco_account/includes/controls.html | 2 +- .../eco_account/includes/deductions.html | 4 +- .../eco_account/includes/states-after.html | 4 +- .../eco_account/includes/states-before.html | 4 +- .../compensation/detail/eco_account/view.html | 2 +- .../report/compensation/report.html | 3 - .../report/eco_account/report.html | 84 ++++++++++++++++++ compensation/views/eco_account_views.py | 44 +++++++-- ema/managers.py | 21 +++++ ema/models.py | 3 + ema/tables.py | 4 +- .../ema/detail/includes/controls.html | 2 +- ema/templates/ema/report/report.html | 3 - intervention/managers.py | 48 ++++++++++ intervention/models.py | 19 ++-- intervention/tables.py | 6 +- .../intervention/detail/includes/comment.html | 23 ----- .../detail/includes/controls.html | 2 +- .../templates/intervention/detail/view.html | 2 +- .../templates/intervention/report/report.html | 3 - intervention/views.py | 11 ++- konova/models.py | 2 +- .../templates/konova/comment_card.html | 5 ++ locale/de/LC_MESSAGES/django.mo | Bin 23203 -> 23251 bytes locale/de/LC_MESSAGES/django.po | 45 ++++++---- 32 files changed, 364 insertions(+), 122 deletions(-) create mode 100644 compensation/managers.py delete mode 100644 compensation/templates/compensation/detail/eco_account/includes/comment.html create mode 100644 compensation/templates/compensation/report/eco_account/report.html create mode 100644 ema/managers.py create mode 100644 intervention/managers.py delete mode 100644 intervention/templates/intervention/detail/includes/comment.html rename compensation/templates/compensation/detail/compensation/includes/comment.html => konova/templates/konova/comment_card.html (81%) diff --git a/compensation/managers.py b/compensation/managers.py new file mode 100644 index 00000000..c97cd518 --- /dev/null +++ b/compensation/managers.py @@ -0,0 +1,73 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 14.10.21 + +""" +from django.db import models + + +class CompensationActionManager(models.Manager): + """ Holds default db fetch setting for this model type + + """ + def get_queryset(self): + return super().get_queryset().select_related( + "action_type", + "action_type__parent" + ) + + +class CompensationStateManager(models.Manager): + """ Holds default db fetch setting for this model type + + """ + def get_queryset(self): + return super().get_queryset().select_related( + "biotope_type", + "biotope_type__parent" + ) + + +class CompensationManager(models.Manager): + """ Holds default db fetch setting for this model type + + """ + def get_queryset(self): + return super().get_queryset().select_related( + "modified", + "intervention", + "intervention__recorded", + "intervention__recorded__user", + "intervention__modified", + "intervention__checked", + "intervention__checked__user", + ) + + +class EcoAccountManager(models.Manager): + """ Holds default db fetch setting for this model type + + """ + def get_queryset(self): + return super().get_queryset().select_related( + "recorded", + "recorded__user", + "modified", + "modified__user", + ).prefetch_related( + "users", + ) + + +class EcoAccountDeductionManager(models.Manager): + """ Holds default db fetch setting for this model type + + """ + def get_queryset(self): + return super().get_queryset().select_related( + "intervention", + "intervention__recorded", + "created", + ) \ No newline at end of file diff --git a/compensation/models.py b/compensation/models.py index 850ff7e5..4f9cc919 100644 --- a/compensation/models.py +++ b/compensation/models.py @@ -17,6 +17,8 @@ from django.utils.translation import gettext_lazy as _ from codelist.models import KonovaCode from codelist.settings import CODELIST_COMPENSATION_ACTION_ID, CODELIST_BIOTOPES_ID, \ CODELIST_COMPENSATION_FUNDING_ID +from compensation.managers import CompensationStateManager, EcoAccountDeductionManager, CompensationActionManager, \ + EcoAccountManager, CompensationManager from intervention.models import Intervention, ResponsibilityData from konova.models import BaseObject, BaseResource, Geometry, UuidModel, AbstractDocument, \ generate_document_file_upload_path @@ -67,6 +69,8 @@ class CompensationState(UuidModel): ) surface = models.FloatField() + objects = CompensationStateManager() + def __str__(self): return "{} | {} m²".format(self.biotope_type, self.surface) @@ -102,6 +106,8 @@ class CompensationAction(BaseResource): unit = models.CharField(max_length=100, null=True, blank=True, choices=UnitChoices.choices) comment = models.TextField(blank=True, null=True, help_text="Additional comment") + objects = CompensationActionManager() + def __str__(self): return "{} | {} {}".format(self.action_type, self.amount, self.unit) @@ -178,6 +184,8 @@ class Compensation(AbstractCompensation): related_name='compensations' ) + objects = CompensationManager() + def __str__(self): return "{}".format(self.identifier) @@ -301,6 +309,8 @@ class EcoAccount(AbstractCompensation): default=0, ) + objects = EcoAccountManager() + def __str__(self): return "{}".format(self.identifier) @@ -500,5 +510,7 @@ class EcoAccountDeduction(BaseResource): related_name="deductions", ) + objects = EcoAccountDeductionManager() + def __str__(self): return "{} of {}".format(self.surface, self.account) diff --git a/compensation/tables.py b/compensation/tables.py index 278db13d..df7ec3eb 100644 --- a/compensation/tables.py +++ b/compensation/tables.py @@ -148,14 +148,13 @@ class CompensationTable(BaseTable): Returns: """ - html = "" if value is None: value = User.objects.none() has_access = value.filter( - username=self.user.username + id=self.user.id ).exists() - html += self.render_icn( + html = self.render_icn( tooltip=_("Full access granted") if has_access else _("Access not granted"), icn_class="fas fa-edit rlp-r-inv" if has_access else "far fa-edit", ) @@ -244,7 +243,7 @@ class EcoAccountTable(BaseTable): return format_html(html) def render_r(self, value, record: EcoAccount): - """ Renders the registered column for an eco account + """ Renders the recorded column for an eco account Args: value (str): The identifier value @@ -268,7 +267,7 @@ class EcoAccountTable(BaseTable): return format_html(html) def render_e(self, value, record: EcoAccount): - """ Renders the registered column for an eco account + """ Renders the editable column for an eco account Args: value (str): The identifier value @@ -278,10 +277,9 @@ class EcoAccountTable(BaseTable): """ html = "" - has_access = value.filter( - username=self.user.username - ).exists() - + # Do not use value in here, since value does use unprefetched 'users' manager, where record has already + # prefetched users data + has_access = self.user in record.users.all() html += self.render_icn( tooltip=_("Full access granted") if has_access else _("Access not granted"), icn_class="fas fa-edit rlp-r-inv" if has_access else "far fa-edit", diff --git a/compensation/templates/compensation/detail/compensation/includes/controls.html b/compensation/templates/compensation/detail/compensation/includes/controls.html index a9c68c29..5be0b3e8 100644 --- a/compensation/templates/compensation/detail/compensation/includes/controls.html +++ b/compensation/templates/compensation/detail/compensation/includes/controls.html @@ -6,7 +6,7 @@ LANIS - + diff --git a/compensation/templates/compensation/detail/compensation/view.html b/compensation/templates/compensation/detail/compensation/view.html index 80b70613..35d45046 100644 --- a/compensation/templates/compensation/detail/compensation/view.html +++ b/compensation/templates/compensation/detail/compensation/view.html @@ -103,7 +103,7 @@ {% include 'map/geom_form.html' %}
- {% include 'compensation/detail/compensation/includes/comment.html' %} + {% include 'konova/comment_card.html' %}
diff --git a/compensation/templates/compensation/detail/eco_account/includes/actions.html b/compensation/templates/compensation/detail/eco_account/includes/actions.html index 23b3f069..868242a5 100644 --- a/compensation/templates/compensation/detail/eco_account/includes/actions.html +++ b/compensation/templates/compensation/detail/eco_account/includes/actions.html @@ -4,7 +4,7 @@
- {{obj.actions.count}} + {{actions.count}} {% trans 'Actions' context 'Compensation' %}
@@ -33,13 +33,15 @@ {% trans 'Comment' %} - - {% trans 'Action' %} - + {% if default_member and has_access %} + + {% trans 'Action' %} + + {% endif %} - {% for action in obj.actions.all %} + {% for action in actions %} {{ action.action_type }} diff --git a/compensation/templates/compensation/detail/eco_account/includes/comment.html b/compensation/templates/compensation/detail/eco_account/includes/comment.html deleted file mode 100644 index aff3dec8..00000000 --- a/compensation/templates/compensation/detail/eco_account/includes/comment.html +++ /dev/null @@ -1,23 +0,0 @@ -{% load i18n fontawesome_5 %} - -{% if obj.comment %} -
-
-
-
-
-
- {% fa5_icon 'info-circle' %} - {% trans 'Comment' %} -
-
-
-
-
-
- {{obj.comment}} -
-
-
-
-{% endif %} \ No newline at end of file diff --git a/compensation/templates/compensation/detail/eco_account/includes/controls.html b/compensation/templates/compensation/detail/eco_account/includes/controls.html index dca0823f..5aa9620e 100644 --- a/compensation/templates/compensation/detail/eco_account/includes/controls.html +++ b/compensation/templates/compensation/detail/eco_account/includes/controls.html @@ -6,7 +6,7 @@ LANIS
- + diff --git a/compensation/templates/compensation/detail/eco_account/includes/deductions.html b/compensation/templates/compensation/detail/eco_account/includes/deductions.html index 94d31da0..b35cef1e 100644 --- a/compensation/templates/compensation/detail/eco_account/includes/deductions.html +++ b/compensation/templates/compensation/detail/eco_account/includes/deductions.html @@ -51,9 +51,9 @@ {% if deduction.intervention.recorded %} - + {% else %} - + {% endif %} {{ deduction.surface|floatformat:2|intcomma }} m² diff --git a/compensation/templates/compensation/detail/eco_account/includes/states-after.html b/compensation/templates/compensation/detail/eco_account/includes/states-after.html index da88db0e..bd71e25a 100644 --- a/compensation/templates/compensation/detail/eco_account/includes/states-after.html +++ b/compensation/templates/compensation/detail/eco_account/includes/states-after.html @@ -4,7 +4,7 @@
- {{obj.after_states.count}} + {{after_states.count}} {% trans 'States after' %}
@@ -35,9 +35,11 @@ {% trans 'Surface' %} + {% if is_default_member and has_access %} {% trans 'Action' %} + {% endif %} diff --git a/compensation/templates/compensation/detail/eco_account/includes/states-before.html b/compensation/templates/compensation/detail/eco_account/includes/states-before.html index 33591509..8acb4865 100644 --- a/compensation/templates/compensation/detail/eco_account/includes/states-before.html +++ b/compensation/templates/compensation/detail/eco_account/includes/states-before.html @@ -4,7 +4,7 @@
- {{obj.before_states.count}} + {{before_states.count}} {% trans 'States before' %}
@@ -35,9 +35,11 @@ {% trans 'Surface' %} + {% if is_default_member and has_access %} {% trans 'Action' %} + {% endif %} diff --git a/compensation/templates/compensation/detail/eco_account/view.html b/compensation/templates/compensation/detail/eco_account/view.html index 429c4f4d..e839e6e9 100644 --- a/compensation/templates/compensation/detail/eco_account/view.html +++ b/compensation/templates/compensation/detail/eco_account/view.html @@ -102,7 +102,7 @@ {% include 'map/geom_form.html' %}
- {% include 'compensation/detail/compensation/includes/comment.html' %} + {% include 'konova/comment_card.html' %}
diff --git a/compensation/templates/compensation/report/compensation/report.html b/compensation/templates/compensation/report/compensation/report.html index de8ddd15..956c0094 100644 --- a/compensation/templates/compensation/report/compensation/report.html +++ b/compensation/templates/compensation/report/compensation/report.html @@ -50,9 +50,6 @@
{% include 'map/geom_form.html' %}
-
- {% include 'intervention/detail/includes/comment.html' %} -

{% trans 'Open in browser' %}

diff --git a/compensation/templates/compensation/report/eco_account/report.html b/compensation/templates/compensation/report/eco_account/report.html new file mode 100644 index 00000000..bd633322 --- /dev/null +++ b/compensation/templates/compensation/report/eco_account/report.html @@ -0,0 +1,84 @@ +{% extends 'public_base.html' %} +{% load i18n fontawesome_5 humanize %} + +{% block body %} +
+
+

{% trans 'Report' %}

+

{{obj.identifier}}

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{% trans 'Title' %}{{obj.title|default_if_none:""}}
{% trans 'Conservation office' %}{{obj.responsible.conservation_office.str_as_office|default_if_none:""}}
{% trans 'Conservation office file number' %}{{obj.responsible.conservation_file_number|default_if_none:""}}
{% trans 'Action handler' %}{{obj.responsible.handler|default_if_none:""}}
{% trans 'Funded by' %} + {% with obj.fundings.all as fundings %} + {% for funding in fundings %} +
{{funding.short_name}}
+
+ {% empty %} + {% trans 'None' %} + {% endfor %} + {% endwith %} +
{% trans 'Deductions for' %} + {% for deduction in deductions %} + + {{deduction.intervention__identifier}} + +
+ {% empty %} + {% trans 'None' %} + {% endfor %} +
{% trans 'Last modified' %} + {{obj.modified.timestamp|default_if_none:""|naturalday}} +
+
+ + {% include 'compensation/detail/compensation/includes/states-before.html' %} + {% include 'compensation/detail/compensation/includes/states-after.html' %} + {% include 'compensation/detail/compensation/includes/actions.html' %} +
+
+
+ {% include 'map/geom_form.html' %} +
+
+
+

{% trans 'Open in browser' %}

+ {{ qrcode|safe }} +
+
+

{% trans 'View in LANIS' %}

+ {{ qrcode_lanis|safe }} +
+
+ +
+
+ +{% endblock %} \ No newline at end of file diff --git a/compensation/views/eco_account_views.py b/compensation/views/eco_account_views.py index 5f2ede3b..dadac7e6 100644 --- a/compensation/views/eco_account_views.py +++ b/compensation/views/eco_account_views.py @@ -42,7 +42,6 @@ def index_view(request: HttpRequest): A rendered view """ template = "generic_index.html" - user = request.user eco_accounts = EcoAccount.objects.filter( deleted=None, ) @@ -167,27 +166,36 @@ def detail_view(request: HttpRequest, id: str): """ template = "compensation/detail/eco_account/view.html" - acc = get_object_or_404(EcoAccount, id=id) + acc = get_object_or_404( + EcoAccount.objects.prefetch_related( + "deadlines", + ).select_related( + 'geometry', + 'responsible', + ), + id=id + ) geom_form = SimpleGeomForm(instance=acc) _user = request.user is_data_shared = acc.is_shared_with(_user) # Order states according to surface - before_states = acc.before_states.all().order_by("-surface") - after_states = acc.after_states.all().order_by("-surface") + before_states = acc.before_states.order_by("-surface") + after_states = acc.after_states.order_by("-surface") # Precalculate logical errors between before- and after-states # Sum() returns None in case of no states, so we catch that and replace it with 0 for easier handling sum_before_states = before_states.aggregate(Sum("surface"))["surface__sum"] or 0 sum_after_states = after_states.aggregate(Sum("surface"))["surface__sum"] or 0 diff_states = abs(sum_before_states - sum_after_states) - # Calculate rest of available surface for deductions available_total, available_relative = acc.get_available_rest() + # Prefetch related data to decrease the amount of db connections deductions = acc.deductions.filter( intervention__deleted=None, ) + actions = acc.actions.all() context = { "obj": acc, @@ -205,6 +213,7 @@ def detail_view(request: HttpRequest, id: str): "is_ets_member": in_group(_user, ETS_GROUP), "LANIS_LINK": acc.get_LANIS_link(), "deductions": deductions, + "actions": actions, } context = BaseContext(request, context).context return render(request, template, context) @@ -446,7 +455,7 @@ def report_view(request:HttpRequest, id: str): """ # Reuse the compensation report template since EcoAccounts are structurally identical - template = "compensation/report/report.html" + template = "compensation/report/eco_account/report.html" acc = get_object_or_404(EcoAccount, id=id) # If intervention is not recorded (yet or currently) we need to render another template without any data @@ -454,18 +463,39 @@ def report_view(request:HttpRequest, id: str): template = "report/unavailable.html" return render(request, template, {}) + # Prepare data for map viewer + geom_form = SimpleGeomForm( + instance=acc + ) qrcode_img = generate_qr_code( - request.build_absolute_uri(reverse("compensation:acc-report", args=(id,))), + request.build_absolute_uri(reverse("ema:report", args=(id,))), 10 ) qrcode_img_lanis = generate_qr_code( acc.get_LANIS_link(), 7 ) + # Order states by surface + before_states = acc.before_states.all().order_by("-surface").select_related("biotope_type__parent") + after_states = acc.after_states.all().order_by("-surface").select_related("biotope_type__parent") + actions = acc.actions.all().select_related("action_type__parent") + + # Reduce amount of db fetched data to the bare minimum we need in the template (deduction's intervention id and identifier) + deductions = acc.deductions.all()\ + .distinct("intervention")\ + .select_related("intervention")\ + .values_list("intervention__id", "intervention__identifier", named=True) + context = { "obj": acc, "qrcode": qrcode_img, "qrcode_lanis": qrcode_img_lanis, + "has_access": False, # disables action buttons during rendering + "before_states": before_states, + "after_states": after_states, + "geom_form": geom_form, + "actions": actions, + "deductions": deductions, } context = BaseContext(request, context).context return render(request, template, context) diff --git a/ema/managers.py b/ema/managers.py new file mode 100644 index 00000000..aaac3a39 --- /dev/null +++ b/ema/managers.py @@ -0,0 +1,21 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 14.10.21 + +""" +from django.db import models + + +class EmaManager(models.Manager): + """ Holds default db fetch setting for this model type + + """ + def get_queryset(self): + return super().get_queryset().select_related( + "modified", + "modified__user", + "recorded", + "recorded__user", + ) \ No newline at end of file diff --git a/ema/models.py b/ema/models.py index d7e214fe..e8d31c4f 100644 --- a/ema/models.py +++ b/ema/models.py @@ -5,6 +5,7 @@ from django.db import models from django.db.models import QuerySet from compensation.models import AbstractCompensation +from ema.managers import EmaManager from konova.models import AbstractDocument, generate_document_file_upload_path from konova.settings import DEFAULT_SRID_RLP, LANIS_LINK_TEMPLATE, EMA_DOC_PATH from user.models import UserActionLogEntry @@ -43,6 +44,8 @@ class Ema(AbstractCompensation): related_name="+" ) + objects = EmaManager() + def __str__(self): return "{}".format(self.identifier) diff --git a/ema/tables.py b/ema/tables.py index aeeece2f..9055059d 100644 --- a/ema/tables.py +++ b/ema/tables.py @@ -49,7 +49,7 @@ class EmaTable(BaseTable): lm = tables.Column( verbose_name=_("Last edit"), orderable=True, - accessor="created__timestamp", + accessor="modified__timestamp", ) class Meta(BaseTable.Meta): @@ -122,7 +122,7 @@ class EmaTable(BaseTable): """ html = "" has_access = value.filter( - username=self.user.username + id=self.user.id ).exists() html += self.render_icn( diff --git a/ema/templates/ema/detail/includes/controls.html b/ema/templates/ema/detail/includes/controls.html index 88a112ff..1d5e5467 100644 --- a/ema/templates/ema/detail/includes/controls.html +++ b/ema/templates/ema/detail/includes/controls.html @@ -6,7 +6,7 @@ LANIS
- + diff --git a/ema/templates/ema/report/report.html b/ema/templates/ema/report/report.html index 756b6573..2395e7ce 100644 --- a/ema/templates/ema/report/report.html +++ b/ema/templates/ema/report/report.html @@ -54,9 +54,6 @@
{% include 'map/geom_form.html' %}
-
- {% include 'intervention/detail/includes/comment.html' %} -

{% trans 'Open in browser' %}

diff --git a/intervention/managers.py b/intervention/managers.py new file mode 100644 index 00000000..213e8659 --- /dev/null +++ b/intervention/managers.py @@ -0,0 +1,48 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 14.10.21 + +""" +from django.db import models + + +class InterventionManager(models.Manager): + """ Holds default db fetch setting for this model type + + """ + def get_queryset(self): + return super().get_queryset().select_related( + "recorded", + "recorded__user", + "modified", + "modified__user", + "checked", + "checked__user", + ).prefetch_related( + "users", + ) + + +class LegalDataManager(models.Manager): + """ Holds default db fetch setting for this model type + + """ + def get_queryset(self): + return super().get_querset().select_related( + "process_type", + ).prefetch_related( + "laws" + ) + + +class ResponsibilityDataManager(models.Manager): + """ Holds default db fetch setting for this model type + + """ + def get_queryset(self): + return super().get_querset().select_related( + "registration_office", + "conservation_office", + ) diff --git a/intervention/models.py b/intervention/models.py index e2a6c44e..2bdf1eff 100644 --- a/intervention/models.py +++ b/intervention/models.py @@ -10,16 +10,15 @@ import shutil from django.contrib.auth.models import User from django.contrib.gis.db import models from django.db.models import QuerySet -from django.utils.timezone import localtime from django.utils.translation import gettext_lazy as _ from codelist.models import KonovaCode from codelist.settings import CODELIST_REGISTRATION_OFFICE_ID, CODELIST_CONSERVATION_OFFICE_ID, CODELIST_LAW_ID, \ CODELIST_PROCESS_TYPE_ID +from intervention.managers import InterventionManager, LegalDataManager, ResponsibilityDataManager from konova.models import BaseObject, Geometry, UuidModel, BaseResource, AbstractDocument, \ generate_document_file_upload_path from konova.settings import DEFAULT_SRID_RLP, LANIS_LINK_TEMPLATE, LANIS_ZOOM_LUT -from konova.sub_settings.django_settings import DEFAULT_DATE_TIME_FORMAT from konova.utils import generators from user.models import UserActionLogEntry @@ -57,6 +56,8 @@ class ResponsibilityData(UuidModel): conservation_file_number = models.CharField(max_length=1000, blank=True, null=True) handler = models.CharField(max_length=500, null=True, blank=True, help_text="Refers to 'Eingriffsverursacher' or 'Maßnahmenträger'") + objects = ResponsibilityDataManager() + def __str__(self): return "ZB: {} | ETS: {} | Handler: {}".format( self.registration_office, @@ -171,6 +172,8 @@ class LegalData(UuidModel): revocation = models.OneToOneField(Revocation, null=True, blank=True, help_text="Refers to 'Widerspruch am'", on_delete=models.SET_NULL) + objects = LegalDataManager() + class Intervention(BaseObject): """ @@ -221,6 +224,8 @@ class Intervention(BaseObject): help_text="Used for sharing access", ) + objects = InterventionManager() + def __str__(self): return "{} ({})".format(self.identifier, self.title) @@ -379,16 +384,6 @@ class Intervention(BaseObject): y, ) - @property - def recorded_tooltip(self): - tooltip = _("Not recorded yet") - if self.recorded: - value = self.recorded.timestamp - value = localtime(value) - on = value.strftime(DEFAULT_DATE_TIME_FORMAT) - tooltip = _("Recorded on {} by {}").format(on, self.recorded.user) - return tooltip - def get_documents(self) -> (QuerySet, QuerySet): """ Getter for all documents of an intervention diff --git a/intervention/tables.py b/intervention/tables.py index bf0e718d..103d419a 100644 --- a/intervention/tables.py +++ b/intervention/tables.py @@ -117,7 +117,7 @@ class InterventionTable(BaseTable): return format_html(html) def render_r(self, value, record: Intervention): - """ Renders the registered column for an intervention + """ Renders the recorded column for an intervention Args: value (str): The identifier value @@ -141,7 +141,7 @@ class InterventionTable(BaseTable): return format_html(html) def render_e(self, value, record: Intervention): - """ Renders the registered column for an intervention + """ Renders the editable column for an intervention Args: value (str): The identifier value @@ -152,7 +152,7 @@ class InterventionTable(BaseTable): """ html = "" has_access = value.filter( - username=self.user.username + id=self.user.id ).exists() html += self.render_icn( diff --git a/intervention/templates/intervention/detail/includes/comment.html b/intervention/templates/intervention/detail/includes/comment.html deleted file mode 100644 index aff3dec8..00000000 --- a/intervention/templates/intervention/detail/includes/comment.html +++ /dev/null @@ -1,23 +0,0 @@ -{% load i18n fontawesome_5 %} - -{% if obj.comment %} -
-
-
-
-
-
- {% fa5_icon 'info-circle' %} - {% trans 'Comment' %} -
-
-
-
-
-
- {{obj.comment}} -
-
-
-
-{% endif %} \ No newline at end of file diff --git a/intervention/templates/intervention/detail/includes/controls.html b/intervention/templates/intervention/detail/includes/controls.html index 4a64e5fb..bb94042a 100644 --- a/intervention/templates/intervention/detail/includes/controls.html +++ b/intervention/templates/intervention/detail/includes/controls.html @@ -6,7 +6,7 @@ LANIS
- + diff --git a/intervention/templates/intervention/detail/view.html b/intervention/templates/intervention/detail/view.html index 7d2788e3..e3d919f3 100644 --- a/intervention/templates/intervention/detail/view.html +++ b/intervention/templates/intervention/detail/view.html @@ -127,7 +127,7 @@ {% include 'map/geom_form.html' %}
- {% include 'intervention/detail/includes/comment.html' %} + {% include 'konova/comment_card.html' %}
diff --git a/intervention/templates/intervention/report/report.html b/intervention/templates/intervention/report/report.html index 4813582e..cf422042 100644 --- a/intervention/templates/intervention/report/report.html +++ b/intervention/templates/intervention/report/report.html @@ -100,9 +100,6 @@
{% include 'map/geom_form.html' %}
-
- {% include 'intervention/detail/includes/comment.html' %} -

{% trans 'Open in browser' %}

diff --git a/intervention/views.py b/intervention/views.py index 49b363cf..6853197f 100644 --- a/intervention/views.py +++ b/intervention/views.py @@ -35,6 +35,8 @@ def index_view(request: HttpRequest): # Filtering by user access is performed in table filter inside of InterventionTableFilter class interventions = Intervention.objects.filter( deleted=None, # not deleted + ).select_related( + "legal" ) table = InterventionTable( request=request, @@ -194,7 +196,14 @@ def detail_view(request: HttpRequest, id: str): template = "intervention/detail/view.html" # Fetch data, filter out deleted related data - intervention = get_object_or_404(Intervention, id=id) + intervention = get_object_or_404( + Intervention.objects.select_related( + "geometry", + "legal", + "responsible", + ), + id=id + ) compensations = intervention.compensations.filter( deleted=None, ) diff --git a/konova/models.py b/konova/models.py index ab4ad7ae..f9f87584 100644 --- a/konova/models.py +++ b/konova/models.py @@ -149,7 +149,7 @@ class BaseObject(BaseResource): """ if hasattr(self, "users"): - return self.users.filter(username=user.username).exists() + return self.users.filter(id=user.id) else: return User.objects.none() diff --git a/compensation/templates/compensation/detail/compensation/includes/comment.html b/konova/templates/konova/comment_card.html similarity index 81% rename from compensation/templates/compensation/detail/compensation/includes/comment.html rename to konova/templates/konova/comment_card.html index aff3dec8..0cc91bf0 100644 --- a/compensation/templates/compensation/detail/compensation/includes/comment.html +++ b/konova/templates/konova/comment_card.html @@ -1,5 +1,10 @@ {% load i18n fontawesome_5 %} +{% comment %} + Used in e.g. reports and detail views for every model which supports comment field (BaseObject derived) +{% endcomment %} + + {% if obj.comment %}
diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index 348a808d988e5289faef8d59491fb3dd9e5230e5..5c28ab3990cbc7c5abdc48bc98a964e3f7a8dac3 100644 GIT binary patch delta 6849 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 delta 6832 zcmYk=30ziH8prX2Y_bTlgQy@NsDOatinuWvcDEOpz8GmmPaSCiIO~+KUO`Obr|Mwo|52*1N%ti}+$z0 zeW?D9qOPy9UPASE12ge9COH%`6Wu2ni2l?^Vj7OcI9!HG;X9~_?67`{y1oiE;Ca-5 zHKPc3kCbR`Lkv*u1e1=MS6{@2P z*cY$jV$5R$X-^zN4R{*ax8@@1!F*EO`+`yRh!pa#8OPHgQ&6eNL=9Yk8gMXbzz0wr zk46nN34?GRD)l9(iLXIr_FdclG3xEAKrO*#)HrpVrfvtZsFbFlQdWc+IMUXa-~j67 z=!4f#6aEF2ncJv|)lYRzLS-@+JxhXq)CXb#-h;mAth6V}kyqQig&N=h>c%6e37tS? z;=FCIM$cxm`Z4<$&PSl`OGiJDbArL{-dqmLT~Cp&6Oe6Ka_$Rl29{F#k!b@ z8mO(U7ob1&BGl3h!AzWmdcw`93~obhx(ZakmrxVAin{+6YVY{A;K3Q+L{ZQhCZYz+ z!2s-R+Y4>|KGZ;?QBOV=)$vT!lfQuKcpa*rZK!_tqcVE}bzMNZdtU-NN?j%e?e^}d zfd`>dct2|GC!)TH=3^|rX3y_LO{4ici4~$IbT_K~5mW}2p*CMx2KiUR z8X9!Ndi10aJ+BL@gUhHTxrIUKm+3B5I0jRXL*1Wh>$#|WMdC0`A2$Jd114zopypdQ@sRVm;i0JiIxEy8i}h;=x(24Kajz25P)K z)WrKa6g1Oes7w^2Qv4`tfY}&`r5K89Z2KluM|+W1-yBE1@4up!FfiNQE0L)F<4_Yz zwC18R;}lX*2SZS6J_WU=C8&wKja~2~)N5EL$C!Lf#84c8z3_2Vig%#ab}wq;pP(jI zf!ciEqQhGW(rF_C(MT-Q9*4G*AFy8!isCDvC^6JKq89X0VcQ4`*R z%ETU2#*Uz_KZ9Y6Z>lKhhHBIeHK-Z;^G@l#4Mn{bJyA>pEt8gM@V{RA zj@wXc_cbcD=j{1QsI~R(?7p@UsEnnc`pdEwpvJogwU?f9Y+#NGDQZ)0KxO6x zDrFb3DPBiSES7guYnhD=F&~w&VW2- zLZzMfapW3U7@ks8z<@agGp;&4>|X{Zc!#zr_8 z9lhUAQqYalumdhY4ZPoa6gA^7&=)VE2Dpap@HT3XwCm+QaZl8yy9?F+5bFM?QT;AN ze=O}q{?*}18ho%E@51%i7jL3J_AKNJ2m7O5!xBux-L`%XHBeY@cPSH56KIZljXRdo9BLwIs6Esg zHPL>k%#A>;eYtJlj>?2{kOJ8=m8cA)7P)pnZIU9?gvMbIPQg^1kIiu-X5(qh#Jc_5 zuj;m_P5KD3Jxm$4!n3G}h4=T2cj<7c$@Mom0skelj6Yc6)7y%3f1=TYOlik{#9O)Ai^4>i*hwtfMXft#p~>kM}P zAPK@S>KUjf>5SS;eNdaMKdPTGn2FQTv$rsu`aV>qPokq#RZ`Fm-=XKL7?rvx-bG~~ z8Fju7YT%KmHJpgrTys!Qb`W#05<@X`2$RDERDUB-4>BHuanca-uN!C6pfz2A$@n2^ zfUhtTFQX>|L)|9`LUqs>^*W_v6!x<9;i&VIQTNYBO?)LPV;fNu+&Pr>SBj6&@Ejh; zR@mom_eWzoHlrSWk82l9q&^nYaUp8L+fgY!gBsvlTfd50ni|wNx9oY}d)*0zITUn5 zGU`dPP)pJm^#p@a@BM?QjEqBdG!;AI9P1v`>so_}7;~RH;r5tEy%@EWt5Fj=fa=#d zOhG9+iR$&)fQo$d8}-m3WWPvg%+hDAp>ODO%tQ|CtoS!U0_h}E>4 z(ChTHDjdbc38I`xW|%Sf8o}3s`Gm-&O-CM%!X3msHE=8^V(s|@lp9ihOM7n|X6UEtZYUha=BZK*U2&{HJZ~ZhZuM67{&?0X#>s|C~(eg6Tv@oXjRNi54{8OJq^5JuXrRBs$PG4L>JRDc?3*uQZ4b Q*cy>?xbfB>x_=+@2YklAUjP6A diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po index ab0ecbbd..78df84ba 100644 --- a/locale/de/LC_MESSAGES/django.po +++ b/locale/de/LC_MESSAGES/django.po @@ -19,7 +19,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-10-14 08:46+0200\n" +"POT-Creation-Date: 2021-10-14 09:12+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -51,6 +51,7 @@ msgstr "Automatisch generiert" #: compensation/templates/compensation/detail/eco_account/includes/documents.html:28 #: compensation/templates/compensation/detail/eco_account/view.html:31 #: compensation/templates/compensation/report/compensation/report.html:12 +#: compensation/templates/compensation/report/eco_account/report.html:12 #: ema/tables.py:33 ema/templates/ema/detail/includes/documents.html:28 #: ema/templates/ema/detail/view.html:24 #: ema/templates/ema/report/report.html:12 intervention/forms/forms.py:39 @@ -89,22 +90,19 @@ msgstr "Auswählen..." #: compensation/forms/forms.py:73 compensation/forms/modalForms.py:61 #: compensation/forms/modalForms.py:272 compensation/forms/modalForms.py:367 #: compensation/templates/compensation/detail/compensation/includes/actions.html:34 -#: compensation/templates/compensation/detail/compensation/includes/comment.html:11 #: compensation/templates/compensation/detail/compensation/includes/deadlines.html:34 #: compensation/templates/compensation/detail/compensation/includes/documents.html:31 #: compensation/templates/compensation/detail/eco_account/includes/actions.html:34 -#: compensation/templates/compensation/detail/eco_account/includes/comment.html:11 #: compensation/templates/compensation/detail/eco_account/includes/deadlines.html:34 #: compensation/templates/compensation/detail/eco_account/includes/documents.html:31 #: ema/templates/ema/detail/includes/actions.html:34 #: ema/templates/ema/detail/includes/deadlines.html:34 #: ema/templates/ema/detail/includes/documents.html:31 #: intervention/forms/forms.py:179 intervention/forms/modalForms.py:132 -#: intervention/templates/intervention/detail/includes/comment.html:11 #: intervention/templates/intervention/detail/includes/documents.html:31 #: intervention/templates/intervention/detail/includes/payments.html:34 #: intervention/templates/intervention/detail/includes/revocation.html:38 -#: konova/forms.py:371 +#: konova/forms.py:371 konova/templates/konova/comment_card.html:16 msgid "Comment" msgstr "Kommentar" @@ -114,8 +112,9 @@ msgstr "Zusätzlicher Kommentar" #: compensation/forms/forms.py:93 #: compensation/templates/compensation/detail/eco_account/view.html:58 +#: compensation/templates/compensation/report/eco_account/report.html:16 #: ema/templates/ema/detail/view.html:42 -#: ema/templates/ema/report/report.html:29 intervention/forms/forms.py:101 +#: ema/templates/ema/report/report.html:16 intervention/forms/forms.py:101 #: intervention/templates/intervention/detail/view.html:56 #: intervention/templates/intervention/report/report.html:37 msgid "Conservation office" @@ -127,8 +126,9 @@ msgstr "Verantwortliche Stelle" #: compensation/forms/forms.py:109 #: compensation/templates/compensation/detail/eco_account/view.html:62 +#: compensation/templates/compensation/report/eco_account/report.html:20 #: ema/templates/ema/detail/view.html:46 -#: ema/templates/ema/report/report.html:33 intervention/forms/forms.py:129 +#: ema/templates/ema/report/report.html:20 intervention/forms/forms.py:129 #: intervention/templates/intervention/detail/view.html:60 #: intervention/templates/intervention/report/report.html:41 msgid "Conservation office file number" @@ -687,16 +687,19 @@ msgstr "Verzeichnet am" #: compensation/templates/compensation/detail/compensation/view.html:71 #: compensation/templates/compensation/detail/eco_account/view.html:70 #: compensation/templates/compensation/report/compensation/report.html:24 +#: compensation/templates/compensation/report/eco_account/report.html:28 #: ema/templates/ema/detail/view.html:54 -#: ema/templates/ema/report/report.html:16 +#: ema/templates/ema/report/report.html:28 msgid "Funded by" msgstr "Gefördert mit" #: compensation/templates/compensation/detail/compensation/view.html:79 #: compensation/templates/compensation/detail/eco_account/view.html:78 #: compensation/templates/compensation/report/compensation/report.html:31 +#: compensation/templates/compensation/report/eco_account/report.html:35 +#: compensation/templates/compensation/report/eco_account/report.html:49 #: ema/templates/ema/detail/view.html:62 -#: ema/templates/ema/report/report.html:23 +#: ema/templates/ema/report/report.html:35 #: intervention/templates/intervention/report/report.html:57 #: intervention/templates/intervention/report/report.html:78 msgid "None" @@ -705,6 +708,7 @@ msgstr "" #: compensation/templates/compensation/detail/compensation/view.html:84 #: compensation/templates/compensation/detail/eco_account/view.html:83 #: compensation/templates/compensation/report/compensation/report.html:37 +#: compensation/templates/compensation/report/eco_account/report.html:54 #: ema/templates/ema/detail/view.html:67 #: ema/templates/ema/report/report.html:41 #: intervention/templates/intervention/detail/view.html:108 @@ -779,27 +783,37 @@ msgid "Missing" msgstr "Fehlt" #: compensation/templates/compensation/detail/eco_account/view.html:66 +#: compensation/templates/compensation/report/eco_account/report.html:24 +#: ema/templates/ema/detail/view.html:50 +#: ema/templates/ema/report/report.html:24 msgid "Action handler" msgstr "Maßnahmenträger" #: compensation/templates/compensation/report/compensation/report.html:7 +#: compensation/templates/compensation/report/eco_account/report.html:7 #: ema/templates/ema/report/report.html:7 #: intervention/templates/intervention/report/report.html:7 msgid "Report" msgstr "Bericht" #: compensation/templates/compensation/report/compensation/report.html:58 +#: compensation/templates/compensation/report/eco_account/report.html:75 #: ema/templates/ema/report/report.html:62 #: intervention/templates/intervention/report/report.html:108 msgid "Open in browser" msgstr "Im Browser öffnen" #: compensation/templates/compensation/report/compensation/report.html:62 +#: compensation/templates/compensation/report/eco_account/report.html:79 #: ema/templates/ema/report/report.html:66 #: intervention/templates/intervention/report/report.html:112 msgid "View in LANIS" msgstr "In LANIS öffnen" +#: compensation/templates/compensation/report/eco_account/report.html:41 +msgid "Deductions for" +msgstr "Abbuchungen für" + #: compensation/views/compensation_views.py:77 msgid "Compensation {} added" msgstr "Kompensation {} hinzugefügt" @@ -913,13 +927,6 @@ msgstr "" msgid "Payment funded compensation" msgstr "Ersatzzahlungsmaßnahme" -#: ema/templates/ema/detail/view.html:50 -#: ema/templates/ema/report/report.html:37 intervention/forms/forms.py:141 -#: intervention/templates/intervention/detail/view.html:64 -#: intervention/templates/intervention/report/report.html:45 -msgid "Intervention handler" -msgstr "Eingriffsverursacher" - #: ema/views.py:78 msgid "EMA {} added" msgstr "EMA {} hinzugefügt" @@ -984,6 +991,12 @@ msgstr "Aktenzeichen Zulassungsbehörde" msgid "ZB-123/ABC.456" msgstr "" +#: intervention/forms/forms.py:141 +#: intervention/templates/intervention/detail/view.html:64 +#: intervention/templates/intervention/report/report.html:45 +msgid "Intervention handler" +msgstr "Eingriffsverursacher" + #: intervention/forms/forms.py:145 msgid "Who performs the intervention" msgstr "Wer führt den Eingriff durch"