class Entrega(models.Model): """ Modela las Entregas de trabajos que realiza una Persona """ LICENSE_CHOICES = ( (0, _('No autoriza consulta pública')), (1, _('Autoriza consulta pública')), ) # La entrega pasará por varios estados # Al depositar -> estado 0 # Al confirmarla el alumno -> estado 1 # Al validarla Secretaría/Tribunal -> estado 2 # Al pasarla a ZAGUAN -> estado 3 ESTADOS_CHOICES = ( (0, _('Sin confirmar')), (1, _('Confirmada')), (2, _('Validada')), (3, _('Pasada a Zaguan')), ) tid = models.AutoField(_('Código de entrega'), primary_key=True) titulo = models.CharField(max_length=500) resumen = models.CharField(max_length=5000) resumen_en = models.CharField(max_length=5000, null=True, blank=True) notas = models.CharField(max_length=5000, null=True, blank=True) #Todo keywords as manytomanyfield? #ToDo director(es) #ToDo director(es) delegado(s) departamentos = models.ManyToManyField(Departamento) license = models.IntegerField(choices=LICENSE_CHOICES, default=0) matricula = models.ForeignKey(Matricula, on_delete=models.CASCADE) fecha = models.DateTimeField(auto_now=True) #memoria = models.FileField(upload_to=user_upload_memoria_directory_path) #anexos = models.FileField(null=True, blank=True, upload_to=user_upload_anexos_directory_path) memoria = PrivateFileField("Memoria", upload_subfolder=user_private_upload_path) anexos = PrivateFileField("Anexos", null=True, blank=True, upload_subfolder=user_private_upload_path) # ficheroprivado = PrivateFileField("Fichero_privado", null=True, blank=True, upload_subfolder=user_private_upload_path) # refer to https://github.com/edoburu/django-private-storage entrega_material_adicional = models.BooleanField(default=False) estado = models.IntegerField(choices=ESTADOS_CHOICES, default=0) def __str__(self): return (_("{} - Entrega {} del alumno {}").format( self.fecha, self.tid, self.matricula.persona)) class Meta: verbose_name = _('Entrega') verbose_name_plural = _('Entregas')
class Delivery(models.Model): task = models.ForeignKey(Task, on_delete=models.CASCADE, related_name="delivery") file = PrivateFileField( upload_to=delivery_path, validators=[validate_file_extension, validate_file_size]) comment = models.TextField(max_length=500) delivery_user = models.ForeignKey(Profile, on_delete=models.CASCADE, related_name="deliveries") delivery_time = models.DateTimeField(auto_now=True) responding_user = models.ForeignKey(Profile, on_delete=models.CASCADE, related_name="responded_deliveries", blank=True, null=True) responding_time = models.DateTimeField(blank=True, null=True) ACCEPTED = 'a' PENDING = 'p' DECLINED = 'd' STATUS_CHOICES = ( (ACCEPTED, 'Accepted'), (PENDING, 'Pending'), (DECLINED, 'Declined'), ) status = models.CharField(max_length=8, choices=STATUS_CHOICES, default=PENDING) feedback = models.TextField(max_length=500)
class Key(CommonInfo): name = models.CharField(verbose_name="Name", max_length=50) username = models.CharField(verbose_name="Username", max_length=50, blank=True, null=True) password = EncryptedCharField(verbose_name="Password", max_length=50, blank=True, null=True) note = models.CharField(verbose_name="Note", max_length=200, blank=True, null=True) url = models.CharField(verbose_name="URL", max_length=50, blank=True, null=True) file = PrivateFileField("File", storage=storage2, upload_to=upload_key, blank=True, null=True) set = models.ForeignKey(Set, on_delete=models.CASCADE) slug = models.SlugField() history = HistoricalRecords() class Meta: verbose_name = "Key" verbose_name_plural = "Keys" ordering = ['last_modified_at'] def __str__(self): return self.name def save(self, *args, **kwargs): self.slug = slugify(self.name) super(Key, self).save(*args, **kwargs) if self.file: input_file = self.file.path output_file = self.file.path with open(input_file, 'rb') as f: data = f.read() fernet = Fernet(settings.SECRET_KEY) encrypted = fernet.encrypt(data) with open(output_file, 'wb') as f: f.write(encrypted)
class MainSubmission(models.Model): created_date = models.DateTimeField(default=timezone.now) user_handle = models.ForeignKey(UserProfile, related_name='user_m_submission', on_delete=models.CASCADE) problem_submitted = models.ForeignKey(Problem, related_name='problem_m_submission', on_delete=models.CASCADE) verdict = models.CharField(blank=True, default='...', max_length=500) execution_time = models.DecimalField(blank=True, null=True, default=0, max_digits=6, decimal_places=3) memory = models.PositiveIntegerField(blank=True, null=True) language = models.CharField(blank=True, default='c_cpp', max_length=100, choices=lang_choices) actual_language = models.CharField(blank=True, max_length=100) solution = PrivateFileField(upload_to=user_directory_path) def __str__(self): return 'p_{}_u_{}_s_{}'.format(self.problem_submitted.problem_name, self.user_handle.username, str(self.id))
class Empresa(models.Model): def logo_upload_path(instance, filename): return 'logos/{0}-{1}-{2}'.format("logo", instance.user.username, filename) descripcion = models.TextField(max_length=1000, blank=True, null=True) url = models.URLField(max_length=200, default='', blank=True, null=True) logo = PrivateFileField(blank=True, null=True, content_types=('image/jpeg', 'image/png', 'image/jpg'), upload_to=logo_upload_path, max_file_size=1024 * 1024) nombre_fantasia = models.CharField(max_length=200, blank=False, null=False, verbose_name="Nombre de Fantasía") departamento = models.ForeignKey('Departamento', on_delete=models.CASCADE) activa = models.BooleanField(default=True) user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='empresa_user') class Meta: verbose_name = 'Empresa' verbose_name_plural = 'Empresas' unique_together = (("departamento", "nombre_fantasia"),) def get_cantidad_de_pasantes(self): return Pasantia.objects.filter(entrevista__empresa=self).count() def get_cantidad_de_postulados(self): return Postulacion.objects.filter(puesto__empresa=self, activa=True).count() def __str__(self): return self.nombre_fantasia.__str__()
class File(models.Model): file = PrivateFileField(_('File'), content_types='application/pdf', max_file_size=10 * 1024 * 1024) date_created = models.DateTimeField(_('Date created'), auto_now_add=True) apiary = models.ForeignKey(Apiary, null=True, blank=True, related_name='files', on_delete=models.CASCADE) hive = models.ForeignKey(Hive, null=True, blank=True, related_name='files', on_delete=models.CASCADE) def clean(self): if self.apiary and self.hive: raise ValidationError( _('File cannot have both an apiary and a hive')) def __str__(self): if self.apiary: return _('Apiary file for {apiary} ({pk})').format( apiary=self.apiary, pk=self.apiary.pk) if self.hive: return _('Hive file for {hive} ({pk})').format(hive=self.hive, pk=self.hive.pk)
class Guide(CommonInfo): name = models.CharField(verbose_name="Name", max_length=50) guide = RichTextUploadingField(verbose_name="Text", blank=True, null=True) file = PrivateFileField("File", storage=storage2, upload_to=upload_guide, blank=True, null=True) set = models.ForeignKey(Set, on_delete=models.CASCADE) slug = models.SlugField() class Meta: verbose_name = "Guide" verbose_name_plural = "Guides" ordering = ['last_modified_at'] def __str__(self): return self.name def save(self, *args, **kwargs): self.slug = slugify(self.name) super(Guide, self).save(*args, **kwargs) if self.file: input_file = self.file.path output_file = self.file.path with open(input_file, 'rb') as f: data = f.read() fernet = Fernet(settings.SECRET_KEY) encrypted = fernet.encrypt(data) with open(output_file, 'wb') as f: f.write(encrypted)
class PretrainedModel(OwnedResourceModel): shared_users = models.ManyToManyField('users.User', blank=True, related_name='pm_shared_users') shared_groups = models.ManyToManyField(Group, blank=True, related_name='pm_shared_groups') file = PrivateFileField(upload_to=get_encoded_filepath, ) componentInstance = models.ForeignKey('analysis.ComponentInstance', on_delete=models.SET_NULL, blank=True, null=True) metadata = JSONField(blank=True, null=True) objects = models.Manager() def get_filename(self): return os.path.basename(self.file.name) def get_absolute_url(self): return reverse('prediction:model-detail', kwargs={'id': self.id}) def get_full_path(self): return self.file.full_path def get_owned_models(self, user): return PretrainedModel.objects.filter(owner=user) def get_public_models(self): return PretrainedModel.objects.filter( accessibility=PretrainedModel.ACCESSIBILITY_PUBLIC) def predict(self, inports): outport = {} inputs = [] for key, value in inports.items(): inputs.append( float(value)) # TODO: support different types: str, etc, logger.info(inputs) model = joblib.load(self.file) out = model.predict([inputs]) outport = out[0] return outport @delete_previous_file def save(self, force_insert=False, force_update=False, using=None, update_fields=None): super(PretrainedModel, self).save() @delete_previous_file def delete(self, using=None, keep_parents=False): super(PretrainedModel, self).delete()
class CustomerDossier(models.Model): def upload_subfolder(self): # self.pk is still None here! return [slugify(self.customer)] customer = models.CharField(max_length=100) file = PrivateFileField(upload_to='CustomerDossier', upload_subfolder=upload_subfolder)
class CustomerDossierJoin(models.Model): def upload_subfolder2(self): # Slightly incorrect usage by developers, joining locally. return os.path.join(slugify(self.customer), 'sub2') customer = models.CharField(max_length=100) file = PrivateFileField(upload_to='CustomerDossierJoin', upload_subfolder=upload_subfolder2)
class Alumno(models.Model): def validate_hash(value): reg = re.compile('^30[0-9]{5,6}') if not reg.match(str(value)): raise ValidationError(u'Formato de registro erroneo, recuerda que debe comenzar con 30') def curriculum_upload_path(instance, filename): return 'curriculums/{0}-{1}-{2}'.format("curriculum", instance.user.username, filename) def plan_upload_path(instance, filename): return 'planes_de_estudio/{0}-{1}-{2}'.format("plan", instance.user.username, filename) def historia_upload_path(instance, filename): return 'historias_academicas/{0}-{1}-{2}'.format("historia", instance.user.username, filename) def perfil_upload_path(instance, filename): return 'perfiles/{0}-{1}-{2}'.format("perfil", instance.user.username, filename) numero_registro = models.PositiveIntegerField(validators=[validate_hash], unique=True) curriculum = PrivateFileField('Curriculum (.pdf)', upload_to=curriculum_upload_path, content_types='application/pdf', max_file_size=1024 * 1024) plan_de_estudio = PrivateFileField('Plan de Estudio (.pdf)', upload_to=plan_upload_path, content_types='application/pdf', max_file_size=1024 * 1024) historia_academica = PrivateFileField('Historia Académica (.pdf)', upload_to=historia_upload_path, content_types='application/pdf', max_file_size=1024 * 1024) descripcion_intereses = models.TextField(max_length=500, blank=True, null=True) descripcion_habilidades = models.TextField(max_length=1000, blank=True, null=True) ultima_actualizacion_perfil = models.DateField(default=date.today) ultima_postulacion = models.DateField(null=True, blank=True) condicion_acreditacion = models.NullBooleanField(verbose_name='Está en condición de acreditación de práctica del plan de estudio?') expedicion_acreditacion = models.TextField(max_length=500, null=True, blank=True, verbose_name='Justificación de acreditación o su negativa') comentarios_comision_carrera = models.TextField(max_length=1000, null=True, blank=True) comentarios_carrera_visibles = models.BooleanField(default=False, verbose_name='Comentarios visibles para las empresas') comentarios_comision_pps = models.TextField(max_length=1000, null=True, blank=True) perfil = PrivateFileField(blank=True, null=True, content_types=('image/jpeg', 'image/png', 'image/jpg'), upload_to=perfil_upload_path, max_file_size=1024 * 1024, verbose_name='Foto de perfil') progreso = models.SmallIntegerField(validators=[MinValueValidator(0), MaxValueValidator(100)], default=0, verbose_name='Progreso en %') telefono = PhoneNumberField(blank=True, null=True) user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='alumno_user') carrera = models.ForeignKey('Carrera', on_delete=models.DO_NOTHING) class Meta: verbose_name = 'Alumno' verbose_name_plural = 'Alumnos' def __str__(self): return self.user.last_name.__str__() + ", " + self.user.first_name.__str__()
class File(models.Model): name = models.CharField(max_length=200) uuid = models.CharField(max_length=8, default=get_uuid, unique=True) created = models.DateTimeField(auto_now_add=True) accessed = models.DateTimeField(auto_now=True) file = PrivateFileField(upload_to=get_filename) size = models.BigIntegerField(default=0) thumb = NotRequiredPrivateFileField(upload_to=get_thumbnail_filename, blank=True, null=True) folder = models.ForeignKey('Folder', related_name='files', on_delete=models.CASCADE) share = models.OneToOneField(Share, related_name='file', on_delete=models.CASCADE, default=_get_share) owner = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='files', on_delete=models.CASCADE) def ext(self) -> str: return os.path.splitext(self.name)[1] def clean_name(self) -> str: return os.path.splitext(self.name)[0] def text(self) -> bool: mimetype = guess_type(self.name)[0] if mimetype: mimetype = mimetype.split('/')[0] == 'text' return mimetype def generate_thumbnail(self): ext = self.ext().strip('.').upper() if ext == 'JPG': ext = 'JPEG' if ext in settings.IMAGE_THUMBNAIL_TYPES: try: img = Image.open(self.file.file) img.thumbnail(settings.IMAGE_THUMBNAIL_SIZE) img_bytes = BytesIO() img.save(img_bytes, format=ext) self.thumb.save(self.thumb.name, CoreFile(img_bytes)) # NOTE: Thumbs can currently exceed the quota self.size += self.thumb.file.size self.save() self.owner.quota.use(self.thumb.file.size) except UnidentifiedImageError: pass # We couldn't open the image, probably because it isn't one. def __str__(self): return self.name
class Problem(models.Model): problem_name = models.CharField(max_length = 1000, unique = True) slug = models.SlugField(unique=True) problem_statement = models.TextField() setter = models.ForeignKey(UserProfile, default = DEFAULT_SETTER_ID, on_delete=models.SET_DEFAULT) score = models.PositiveIntegerField(blank=True, null=True, default = 100) time_limit = models.PositiveIntegerField(default = DEFAULT_TIME_LIMIT) memory_limit = models.PositiveIntegerField(default = DEFAULT_MEM_LIMIT) src_code_size = models.PositiveIntegerField(default = DEFAULT_SRC_CODE_SZ) solution_file = PrivateFileField(upload_to = user_directory_path, max_file_size = DEFAULT_SRC_CODE_SZ) test_file = PrivateFileField(upload_to = user_directory_path, max_file_size = DEFAULT_BASE_FILE_SIZE*30) def save(self, *args, **kwargs): self.slug = slugify(self.problem_name) super(Problem, self).save(*args, **kwargs) def get_absolute_url(self): return reverse('problems:problem_page', kwargs={'slug':self.slug}) def __str__(self): return self.problem_name
class RawData(models.Model): """Raw data that is stored in the system, can be Zip files, Shapefiles, or Geotiffs that will be sent to the computation server Attributes: path (str): File path to file on fileserver """ name = models.CharField(max_length=50, null=True) ext = models.CharField(max_length=10, null=True) path = PrivateFileField(storage=PrivateFileSystemStorage, upload_to="raw_files/")
class TaskFile(models.Model): task = models.ForeignKey(Task, on_delete=models.CASCADE, related_name="files") file = PrivateFileField( upload_to=directory_path, storage=OverwriteStorage(), validators=[validate_file_extension, validate_file_size]) def name(self): parts = self.file.path.split("/") file_name = parts[len(parts) - 1] return file_name
class File(models.Model): file = PrivateFileField("File") published = models.BooleanField() description = models.CharField( blank=True, null=True, verbose_name="Açıklama", help_text="Varsa dosya ile ilgili açıklama.", max_length=64) date = models.DateTimeField(blank=True, null=True, verbose_name="Dosyanın ürtildiği tarih", help_text="Biliniyorsa.")
class AssetFile(models.Model): # More to come! MAP_LAYER = 'map_layer' TYPE_CHOICES = ((MAP_LAYER, MAP_LAYER), ) uid = KpiUidField(uid_prefix='af') asset = models.ForeignKey('Asset', related_name='asset_files') # Keep track of the uploading user, who could be anyone with `change_asset` # rights, not just the asset owner user = models.ForeignKey('auth.User', related_name='asset_files') file_type = models.CharField(choices=TYPE_CHOICES, max_length=32) name = models.CharField(max_length=255) date_created = models.DateTimeField(default=timezone.now) # TODO: Handle deletion! The file won't be deleted automatically when the # object is removed from the database content = PrivateFileField(upload_to=upload_to, max_length=380) metadata = JSONBField(default=dict)
class InAppMessageFile(models.Model): """ A file uploaded by the django-markdownx editor. It doesn't have a foreign key to `InAppMessage` because it was likely uploaded while the message was still being drafted, before ever being saved in the database """ # TODO: Clean these up if they're no longer referenced by an # `InAppMessage`? Parse the Markdown to figure it out? GitHub does it # somehow… content = PrivateFileField( # Avoid collisions with usernames, which must begin with `[a-z]` # (see `kpi.forms.USERNAME_REGEX`) upload_to='__in_app_message/%Y/%m/%d/') def __str__(self): return self.content.name
class DocumentTemplate(models.Model): """Document that is produced in a certain phase of a project. Project attribute data is rendered into the given document template. """ name = models.CharField(max_length=255, verbose_name=_("name")) slug = models.SlugField() common_project_phases = models.ManyToManyField( CommonProjectPhase, verbose_name=_("project phase"), related_name="document_templates", ) silent_downloads = models.BooleanField( default=False, verbose_name=_("Downloading document doesn't trigger warnings"), ) def get_upload_subfolder(self): return ["document_templates", self.slug] file = PrivateFileField( "File", storage=KaavapinoPrivateStorage( base_url=reverse_lazy( "serve_private_document_template_file", kwargs={"path": ""} ), url_postfix="document_templates", ), upload_subfolder=get_upload_subfolder, max_length=255, ) image_template = models.BooleanField( verbose_name=_("image template"), default=False, ) class Meta: verbose_name = _("document template") verbose_name_plural = _("document templates") def __str__(self): return self.name def save(self, *args, **kwargs): self.slug = slugify(self.name) return super().save(*args, **kwargs)
class File(models.Model): file = PrivateFileField(upload_to=file_upload_location, validators=[validate_file_type]) accession = models.ForeignKey('Accession', on_delete=models.CASCADE) file_description = models.TextField(blank=True) content_type = models.CharField(max_length=255, blank=True) date_file_submitted = models.DateTimeField(auto_now_add=True) def get_filename(self): return os.path.basename(self.file.name) get_filename.short_description = 'Filename' def file_download_element(self): return format_html('<a href="{0}" download="{1}">Download file</a>', self.file.url, self.get_filename()) file_download_element.short_description = 'Download' def image_thumb(self): return format_html('<img src="{}" width="100" height="100" />', self.file.url) def clickable_thumb(self): if self.content_type.split('/')[0] == 'image': thumb = self.image_thumb() else: thumb = self.icon_thumb() return format_html('<a href="{0}" target="_blank">{1}</a>', self.file.url, thumb) clickable_thumb.short_description = 'View file' def icon_thumb(self): mime_type = self.content_type.split('/')[0] if self.content_type in list(ACCEPTED_FILE_TYPES.keys()): icon_class = ACCEPTED_FILE_TYPES[self.content_type] elif '{0}/{1}'.format(mime_type, '*') in list(ACCEPTED_FILE_TYPES.keys()): icon_class = ACCEPTED_FILE_TYPES['{0}/{1}'.format(mime_type, '*')] else: icon_class = 'file-o' return format_html('<i class="fa fa-{0} fa-5x"></i>', icon_class) def __str__(self): return self.get_filename()
class Guide(CommonInfo): name = models.CharField(verbose_name="Name", max_length=50, unique=True) guide = RichTextUploadingField(verbose_name="Text", blank=True, null=True) file = PrivateFileField("File", storage=storage1, upload_to=upload_guide, blank=True, null=True) profile = models.ForeignKey(Profile, on_delete=models.CASCADE) slug = models.SlugField(unique=True) class Meta: verbose_name = "Guide" verbose_name_plural = "Guides" ordering = ['-last_modified_at'] def __str__(self): return self.name def save(self, *args, **kwargs): self.slug = slugify(self.name) super(Guide, self).save(*args, **kwargs)
class ElectricityBill(AbstractTimestampModel): project = models.ForeignKey(Project, related_name='electricity_bills', null=True, blank=True) date = models.DateField(null=True, blank=True) private_file = PrivateFileField( upload_to='uploads/electricity_bills/', help_text='Please upload a .pdf file if possible.', null=True, ) def __str__(self): return "Electricity bill - {}".format(self.date_str) @property def date_str(self): if self.date: date_str = self.date.strftime("%b. %Y") else: date_str = "unknown" return "{}".format(date_str)
class SubmissionCache(models.Model): created_date = models.DateTimeField(default=timezone.now) user_handle = models.ForeignKey(UserProfile, related_name='user_c_submission', on_delete=models.CASCADE) problem_submitted = models.ForeignKey(Problem, related_name='problem_c_submission', on_delete=models.CASCADE) language = models.CharField(blank=True, default='c_cpp', max_length=100, choices=lang_choices) actual_language = models.CharField(blank=True, max_length=100) solution = PrivateFileField(upload_to=user_directory_path) sidno = models.PositiveIntegerField(blank=True, null=True) judged = models.CharField(blank=True, default='no', max_length=5) def __str__(self): return 'p_{}_u_{}_s_{}'.format(self.problem_submitted.problem_name, self.user_handle.username, str(self.id))
class Track(models.Model): """ The actual track, uploaded by the user to be mixed. Tracks are always part of a Group. """ group = models.ForeignKey(Group, related_name="tracks") file = PrivateFileField("File", max_length=255, upload_to=private_track_path) class Meta: verbose_name = "track" verbose_name_plural = "tracks" def __str__(self): # Filename and extension try: return self.file.name.split('/')[-1] except AttributeError: return ""
class Book(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) title = models.CharField(max_length=200) author = models.CharField(max_length=200) price = models.DecimalField(max_digits=6, decimal_places=2) cover = models.ImageField(upload_to='covers/', blank=True) pdf_file = PrivateFileField("File") class Meta: indexes = [ models.Index(fields=['id'], name='id_index'), ] permissions = [ ("special_status", "Can read all books"), ] def __str__(self): return self.title def get_absolute_url(self): return reverse('book_detail', kwargs={'pk': str(self.pk)})
class DataSource(OwnedResourceModel): file = PrivateFileField(upload_to=get_encoded_filepath, max_file_size=4194304) # file = PrivateFileField("File") shared_users = models.ManyToManyField( 'users.User', blank=True, related_name='datasource_shared_users') shared_groups = models.ManyToManyField( Group, blank=True, related_name='datasource_shared_groups') objects = models.Manager() def get_filename(self): return os.path.basename(self.file.name) def get_absolute_url(self): return reverse('datamanagement:datasource-detail', kwargs={'id': self.id}) def get_full_path(self): return self.file.full_path def get_owned_datasources(self, user): return DataSource.objects.filter(owner=user) def get_public_datasources(self): return DataSource.objects.filter( accessibility=DataSource.ACCESSIBILITY_PUBLIC) @delete_previous_file def save(self, force_insert=False, force_update=False, using=None, update_fields=None): super(DataSource, self).save() @delete_previous_file def delete(self, using=None, keep_parents=False): super(DataSource, self).delete()
class DocumentTemplate(models.Model): """Document that is produced in a certain phase of a project. Project attribute data is rendered into the given document template. """ name = models.CharField(max_length=255, verbose_name=_("name")) slug = models.SlugField() project_phase = models.ForeignKey( ProjectPhase, verbose_name=_("project phase"), related_name="document_templates", on_delete=models.CASCADE, ) def get_upload_subfolder(self): phase_name = slugify(self.project_phase.name) return ["document_templates", phase_name, self.slug] file = PrivateFileField( "File", storage=KaavapinoPrivateStorage( base_url=reverse_lazy("serve_private_document_template_file", kwargs={"path": ""}), url_postfix="document_templates", ), upload_subfolder=get_upload_subfolder, max_length=255, ) class Meta: verbose_name = _("document template") verbose_name_plural = _("document templates") def __str__(self): return self.name def save(self, *args, **kwargs): self.slug = slugify(self.name) return super().save(*args, **kwargs)
class ProjectAttributeFile(models.Model): """Project attribute value that is an file.""" attribute = models.ForeignKey( Attribute, verbose_name=_("attribute"), related_name="files", on_delete=models.CASCADE, ) project = models.ForeignKey( Project, verbose_name=_("project"), related_name="files", on_delete=models.CASCADE, ) def get_upload_subfolder(self): project_id = str(self.project.pk) if not project_id: raise ValueError("No project id could be found, can't save file!") return ["projects", project_id, self.attribute.identifier] file = PrivateFileField( "File", storage=KaavapinoPrivateStorage( base_url=reverse_lazy("serve_private_project_file", kwargs={"path": ""}), url_postfix="projects", ), upload_subfolder=get_upload_subfolder, max_length=255, ) class Meta: verbose_name = _("project attribute file") verbose_name_plural = _("project attribute files") def __str__(self): return f"{self.project} {self.attribute}"
class StaffDocument(TimeStampedModel, models.Model): """StaffDocument model class.""" staff = models.ForeignKey(StaffProfile, verbose_name=_("Staff Member"), on_delete=models.CASCADE) name = models.CharField(_("Name"), max_length=255) description = models.TextField(_("Description"), blank=True, default="") file = PrivateFileField( _("File"), upload_to="staff-documents/", help_text=_("Upload staff member document"), content_types=[ "application/pdf", "application/msword", "application/vnd.oasis.opendocument.text", "image/jpeg", "image/png", ], max_file_size=10485760, ) public = models.BooleanField( _("Public"), help_text=_("If public, it will be available to everyone."), blank=True, default=False, ) class Meta: # pylint: disable=too-few-public-methods """Meta options for StaffDocument.""" abstract = False verbose_name = _("Staff Document") verbose_name_plural = _("Staff Documents") ordering = ["staff", "name", "-created"] def __str__(self): """Unicode representation of class object.""" return f"{self.staff.get_name()} - {self.name}"
class Key(CommonInfo): name = models.CharField(verbose_name="Name", max_length=50) username = models.CharField(verbose_name="Username", max_length=50, blank=True, null=True) password = EncryptedCharField(verbose_name="Password", max_length=50, blank=True, null=True) note = models.CharField(verbose_name="Note", max_length=200, blank=True, null=True) url = models.CharField(verbose_name="URL", max_length=200, blank=True, null=True) file = PrivateFileField("File", storage=storage1, upload_to=upload_key, blank=True, null=True) profile = models.ForeignKey(Profile, on_delete=models.CASCADE) slug = models.SlugField() history = HistoricalRecords() class Meta: verbose_name = "Key" verbose_name_plural = "Keys" ordering = ['name'] def __str__(self): return self.name def save(self, *args, **kwargs): self.slug = slugify(self.name) super(Key, self).save(*args, **kwargs)