Skip to content

Commit

Permalink
Merge pull request #67 from desklab/document-cache
Browse files Browse the repository at this point in the history
Measurement document cache
  • Loading branch information
3j14 authored May 6, 2022
2 parents cfd57fc + 7c984a7 commit f24e4d2
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 1 deletion.
3 changes: 3 additions & 0 deletions gcampus/core/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ class GCampusCoreAppConfig(AppConfig):
name = "gcampus.core"
label = "gcampuscore"
verbose_name = _("GCampus Core")

def ready(self):
from . import receivers # imported to connect all receivers
23 changes: 23 additions & 0 deletions gcampus/core/migrations/0005_measurement_document_cache.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 4.0.4 on 2022-05-06 13:58

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("gcampuscore", "0004_location_help_text"),
]

operations = [
migrations.AddField(
model_name="measurement",
name="document",
field=models.FileField(
blank=True,
null=True,
upload_to="documents/measurement",
verbose_name="Document",
),
),
]
9 changes: 9 additions & 0 deletions gcampus/core/models/measurement.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,15 @@ class Meta:
#: generated column in migration ``0002_search``.
search_vector = SearchVectorField(null=True, editable=False)

#: File field to cache the measurement detail document for this
#: measurement.
document = models.FileField(
verbose_name=_("Document"),
upload_to="documents/measurement",
blank=True,
null=True,
)

#: Related field: List of all parameters associated with this
#: measurement.
parameters: List[Parameter]
Expand Down
86 changes: 86 additions & 0 deletions gcampus/core/receivers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Copyright (C) 2022 desklab gUG (haftungsbeschränkt)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

__all__ = ["update_measurement_document", "clear_measurement_documents"]

import logging
from typing import Union, Optional

from django.db.models import QuerySet
from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver
from django.utils.translation import get_language

from gcampus.core.models import Parameter, Measurement, ParameterType, Water
from gcampus.documents.tasks import render_cached_document_view

logger = logging.getLogger("gcampus.core.receivers")


@receiver(post_save, sender=Measurement)
@receiver(post_save, sender=Parameter)
@receiver(post_delete, sender=Parameter)
def update_measurement_document(
sender, # noqa
instance: Union[Parameter, Measurement],
created: bool = False,
update_fields: Optional[Union[tuple, list]] = None,
**kwargs, # noqa
):
update_fields = update_fields or ()

if isinstance(instance, Measurement):
if "document" in update_fields:
return
if created:
return
measurement: Measurement = instance
elif isinstance(instance, Parameter):
measurement: Measurement = instance.measurement
else:
raise NotImplementedError(f"Unhandled instance '{type(instance)}'")

if not measurement.document:
# Only build the document if it has been build already.
return

render_cached_document_view.apply_async(
args=(
"gcampus.documents.views.MeasurementDetailPDF",
measurement.pk,
get_language(),
),
)


@receiver(post_save, sender=ParameterType)
def clear_measurement_documents(
sender, # noqa
instance: ParameterType,
created: bool = False,
**kwargs, # noqa
):
if created:
return
qs: QuerySet
if isinstance(instance, ParameterType):
qs = Measurement.objects.filter(parameters__parameter_type=instance)
elif isinstance(instance, Water):
qs = Measurement.objects.filter(water=instance)
else:
raise NotImplementedError(f"Unhandled instance '{type(instance)}'")
# Note that the file will not be deleted from the storage backend,
# only its reference is removed from the database.
qs.update(document=None)
3 changes: 2 additions & 1 deletion gcampus/documents/views/print.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,12 @@ def get_filename(self):
)


class MeasurementDetailPDF(SingleObjectDocumentView):
class MeasurementDetailPDF(CachedDocumentView):
template_name = "gcampusdocuments/documents/measurement_detail.html"
filename = gettext_lazy("gewaessercampus-measurement-detail.pdf")
context_object_name = "measurement"
model = Measurement
model_file_field = "document"

def dispatch(self, request, *args, **kwargs):
return super(MeasurementDetailPDF, self).dispatch(request, *args, **kwargs)
Expand Down

0 comments on commit f24e4d2

Please sign in to comment.