CachedFile
pretalx.common.models.file.CachedFile source
An uploaded file, primarily used for API uploads. Deleted after expiry.
Fields 7
idUUIDFieldpksource
id = models.UUIDField(primary_key=True, default=uuid.uuid4)
expiresDateTimeFieldsource
expires = models.DateTimeField()
timestampDateTimeFieldnullsource
timestamp = models.DateTimeField(null=True, blank=True)
filenameCharFieldsource
filename = models.CharField(max_length=255)
content_typeCharFieldsource
content_type = models.CharField(max_length=255)
session_keyTextFieldnullsource
session_key = models.TextField(
null=True, blank=True
) # only allow processing by the same user / token, if set. If unset, the file cannot be processed further, but can be used for downloads by anybody.
fileFileFieldnullsource
file = models.FileField(
null=True, blank=True, upload_to=cachedfile_name, max_length=255
)
Attributes 1
objects<pretalx.common.models.managers.PretalxManager>Methods 31
Defined here
build_absolute_url(file_field, request)sourceReturn an absolute URL for a FileField value, or None if unavailable.
@staticmethod
def build_absolute_url(file_field, request):
"""Return an absolute URL for a FileField value, or None if unavailable."""
if not file_field:
return None
try:
url = file_field.url
except (AttributeError, ValueError):
return None
if request is None:
return None
return request.build_absolute_uri(url)
__str__()sourceReturn str(self).
on pretalx.common.models.file.CachedFile source
def __str__(self):
return f"CachedFile(id={self.id}, file={self.file})"
Return str(self).
def __str__(self):
return "%s object (%s)" % (self.__class__.__name__, self.pk)
From FileCleanupMixin pretalx.common.models.mixins
delete(*args, **kwargs)source
on pretalx.common.models.mixins.FileCleanupMixin source
def delete(self, *args, **kwargs):
self.delete_files()
return super().delete(*args, **kwargs)
def delete(self, using=None, keep_parents=False):
if not self._is_pk_set():
raise ValueError(
"%s object can't be deleted because its %s attribute is set "
"to None." % (self._meta.object_name, self._meta.pk.attname)
)
using = using or router.db_for_write(self.__class__, instance=self)
collector = Collector(using=using, origin=self)
collector.collect([self], keep_parents=keep_parents)
return collector.delete()
delete_files()sourceSchedule cleanup of every uploaded file attached to this object.
Public hook: called by delete() and by anonymisation paths (e.g. person.domain.user.deactivate_user) that want to drop files without removing the row. Overridable by subclasses that need to recurse into related objects.
def delete_files(self):
"""Schedule cleanup of every uploaded file attached to this object.
Public hook: called by ``delete()`` and by anonymisation paths
(e.g. ``person.domain.user.deactivate_user``) that want to drop
files without removing the row. Overridable by subclasses that
need to recurse into related objects."""
for field in self._file_fields:
value = getattr(self, field, None)
if not value:
continue
with suppress(Exception):
self._schedule_file_cleanup(field=field, path=value.path)
process_image(field, generate_thumbnail=False)source
def process_image(self, field, generate_thumbnail=False):
task_process_image.apply_async(
kwargs={
"field": field,
"model": self._meta.model_name.capitalize(),
"pk": self.pk,
"generate_thumbnail": generate_thumbnail,
},
countdown=10,
)
save(*args, **kwargs)source
on pretalx.common.models.mixins.FileCleanupMixin source
def save(self, *args, **kwargs):
update_fields = kwargs.get("update_fields")
if self._state.adding or (
update_fields and not set(self._file_fields) & set(update_fields)
):
return super().save(*args, **kwargs)
try:
pre_save_instance = self.__class__.objects.get(pk=self.pk)
except ObjectDoesNotExist:
return super().save(*args, **kwargs)
old_files = {}
for field in self._file_fields:
if old_value := getattr(pre_save_instance, field):
new_value = getattr(self, field)
if new_value and old_value.path != new_value.path:
old_files[field] = old_value.path
result = super().save(*args, **kwargs)
for field, path in old_files.items():
self._schedule_file_cleanup(field=field, path=path)
return result
Save the current instance. Override this in a subclass if you want to control the saving process.
The 'force_insert' and 'force_update' parameters can be used to insist that the "save" must be an SQL insert or update (or equivalent for non-SQL backends), respectively. Normally, they should not be set.
def save(
self,
*,
force_insert=False,
force_update=False,
using=None,
update_fields=None,
):
"""
Save the current instance. Override this in a subclass if you want to
control the saving process.
The 'force_insert' and 'force_update' parameters can be used to insist
that the "save" must be an SQL insert or update (or equivalent for
non-SQL backends), respectively. Normally, they should not be set.
"""
self._prepare_related_fields_for_save(operation_name="save")
using = using or router.db_for_write(self.__class__, instance=self)
if force_insert and (force_update or update_fields):
raise ValueError("Cannot force both insert and updating in model saving.")
deferred_non_generated_fields = {
f.attname
for f in self._meta.concrete_fields
if f.attname not in self.__dict__ and f.generated is False
}
if update_fields is not None:
# If update_fields is empty, skip the save. We do also check for
# no-op saves later on for inheritance cases. This bailout is
# still needed for skipping signal sending.
if not update_fields:
return
update_fields = frozenset(update_fields)
field_names = self._meta._non_pk_concrete_field_names
not_updatable_fields = update_fields.difference(field_names)
if not_updatable_fields:
raise ValueError(
"The following fields do not exist in this model, are m2m "
"fields, primary keys, or are non-concrete fields: %s"
% ", ".join(not_updatable_fields)
)
# If saving to the same database, and this model is deferred, then
# automatically do an "update_fields" save on the loaded fields.
elif (
not force_insert
and deferred_non_generated_fields
and using == self._state.db
and self._is_pk_set()
):
field_names = set()
pk_fields = self._meta.pk_fields
for field in self._meta.concrete_fields:
if field not in pk_fields and not hasattr(field, "through"):
field_names.add(field.attname)
loaded_fields = field_names.difference(deferred_non_generated_fields)
if loaded_fields:
update_fields = frozenset(loaded_fields)
self.save_base(
using=using,
force_insert=force_insert,
force_update=force_update,
update_fields=update_fields,
)