2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-29 12:06:44 +00:00

Merge pull request #2641 from SchrodingersGat/report-cache-fixes

Report cache fixes
This commit is contained in:
Oliver 2022-02-18 08:54:09 +11:00 committed by GitHub
commit 0f7b6e77ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 36 deletions

View File

@ -225,13 +225,14 @@ class ReportPrintMixin:
outputs.append(report.render_as_string(request)) outputs.append(report.render_as_string(request))
else: else:
outputs.append(report.render(request)) outputs.append(report.render(request))
except TemplateDoesNotExist: except TemplateDoesNotExist as e:
template = str(e)
filename = report.template if not template:
template = report.template
return Response( return Response(
{ {
'error': _(f"Template file '{filename}' is missing or does not exist"), 'error': _(f"Template file '{template}' is missing or does not exist"),
}, },
status=400, status=400,
) )
@ -269,13 +270,16 @@ class ReportPrintMixin:
else: else:
pdf = outputs[0].get_document().write_pdf() pdf = outputs[0].get_document().write_pdf()
except TemplateDoesNotExist: except TemplateDoesNotExist as e:
filename = report.template template = str(e)
if not template:
template = report.template
return Response( return Response(
{ {
'error': _(f"Template file '{filename}' is missing or does not exist"), 'error': _(f"Template file '{template}' is missing or does not exist"),
}, },
status=400, status=400,
) )

View File

@ -14,12 +14,12 @@ import datetime
from django.urls import reverse from django.urls import reverse
from django.db import models from django.db import models
from django.conf import settings from django.conf import settings
from django.core.cache import cache
from django.core.exceptions import ValidationError, FieldError from django.core.exceptions import ValidationError, FieldError
from django.template.loader import render_to_string from django.template.loader import render_to_string
from django.template import Template, Context from django.template import Template, Context
from django.core.files.storage import FileSystemStorage
from django.core.validators import FileExtensionValidator from django.core.validators import FileExtensionValidator
import build.models import build.models
@ -43,32 +43,12 @@ except OSError as err: # pragma: no cover
logger = logging.getLogger("inventree") logger = logging.getLogger("inventree")
class ReportFileUpload(FileSystemStorage):
"""
Custom implementation of FileSystemStorage class.
When uploading a report (or a snippet / asset / etc),
it is often important to ensure the filename is not arbitrarily *changed*,
if the name of the uploaded file is identical to the currently stored file.
For example, a snippet or asset file is referenced in a template by filename,
and we do not want that filename to change when we upload a new *version*
of the snippet or asset file.
This uploader class performs the following pseudo-code function:
- If the model is *new*, proceed as normal
- If the model is being updated:
a) If the new filename is *different* from the existing filename, proceed as normal
b) If the new filename is *identical* to the existing filename, we want to overwrite the existing file
"""
def get_available_name(self, name, max_length=None):
return super().get_available_name(name, max_length)
def rename_template(instance, filename): def rename_template(instance, filename):
"""
Helper function for 'renaming' uploaded report files.
Pass responsibility back to the calling class,
to ensure that files are uploaded to the correct directory.
"""
return instance.rename_file(filename) return instance.rename_file(filename)
@ -155,7 +135,23 @@ class ReportBase(models.Model):
filename = os.path.basename(filename) filename = os.path.basename(filename)
return os.path.join('report', 'report_template', self.getSubdir(), filename) path = os.path.join('report', 'report_template', self.getSubdir(), filename)
fullpath = os.path.join(settings.MEDIA_ROOT, path)
fullpath = os.path.abspath(fullpath)
# If the report file is the *same* filename as the one being uploaded,
# remove the original one from the media directory
if str(filename) == str(self.template):
if os.path.exists(fullpath):
logger.info(f"Deleting existing report template: '{filename}'")
os.remove(fullpath)
# Ensure that the cache is cleared for this template!
cache.delete(fullpath)
return path
@property @property
def extension(self): def extension(self):
@ -522,16 +518,20 @@ def rename_snippet(instance, filename):
path = os.path.join('report', 'snippets', filename) path = os.path.join('report', 'snippets', filename)
fullpath = os.path.join(settings.MEDIA_ROOT, path)
fullpath = os.path.abspath(fullpath)
# If the snippet file is the *same* filename as the one being uploaded, # If the snippet file is the *same* filename as the one being uploaded,
# delete the original one from the media directory # delete the original one from the media directory
if str(filename) == str(instance.snippet): if str(filename) == str(instance.snippet):
fullpath = os.path.join(settings.MEDIA_ROOT, path)
fullpath = os.path.abspath(fullpath)
if os.path.exists(fullpath): if os.path.exists(fullpath):
logger.info(f"Deleting existing snippet file: '{filename}'") logger.info(f"Deleting existing snippet file: '{filename}'")
os.remove(fullpath) os.remove(fullpath)
# Ensure that the cache is deleted for this snippet
cache.delete(fullpath)
return path return path