Group.add_to_class( 'label', models.CharField(_('Label'), max_length=150, help_text=_('Label of the group.'))) # CreationModel Group.add_to_class( 'created_at', models.DateTimeField(_('Created at'), auto_now_add=True, editable=False, help_text=_('Date when it was created.'))) Group.add_to_class( 'created_by', CurrentUserField(verbose_name=_('Created by'), related_name='created_%(class)s', help_text=_('User who created it.'))) # ModificationModel Group.add_to_class( 'modified_at', models.DateTimeField(_('Modified at'), auto_now=True, editable=False, help_text=_('Date when it was modified.'))) Group.add_to_class( 'modified_by', models.ForeignKey('user.User', verbose_name=_('Modified by'), related_name='modified_%(class)s', on_delete=models.CASCADE, help_text=_('User who modified it.')))
class Ad(BaseModel): title = models.CharField(max_length=200, verbose_name=_('Title')) slug = AutoSlugField(populate_from=['title'], verbose_name=_('Slug')) category = models.ForeignKey('categories.Category', null=True, on_delete=models.SET_NULL, verbose_name=_('Category')) description = models.TextField(verbose_name=_('Description')) price = models.DecimalField(max_digits=64, decimal_places=2, blank=True, null=True, default=0.00, verbose_name=_('Price')) user_currency = models.CharField(null=True, max_length=3, choices=[('CUC', 'CUC'), ('CUP', 'CUP')], default='CUC', verbose_name=_('Currency')) province = models.ForeignKey(Province, blank=True, null=True, on_delete=models.SET_NULL, verbose_name=_('Province')) municipality = models.ForeignKey(Municipality, blank=True, null=True, on_delete=models.SET_NULL, verbose_name=_('Municipality')) external_source = models.CharField(max_length=200, blank=True, null=True, verbose_name=_('External source')) external_id = models.CharField(max_length=200, blank=True, null=True, verbose_name=_('External ID')) external_url = models.URLField(blank=True, null=True, verbose_name=_('External URL')) created_by = CurrentUserField(verbose_name=_('Created by')) updated_by = CurrentUserField(on_update=True, related_name='%(class)s_updated_by', verbose_name=_('Updated by')) class Meta: verbose_name = _('Ad') verbose_name_plural = _('Ads') def __str__(self): return self.title def get_absolute_url(self): if self.external_source and self.external_url: return self.external_url return urls.reverse('ads:detail', args=(self.slug, )) def save(self, force_insert=False, force_update=False, using=None, update_fields=None): if self.user_currency == 'CUC': self.price = Decimal(self.price) * settings.CUC_TO_CUP_CHANGE super().save(force_insert, force_update, using, update_fields) def get_user_price(self): if self.user_currency == 'CUC': return self.price / settings.CUC_TO_CUP_CHANGE return self.price
class Variety(models.Model): serial_no = models.CharField(max_length=12, primary_key=True) global_crop = models.ForeignKey('GlobalCrop', on_delete=models.CASCADE) crop_family = models.ForeignKey('CropFamily', on_delete=models.CASCADE) species = models.ForeignKey('Species', on_delete=models.CASCADE) product_type = models.ForeignKey('ProductType', on_delete=models.SET_NULL, null=True, blank=True) variety_seed_type = models.CharField(max_length=2, choices=constant.SEED_TYPE) global_name = models.CharField(max_length=50, blank=True, null=True) variety_supplier_name = models.CharField(max_length=50) variety_supplier_id = models.CharField( max_length=50, validators=[space_prohibited_validator], null=True, blank=True) supplier_contact = models.ForeignKey('contact.Contact', on_delete=models.CASCADE) photo = models.ImageField(upload_to='seed/repo/variety/image', null=True, blank=True) photo_title = models.CharField(max_length=70, null=True, blank=True) photo_legend = models.CharField(max_length=100, null=True, blank=True) created_by = CurrentUserField() created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) updated_by = models.ForeignKey('auth.User', on_delete=models.SET_NULL, null=True, related_name='updated_user') group = models.ManyToManyField('auth.Group', null=True, blank=True) class Meta: permissions = (('group_level', 'Group level'), ) def __str__(self): # if self.global_name: # return self.global_name return self.variety_supplier_name def get_absolute_url(self): return reverse('variety-detail', args=[self.serial_no]) # return reverse('variety-detail', args=[self.serial_no]) # return reverse('variety-detail', args=[str(self.pk)]) def shot_image(self, obj): return self.photo.url def filename(self): # return os.path.basename(self.photo.name) return basename(splitext(self.photo.name)[0]) def pdf_url(self): return reverse('pdf', args=[str(self.global_name)]) def save(self, *args, **kwargs): if not self.global_name: self.global_name = self.variety_supplier_name super().save(*args, **kwargs)
class Entity(models.Model): class Meta: abstract = True ACTIVE = 1 DELETED = 2 STATES = ( (ACTIVE, 'Active'), (DELETED, 'Deleted'), ) owner = CurrentUserField() state = models.IntegerField(choices=STATES, default=ACTIVE) date_created = models.DateTimeField(auto_now_add=True) date_updated = models.DateTimeField(auto_now=True) @classmethod def field_exists(cls, field): try: cls._meta.get_field(field) return True except FieldDoesNotExist: return False @classmethod def prepare_metadata(cls, metadata, **kwargs): def field_name(mk): k = mk[len(cls.PREFIX):] if '.' in mk else mk return cls.METADATA_TO_FIELD.get(k, k) metadata = { k: metadata.FIELDS[k].unparse(v) for k, v in metadata.items() } filtered_metadata = { k: v for k, v in dict(metadata, **kwargs).items() if '.' not in k or k.startswith(cls.PREFIX) } return { field_name(k): v for k, v in filtered_metadata.items() if v is not None and cls.field_exists(field_name(k)) } @classmethod def from_metadata(cls, metadata, **kwargs): values = cls.prepare_metadata(metadata, **kwargs) kwargs = {k: values.get(k) for k in cls.IDENTITY if values.get(k)} obj, created = cls.objects.get_or_create(defaults=values, **kwargs) obj._created = created return obj @classmethod def from_files(cls, *files, owner=None): metadata = Metadata() for filepath in files: parse_datafile(filepath, metadata=metadata) return cls.from_metadata(metadata)
class MaxQuantResult(models.Model): created_by = CurrentUserField() created = models.DateTimeField(default=timezone.now) raw_file = models.OneToOneField('RawFile', on_delete=models.CASCADE) @property def pipeline(self): return self.raw_file.pipeline def __str__(self): return str(self.name) @property def name(self): return str(self.raw_file.name) @property def raw_fn(self): return self.raw_file.path @property def basename(self): return self.raw_fn.with_suffix('').name @property def mqpar_fn(self): return self.pipeline.mqpar_path @property def fasta_fn(self): return self.pipeline.fasta_path @property def run_directory(self): return COMPUTE_ROOT / 'tmp' / 'MaxQuant' / self.name @property def pipename(self): return self.pipeline.name @property def path(self): return self.raw_file.output_dir @property def output_dir_maxquant(self): return self.path / 'maxquant' @property def output_dir_rawtools(self): return self.path / 'rawtools' @property def output_dir_rawtools_qc(self): return self.path / 'rawtools_qc' @property def maxquant_binary(self): return self.pipeline.maxquant_executable @property def output_directory_exists(self): return self.path.is_dir() @property def maxquantcmd(self): return 'maxquant' @property def run_directory_exists(self): return self.run_directory.is_dir() @property def use_downstream(self): return self.raw_file.use_downstream def maxquant_parameters(self): mqpar_file = str(self.mqpar_fn) fasta_file = str(self.fasta_fn) run_directory = str(self.run_directory) output_dir = str(self.output_dir_maxquant) maxquantcmd = str(self.maxquantcmd) params = dict( maxquantcmd=maxquantcmd, mqpar_file=mqpar_file, fasta_file=fasta_file, run_dir=run_directory, output_dir=output_dir, ) print('MQ parameters:', params) return params def run_maxquant(self, rerun=False): raw_file = str(self.raw_fn) run_maxquant.delay(raw_file, self.maxquant_parameters()) def run_rawtools_qc(self, rerun=False): inp_dir, out_dir = str(self.raw_file.path.parent), str( self.output_dir_rawtools_qc) if rerun and os.path.isdir(out_dir): shutil.rmtree(out_dir) if rerun or (self.n_files_rawtools_qc == 0): rawtools_qc.delay(inp_dir, out_dir) def run_rawtools_metrics(self, rerun=False): raw_fn, out_dir, args = str(self.raw_file.path), str( self.output_dir_rawtools), self.pipeline.rawtools.args if rerun and os.path.isdir(out_dir): shutil.rmtree(out_dir) if rerun or (self.n_files_rawtools_metrics == 0): rawtools_metrics.delay(raw_fn, out_dir, args) def run(self): self.run_maxquant() self.run_rawtools_metrics() self.run_rawtools_qc() def get_data_from_file(self, fn='proteinGroups.txt'): abs_fn = self.output_dir_maxquant / fn if abs_fn.is_file(): df = MaxQuantReader().read(abs_fn) if df is None: return None df['RawFile'] = str(self.raw_file.name) df['Project'] = str(self.raw_file.pipeline.project.name) df['Pipeline'] = str(self.raw_file.pipeline.name) df = df.set_index(['Project', 'Pipeline', 'RawFile']).reset_index() return df else: return None @property def url(self): return reverse('maxquant:mq_detail', kwargs={'pk': self.pk}) @property def download(self): stream = BytesIO() files = glob(self.output_directory + '/**/*.*', recursive=True) with zipfile.ZipFile(stream, 'w') as temp_zip_file: for fn in files: temp_zip_file.write(fn, arcname=basename(fn)) return stream.getvalue() @lru_cache(10) def maxquant_qc_data(self): df = load_maxquant_data_from(self.path) if df is None: df = pd.DataFrame() df['RawFile'] = self.raw_fn.with_suffix('').name return df.set_index('RawFile').reset_index() @lru_cache(10) def rawtools_qc_data(self): df = load_rawtools_data_from(self.path) if df is None: df = pd.DataFrame() df['RawFile'] = self.raw_fn.with_suffix('').name return df.set_index('RawFile').reset_index() @property def parquet_path(self): return self.pipeline.parquet_path def create_protein_quant(self): fn_txt = 'proteinGroups.txt' abs_fn_txt = self.output_dir_maxquant / fn_txt abs_fn_par = self.protein_quant_fn if not abs_fn_par.is_file(): if not abs_fn_par.parent.is_dir(): os.makedirs(abs_fn_par.parent) df = self.get_data_from_file('proteinGroups.txt') if df is None: return None df.to_parquet(abs_fn_par) return abs_fn_par @property def protein_quant_fn(self): basename = self.basename par_path = (self.parquet_path / 'protein_groups' / basename).with_suffix('.parquet') return par_path @property def n_files_maxquant(self): return len(glob(f'{self.output_dir_maxquant/"*.*"}')) @property def n_files_rawtools_metrics(self): return len(glob(f'{self.output_dir_rawtools/"*.*"}')) @property def n_files_rawtools_qc(self): return len(glob(f'{self.output_dir_rawtools_qc/"*.*"}')) @property def status_protein_quant_parquet(self): fn = self.protein_quant_fn if not fn.is_file(): return 'File not found' try: pd.read_parquet(fn) return 'OK' except: return 'Not readable.'
class MaxQuantPipeline(MaxQuantParameter, FastaFile, RawToolsSetup): class Meta: verbose_name = _("MaxQuant Pipeline") verbose_name_plural = _("MaxQuant Pipelines") maxquant_pipepline_id = models.AutoField(primary_key=True) created_by = CurrentUserField() created = models.DateField(default=timezone.now) project = models.ForeignKey("project.Project", on_delete=models.PROTECT, null=True) name = models.CharField(max_length=500, unique=True, null=False) run_automatically = models.BooleanField(default=False) regular_expressions_filter = models.CharField(max_length=256, default=".*") maxquant_executable = models.FilePathField( path=str(COMPUTE_ROOT), match=".*MaxQuantCmd.exe", recursive=True, null=True, blank=True, max_length=2000, help_text= "If this field is empty the default MaxQuant version (1.6.10.43) will be used. " "To try a different version go to MaxQuant Executables. If this is changed, " "all MaxQuant jobs in this pipeline should be rerun.", ) slug = models.SlugField(max_length=500, unique=False, default=uuid4) uuid = models.CharField( max_length=36, default=uuid4, help_text= "UID to use the pipeline with the Python API (in the lrg-omics package)", ) description = models.TextField(max_length=1000, default="") def __str__(self): return self.name @property def tmp_dir(self): return f"{TMP_ROOT}/{self.project.slug}/{self.slug}" def save(self, *args, **kwargs): self.slug = slugify(self.name) return super().save(*args, **kwargs) def get_absolute_url(self): return reverse( "pipeline-detail", kwargs={ "pipeline": self.slug, "project": self.project.slug }, ) @property def path(self): return self.project.path / self._id @property def path_as_str(self): return str(self.path) @property def _id(self): return f"{self.project.id}MQ{self.pk}" @property def config_path(self): return self.path / "config" @property def result_path(self): return self.path / "result" @property def input_path(self): return self.path / "inputs" @property def output_path(self): return self.path / "output" @property def mqpar_path(self): return self.path / "config" / "mqpar.xml" @property def fasta_path(self): return self.path / "config" / "fasta.faa" @property def path_exists(self): return self.path.is_dir() @property def url(self): return reverse( "maxquant:detail", kwargs={ "project": self.project.slug, "pipeline": self.slug }, ) @property def parquet_path(self): return self.path / "parquet" @property def has_maxquant_config(self): if self.fasta_file.name and self.mqpar_file.name: return True return False
class DocumentoFiscal(models.Model): #Lojista_Id = models.ForeignKey('Lojista', verbose_name=u'Loja', on_delete=models.SET_NULL, null=True) #Participante_Id = models.ForeignKey('Participante', default=1, verbose_name=u'Participante', on_delete=models.SET_NULL, null=True) user = models.ForeignKey(User, related_name='rel_username', editable=False, on_delete=models.PROTECT) lojista = models.ForeignKey(Lojista, related_name='rel_lojista', null=False, blank=False, default=1, on_delete=models.PROTECT) vendedor = models.CharField(verbose_name=u'Nome do Vendedor', max_length=50, blank=True, null=True) numeroDocumento = models.CharField(verbose_name=u'Número do Documento', max_length=12, blank=False, null=False, unique=True) dataDocumento = models.DateField(verbose_name=u'Data do Documento', null=False, blank=False) valorDocumento = models.DecimalField( verbose_name=u'Valor do Documento', max_digits=7, decimal_places=2, blank=False, default=0, validators=[ validators.MinValueValidator( 40, message='O valor do documento deve ser maior que 40 reais!') ]) compradoREDE = models.BooleanField( verbose_name=u'Comprou na maquininha da REDE?', default=False) compradoMASTERCARD = models.BooleanField( verbose_name=u'Comprou com MASTERCARD?', default=False) valorREDE = models.DecimalField(verbose_name=u'Valor na REDE', max_digits=7, decimal_places=2, editable=False, blank=True, default=0) #depois posso nao mostrar photo = models.ImageField(upload_to='docs/%Y/%m/%d', blank=True, verbose_name=u'Foto do documento fiscal') photo2 = models.ImageField(upload_to='docs2/%Y/%m/%d', blank=True, verbose_name=u'Foto do comprovante do cartão') valorMASTERCARD = models.DecimalField(verbose_name=u'Valor no MASTERCARD', max_digits=7, decimal_places=2, editable=False, blank=True, default=0) #depois posso nao mostrar valorVirtual = models.DecimalField(verbose_name=u'Valor com Bonificações', max_digits=7, decimal_places=2, editable=False, blank=True, default=0) #depois posso nao mostrar dataCadastro = models.DateTimeField(verbose_name=u'Cadastrado em', auto_now_add=True, editable=False) cadastradoPor = CurrentUserField(verbose_name=u'Cadastrado Por', editable=False) status = models.BooleanField(verbose_name=u'Status', default=False) pendente = models.BooleanField(verbose_name=u'Pendente', default=True) observacao = models.TextField(verbose_name=u'Observação', max_length=1000, blank=True, null=True, default='Nenhuma') #slug = models.SlugField(max_length=200, blank=True) def __str__(self): return 'Documento: {}'.format(self.numeroDocumento) class Meta: #ordering = ['Participante_Id', 'NumeroDocumento'] verbose_name = (u'Documento Fiscal') verbose_name_plural = (u'Documentos Fiscais') def get_absolute_url(self): return reverse('participante:editdocfiscal', args=[self.numeroDocumento]) def get_cupons(self): if self.compradoREDE and self.compradoMASTERCARD: self.valorVirtual = self.valorDocumento * 3 self.valorREDE = self.valorDocumento * 2 self.valorMASTERCARD = self.valorDocumento * 3 elif self.compradoREDE: self.valorVirtual = self.valorDocumento * 2 self.valorREDE = self.valorDocumento * 2 self.valorMASTERCARD = 0 elif self.compradoMASTERCARD: self.valorVirtual = self.valorDocumento * 2 self.valorREDE = 0 self.valorMASTERCARD = self.valorDocumento * 2 else: self.valorVirtual = self.valorDocumento cupons = self.valorVirtual // 40 return cupons
class RawFile(models.Model): # use the custom storage class fo the FileField created_by = CurrentUserField() created = models.DateField(default=timezone.now) pipeline = models.ForeignKey("MaxQuantPipeline", on_delete=models.CASCADE, null=False, default=1) md5sum = models.CharField(max_length=36, default=timezone.now, unique=False) orig_file = models.FileField(upload_to="upload", storage=DATALAKE, max_length=1000, unique=False) slug = models.SlugField(max_length=250, null=True, blank=True) flagged = models.BooleanField(default=False) use_downstream = models.BooleanField(default=None, null=True, blank=True) class Meta: unique_together = ("orig_file", "pipeline") verbose_name = _("RawFile") verbose_name_plural = _("RawFiles") def save(self, *args, **kwargs): self.slug = slugify(self.name) if not self.pk: # file is new md5 = hashlib.md5() for chunk in self.orig_file.chunks(): md5.update(chunk) self.md5sum = md5.hexdigest() if not self.id: self.created = timezone.now() try: super(RawFile, self).save(*args, **kwargs) except IntegrityError as e: print(e) pass def __str__(self): return str(self.name) @property def name(self): return P(self.orig_file.name).name @property def path(self): return self.pipeline.input_path / P( self.name).with_suffix("").name / self.name @property def upload_path(self): return DATALAKE_ROOT / self.orig_file.name @property def filename(self): return self.path.with_suffix("") @property def rawtools_status(self): path = self.path.parent if (path / "QcDataTable.csv").is_file(): return "Done" elif (path / "rawtools.txt").is_file(): return "Running" return "New file" @property def href(self): return self.path @property def download(self): return mark_safe(f'<a href="{self.href}">Download</a>') def browse(self): return mark_safe(r'<a href="{}">Browse</a>'.format(self.href)) browse.short_description = "Browse" def detail_view(self): return mark_safe(r'<a href="{}">Details</a>'.format( self.get_absolute_url)) detail_view.short_description = "Details" def move_to_input_dir(self): src_path = self.upload_path trg_path = self.path os.makedirs(trg_path.parent, exist_ok=True) shutil.move(src_path, trg_path) # self.orig_file.path = trg_path @property def output_dir(self): return self.pipeline.output_path / self.name def submit(self): pass
class Utente(AbstractBaseUser, PermissionsMixin): """ Statuto del Territorio Base User. Fiscal code is a required/unique extra field. """ fiscal_code = models.CharField( verbose_name=_('codice fiscale'), max_length=16, help_text=_('inserire un codice fiscale valido'), validators=[ RegexValidator( regex='^(?i)(?:(?:[B-DF-HJ-NP-TV-Z]|[AEIOU])[AEIOU][AEIOUX]|' '[B-DF-HJ-NP-TV-Z]{2}[A-Z]){2}[\dLMNP-V]{2}(?:[A-EHLMPR-T]' '(?:[04LQ][1-9MNP-V]|[1256LMRS][\dLMNP-V])|[DHPS][37PT][0L]|' '[ACELMRT][37PT][01LM])(?:[A-MZ][1-9MNP-V][\dLMNP-V]{2}|[A-M][0L]' '(?:[1-9MNP-V][\dLMNP-V]|[0L][1-9MNP-V]))[A-Z]$', message=_('Codice fiscale errato.'), ), ], unique=True, db_index=True, blank=False, null=False, primary_key=True) first_name = models.CharField(verbose_name=_('nome'), max_length=255, blank=True, null=True) last_name = models.CharField(verbose_name=_('cognome'), max_length=255, blank=True, null=True) email = models.EmailField(verbose_name=_('indirizzo email'), blank=True, null=True) is_staff = models.BooleanField( _('staff status'), default=False, help_text=_( 'Designates whether the user can log into this admin site.'), ) is_active = models.BooleanField( _('active'), default=True, help_text=_( 'Designates whether this user should be treated as active. ' 'Unselect this instead of deleting accounts.'), ) date_joined = models.DateTimeField(verbose_name=_('data creazione'), auto_now_add=True) date_updated = models.DateTimeField(verbose_name=_('data ultima modifica'), auto_now=True) created_by = CurrentUserField(verbose_name=_('creato da'), editable=False, related_name='%(class)s_created') updated_by = CurrentUserField(verbose_name=_('modificato da'), editable=False, related_name='%(class)s_updated') EMAIL_FIELD = 'email' USERNAME_FIELD = 'fiscal_code' objects = IsideUserManager() def __str__(self): if self.first_name or self.last_name: first_name = self.first_name if self.first_name else '' last_name = self.last_name if self.last_name else '' return "{n1} {n2} [{cf}]".format(cf=self.fiscal_code.upper(), n1=first_name, n2=last_name) else: return "-- [{}]".format(self.fiscal_code.upper()) def get_full_name(self): if self.first_name and self.last_name: return "{} {}".format(self.last_name.title(), self.first_name.title()) else: return self.fiscal_code.upper() def get_short_name(self): if self.first_name and self.last_name: return self.first_name.title() else: return self.fiscal_code.upper() # def get_ruoli(self): # """ # User membership type for each organization # :return: UserMembership queryset # """ # return Ruolo._default_manager.filter(utente=self) class Meta: ordering = [ 'date_joined', ] verbose_name = _('utente') verbose_name_plural = _('utenti')
class Profile(models.Model): user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, related_name='profile') date_of_birth = models.DateField(blank=True, null=True) photo = models.ImageField(upload_to='users/%Y/%m/%d', blank=True) CHOICES_SEXO = (('M', 'Masculino'), ('F', 'Feminino')) nome = models.CharField(max_length=70, blank=True) RG = models.CharField(max_length=12, blank=True, unique=True) CPF = models.CharField(max_length=14, blank=True, unique=True) #dataAtual = models.DateField(verbose_name=u'Data Atual', null=True, blank=True) #mudar depois para nao colocar a data atual sexo = models.CharField(verbose_name=u'Sexo', max_length=1, choices=CHOICES_SEXO, blank=True, help_text=u'ex. M ou F') foneFixo = models.CharField(verbose_name=u'Telefone Fixo', max_length=15, blank=True, help_text=u'ex. (85)3212-0000') foneCelular1 = models.CharField(verbose_name=u'Celular1', max_length=15, blank=True, help_text=u'ex. (85)98888-8675') foneCelular2 = models.CharField(verbose_name=u'Celular2', max_length=15, blank=True, help_text=u'ex. (85)98888-8675') foneCelular3 = models.CharField(verbose_name=u'Celular3', max_length=15, blank=True, help_text=u'ex. (85)98888-8675') whatsapp = models.CharField(max_length=15, blank=True, help_text=u'ex. (85)98888-8675') facebook = models.CharField(max_length=50, blank=True, help_text=u'ex. fb.com/nomenofacebook') twitter = models.CharField(max_length=50, blank=True) endereco = models.CharField(verbose_name=u'Endereço', max_length=50, blank=True) enderecoNumero = models.CharField(verbose_name=u'Nº Endereço', max_length=8, blank=True) enderecoComplemento = models.CharField(verbose_name=u'Complemento', max_length=30, blank=True) bairro = models.CharField(max_length=40, blank=True) cidade = models.CharField(max_length=50, blank=True, default=u'Teresina') estado = models.CharField(max_length=2, blank=True, default=u'PI') CEP = models.CharField(max_length=12, blank=True) observacao = models.TextField( verbose_name=u'Observação', max_length=1000, blank=True, null=True ) #, widget=forms.Textarea(attrs={'placeholder': 'Escreva aqui alguma observação caso seja necessário.'})) dataCadastro = models.DateTimeField( verbose_name=u'Cadastrado em', auto_now_add=True, editable=False) #nao vai aparecer na tela cadastradoPor = CurrentUserField(verbose_name=u'Cadastrado Por', related_name='rel_cadastrado_por', editable=False) pergunta = models.TextField( verbose_name=u'Pergunta', max_length=50, blank=True, null=True ) #, widget=forms.Textarea(attrs={'placeholder': 'Escreva aqui alguma observação caso seja necessário.'})) ativo = models.BooleanField(default=True) pendente = models.BooleanField(default=True, verbose_name=u'Pendente') def __str__(self): return 'Nome completo {}'.format(self.user.username) def get_absolute_url_edit(self): return reverse('participante:user_edit', args=[self.user.username]) def get_absolute_url_detail(self): return reverse('participante:user_detail', args=[self.user.username])
class BaseModel(models.Model): """Act as base class for models, include some extra fields and methods""" user = CurrentUserField( related_name="%(class)s_entrys", help_text='The user that last created / modified the instance') created = models.DateTimeField( 'created at', auto_now_add=True, help_text='Date time on wich the object was created.') modified = models.DateTimeField( 'modified at', auto_now=True, help_text='Date time on wich the object was last modified.') class Meta: """Meta options""" abstract = True get_latest_by = 'created' ordering = ['-created', '-modified'] # Login require configs _query_login_required = True _create_login_required = True _update_login_required = True _delete_login_required = True @classmethod def get_config(cls): """Returns a dict wich store some configs for cls access""" return { "query_login_required": cls._query_login_required, "create_login_required": cls._create_login_required, "update_login_required": cls._update_login_required, "delete_login_required": cls._delete_login_required, } @classmethod def user_create_test(cls, user, instance): """By default test if user is the owner""" return cls.objects.get(pk=instance).user == user @classmethod def user_update_test(cls, user, instance): """By default test if user is the owner""" return cls.objects.get(pk=instance).user == user @classmethod def user_delete_test(cls, user, instance): """By default test if user is the owner""" return cls.objects.get(pk=instance).user == user @classmethod def get_serializer(cls): """Return a basic ModelSerializer ready for normal use cases""" class Serializer(ModelSerializer): """Auto build serializer from model reference""" class Meta: """Meta options""" model = cls fields = '__all__' return Serializer @classmethod def get_mutation(cls): """Return a basic DjangoSerializerMutation ready for normal use cases""" class Mutation(DjangoSerializerMutation): """Generic mutation""" class Meta: """Meta options""" description = cls.__name__ + " generic mutation" serializer_class = cls.get_serializer() @classmethod @login_required def create(cls, root, info, **kwargs): return super(Mutation, cls).create(root, info, **kwargs) @classmethod def update(cls, root, info, **kwargs): user = info.context.user instance = get_id(kwargs) if not cls._meta.model._update_login_required: return super(Mutation, cls).update(root, info, **kwargs) elif not user.is_anonymous: if cls._meta.model.user_update_test(user, instance): return super(Mutation, cls).update(root, info, **kwargs) raise Exception("Instance operation not permited") @classmethod @login_required def delete(cls, root, info, **kwargs): return super(Mutation, cls).delete(root, info, **kwargs) return Mutation @classmethod def get_type(cls): """Return a basic DjangoObjectType ready for normal use cases""" model_type = type( cls.__name__, (DjangoObjectType, ), { "pk": graphene.Int(), "Meta": { "model": cls, "fields": "__all__", "filter_fields": { "user": ["exact"] }, "interfaces": (graphene.relay.Node, ), }, }) return model_type @classmethod def get_single_resolver(cls): """Returns a function that acts as a single resolver""" def single_resolver(self, info, **kwargs): pk = kwargs.get("pk") config = cls.get_config() if pk is not None: if not config.get("query_login_required" ) or info.context.user.is_authenticated: return cls.objects.get(pk=pk) raise Exception("User not logged in") return None return single_resolver @classmethod def get_multi_resolver(cls): """Returns a function that acts as a multi resolver""" def multi_resolver(self, info, **kwargs): config = cls.get_config() exclude = kwargs.get("exclude") filters = kwargs.get("filters") orderBy = kwargs.get("orderBy") if not config.get("query_login_required" ) or info.context.user.is_authenticated: qs = cls.objects.all() if exclude: qs = qs.exclude(**exclude) if filters: qs = qs.filter(**filters) if orderBy: qs = qs.order_by(*orderBy) return gql_optimizer.query(qs, info) raise Exception("User not logged in") return multi_resolver
class RawFile(models.Model): # use the custom storage class fo the FileField created_by = CurrentUserField() created = models.DateField(default=timezone.now) pipeline = models.ForeignKey('MaxQuantPipeline', on_delete=models.CASCADE, null=False, default=1) md5sum = models.CharField(max_length=36, default=timezone.now, unique=False) #result = AutoOneToOneField('MaxQuantResult', on_delete=models.SET_NULL, null=True, blank=True) orig_file = models.FileField(upload_to='upload', storage=DATALAKE, max_length=1000, unique=False) slug = models.SlugField(max_length=250, null=True, blank=True) flagged = models.BooleanField(default=False) use_downstream = models.BooleanField(default=True) class Meta: unique_together = ('orig_file', 'pipeline') def save(self, *args, **kwargs): self.slug = slugify(self.name) if not self.pk: # file is new md5 = hashlib.md5() for chunk in self.orig_file.chunks(): md5.update(chunk) self.md5sum = md5.hexdigest() if not self.id: self.created = timezone.now() try: super(RawFile, self).save(*args, **kwargs) except IntegrityError as e: pass def __str__(self): return str(self.name) @property def name(self): return P(self.orig_file.name).name @property def path(self): return self.pipeline.input_path / P( self.name).with_suffix('').name / self.name @property def upload_path(self): return DATALAKE_ROOT / self.orig_file.name @property def filename(self): return self.path.with_suffix('') ''' @property def get_absolute_url(self): return reverse('raw_detail', kwargs={'pk': self.pk}) ''' @property def rawtools_status(self): path = dirname(self.abs_path) if isfile('QcDataTable.csv'): return 'Done' elif isfile(join(path, 'rawtools.txt')): return 'Running' return 'New file' @property def href(self): return os.path.dirname('/' + self.orig_file.name) def browse(self): return mark_safe(r'<a href="{}">Browse</a>'.format(self.href)) browse.short_description = 'Browse' def detail_view(self): return mark_safe(r'<a href="{}">Details</a>'.format( self.get_absolute_url)) detail_view.short_description = 'Details' def move_to_input_dir(self): src_path = (self.upload_path) trg_path = (self.path) print('Move raw file to inputs:', src_path, trg_path) os.makedirs(trg_path.parent, exist_ok=True) shutil.move(src_path, trg_path) @property def output_dir(self): return self.pipeline.output_path / self.name def submit(self): pass
class Listing(models.Model): """ A single critter listing """ slug = models.CharField( max_length=21, blank=True, editable=False, help_text="Unique URL path to access this listing.") created_by = CurrentUserField() created = models.DateTimeField(auto_now_add=True) modified = models.DateTimeField(auto_now=True, blank=True, null=True) name = models.CharField(max_length=settings.CRITTER_NAME_LENGTH, help_text="Critter's Name") title = models.CharField(max_length=settings.LISTING_TITLE_LENGTH, default="", help_text="Listing Title") desc = models.TextField(blank=True, default='', help_text="Describe your critter!") category = models.CharField(max_length=12, choices=settings.CRITTER_TYPES, default='???', help_text="Critter Type") species = models.CharField(max_length=24, help_text="Critter Species") age = models.IntegerField(blank=True, null=True, help_text="Critter Age") age_Format = models.CharField(blank=True, null=True, max_length=6, choices=[('Year', 'Year'), ('Years', 'Years'), ('Months', 'Months')], help_text="Year/Month") sex = models.CharField(blank=True, null=True, max_length=1, choices=[('F', 'Female'), ('M', 'Male'), ('?', 'Unknown')], help_text="Critter Gender") price = models.DecimalField(blank=True, null=True, max_digits=8, decimal_places=2, help_text="Price (USD)") critter_img = models.ImageField(blank=True, null=True, upload_to='') def __str__(self): return f"{self.name}, the {self.species}" def get_absolute_url(self): """ Returns path for a listing """ path_components = {'slug': self.slug} return reverse('show_critter', kwargs=path_components) def save(self, *args, **kwargs): """ Creates slug automatically when a listing is created """ if not self.pk: self.slug = slugify( self.name + " " + ''.join(choice(ascii_letters + digits) for _ in range(4)), allow_unicode=True) # Call save on the superclass. return super(Listing, self).save(*args, **kwargs)
class UserModelMixin(models.Model): user = CurrentUserField() class Meta: abstract = True
class UserData(models.Model): user = CurrentUserField(on_delete=models.PROTECT) class Meta: abstract = True