class TextAnnotation(models.Model): kind = models.CharField( max_length=255, default=hookset.TEXT_ANNOTATION_DEFAULT_KIND, choices=hookset.TEXT_ANNOTATION_KIND_CHOICES, ) data = JSONField(default=dict, blank=True) idx = models.IntegerField(help_text="0-based index") text_parts = SortedManyToManyField( "scaife_viewer_atlas.Node", related_name="text_annotations" ) urn = models.CharField(max_length=255, blank=True, null=True) def resolve_references(self): if "references" not in self.data: print(f'No references found [urn="{self.urn}"]') return desired_urns = set(self.data["references"]) reference_objs = list(Node.objects.filter(urn__in=desired_urns)) resolved_urns = set([r.urn for r in reference_objs]) delta_urns = desired_urns.symmetric_difference(resolved_urns) if delta_urns: print( f'Could not resolve all references, probably due to bad data in the CEX file [urn="{self.urn}" unresolved_urns="{",".join(delta_urns)}"]' ) self.text_parts.set(reference_objs)
class Galeria(models.Model): GALERIA_CHOICES = ( ('galeria1', 'Galeria 1'), ('galeria2', 'Galeria 2') ) secretaria = models.CharField(verbose_name='secretaria', max_length=60, choices=SECRETARIA_CHOICES, default='administracao') titulo = models.CharField(verbose_name='título', max_length=80) slug = models.SlugField(verbose_name='URL (slug)', blank=True, null=True, max_length=80) imagens = SortedManyToManyField(FotoGaleria) publicacao = models.DateTimeField(verbose_name='publicação', auto_now_add=True) secao = models.CharField(verbose_name='galeria de imagens', max_length=11, choices=GALERIA_CHOICES, default='galeria1') class Meta: db_table = 'tb_galeria' verbose_name = 'galeria' verbose_name_plural = 'galerias' ordering = ('-publicacao',) def get_absolute_url(self): return reverse("galerias:galeria_detail", kwargs={"slug": self.slug}) def save(self, *args, **kwargs): if self.slug == '': self.slug = slugify(self.titulo) super(Galeria, self).save(*args, **kwargs) def __str__(self): return self.titulo
class RelatedSpeakersPlugin(CMSPlugin): # NOTE: This one does NOT subclass NewsBlogCMSPlugin. This is because this # plugin can really only be placed on the article detail view in an apphook. cmsplugin_ptr = models.OneToOneField(CMSPlugin, on_delete=models.CASCADE, related_name='+', parent_link=True) title = models.CharField(max_length=255, blank=True, verbose_name=_('Title')) icon = Icon(blank=False, default='') image = FilerImageField(on_delete=models.SET_NULL, null=True, blank=True, related_name="related_speakers") number_of_people = models.PositiveSmallIntegerField( verbose_name=_('Number of people')) layout = models.CharField(max_length=30, verbose_name=_('layout'), blank=True, default='', choices=[]) speakers = SortedManyToManyField(Speaker, verbose_name=_('speakers'), blank=True, symmetrical=False) def copy_relations(self, oldinstance): self.speakers.set(oldinstance.speakers.all()) def __str__(self): return get_template_title(RELATED_SPEAKERS_LAYOUTS, self.layout)
class Program(TimeStampedModel): site = models.ForeignKey(Site, on_delete=models.CASCADE) uuid = models.UUIDField(verbose_name='UUID') title = models.CharField(max_length=255) # We store runs not courses, since not all runs of a course are in a program course_runs = SortedManyToManyField(CourseRun, related_name='programs') authoring_organizations = SortedManyToManyField(Organization, blank=True, related_name='authored_programs') type = models.CharField(max_length=32, blank=False, default='') class Meta: unique_together = ( ('site', 'uuid'), ) def __str__(self): return self.title
class MenuGroup(models.Model): name = models.CharField( max_length=64, verbose_name="názov", help_text="Zobrazí sa v menu pre všetky skupiny okrem prvej.", ) staff_only = models.BooleanField(default=False, verbose_name="iba pre vedúcich") position = models.IntegerField(verbose_name="pozícia") site = models.ForeignKey( Site, related_name="menu_groups", db_index=True, verbose_name="stránka", on_delete=models.CASCADE, ) items = SortedManyToManyField(MenuItem, related_name="groups", verbose_name="položky") def __str__(self): return "%s #%d: %s" % (str(self.site), self.position, self.name) class Meta: verbose_name = "Skupina v menu" verbose_name_plural = "Skupina v menu" unique_together = ("position", "site")
class CVDocumentSkills(TranslatableModel): id_name = models.CharField( verbose_name=gettext_lazy("Identification name"), max_length=100) translation = TranslatedFields(section_title=models.CharField( verbose_name=gettext_lazy('Section title'), max_length=255)) technologies = SortedManyToManyField( Technology, verbose_name=gettext_lazy('Technologies')) @property def languages_skills(self): return CVDocumentSkillLanguage.objects.get(document_skills=self.id) def other_skills(self): return CVDocumentSkillOther.objects.get(document_skills=self.id) def __str__(self): return self.id_name class Meta: verbose_name = gettext_lazy('Document skills') verbose_name_plural = gettext_lazy('Documents skills') db_table = 'app_owner_cv_doc_skills'
class DoItYourselfShelf(models.Model): books = SortedManyToManyField( Book, sort_value_field_name='diy_sort_number', related_name='diy_shelves', base_class=BaseBookThrough )
class Pathway(TimeStampedModel): """ Connects an organization and programs to a Pathway. Pathways can be credit pathways that represent channels where learners can send their records for credit, or professional pathways. .. no_pii: This model has no learner PII. The email address used here is the email address associated with the pathway itself (such as '*****@*****.**'), not with a learner. """ pathway_type = models.CharField( max_length=32, choices=[(tag.value, tag.value) for tag in PathwayType], default=PathwayType.CREDIT.value, ) site = models.ForeignKey(Site, on_delete=models.CASCADE) uuid = models.UUIDField(verbose_name='UUID') name = models.CharField(max_length=255) org_name = models.CharField(max_length=255) email = models.EmailField() programs = SortedManyToManyField(Program, related_name='pathways') class Meta: unique_together = ( ('site', 'uuid'), ) def __str__(self): return self.name
class Config(OrgMixin, TemplatesVpnMixin, AbstractConfig): """ Concrete Config model """ device = models.OneToOneField('config.Device', on_delete=models.CASCADE) templates = SortedManyToManyField( 'config.Template', related_name='config_relations', verbose_name=_('templates'), base_class=TemplatesThrough, blank=True, help_text=_('configuration templates, applied from ' 'first to last')) vpn = models.ManyToManyField('config.Vpn', through='config.VpnClient', related_name='vpn_relations', blank=True) class Meta(AbstractConfig.Meta): abstract = False def clean(self): if not hasattr(self, 'organization') and self._has_device(): self.organization = self.device.organization super(Config, self).clean()
class D6(models.Model): customer = models.CharField(max_length=100) user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='d6_user') day1 = SortedManyToManyField(Activities, related_name='d6_day1_activities') day2 = models.ManyToManyField(Activities, blank=True, related_name='d6_day2_activities') day3 = models.ManyToManyField(Activities, blank=True, related_name='d6_day3_activities') day4 = models.ManyToManyField(Activities, blank=True, related_name='d6_day4_activities') day5 = models.ManyToManyField(Activities, blank=True, related_name='d6_day5_activities') day6 = models.ManyToManyField(Activities, blank=True, related_name='d6_day6_activities') has_closed = models.BooleanField(blank=True, default=False) price = models.PositiveIntegerField(blank=True, default=0) def __str__(self): return f"{self.user}"
class TextAlignment(models.Model): """ Tracks an alignment between one or more texts. """ label = models.CharField(blank=True, null=True, max_length=255) description = models.TextField(blank=True, null=True) # TODO: Formalize CITE data model for alignments urn = models.CharField(max_length=255, unique=True) """ metadata contains author / attribution information """ metadata = JSONField(default=dict, blank=True) """ versions being sorted maps onto the "items" within a particular record """ versions = SortedManyToManyField( "scaife_viewer_atlas.Node", related_name="text_alignments" ) def __str__(self): return self.label
class Persona(models.Model): opcionesSexo = (('H', 'Hombre'), ('M', 'Mujer')) nombre = models.CharField('Nombre', max_length=50) apellido1 = models.CharField('Primer apellido', max_length=50) apellido2 = models.CharField('Segudo apellido', max_length=50, null=True, blank=True) sexo = models.CharField('Sexo', max_length=5, choices=opcionesSexo) identificacion = models.CharField('Identificacion', max_length=50, unique=True) fecha = models.DateField('Fecha nacimiento') celular = models.CharField('Celular', max_length=30, null=True, blank=True) telefono = models.CharField('Telefono', max_length=30, null=True, blank=True) correo = models.EmailField('Correo', unique=True) usuario = models.OneToOneField(User, on_delete=models.CASCADE) fotos = SortedManyToManyField('photologue.Photo', related_name='fotos', blank=True) #usuario = models.CharField('Usuario', max_length=50) #clave = models.CharField('Clave', max_length=50) #confirmacion = models.CharField('Confirmar clave', max_length=50) def nombreCompleto(self): return self.nombre + ' ' + self.apellido1 + ' ' + self.apellido2
class Ressource(models.Model): titre = models.CharField(db_index=True, max_length=767) slug = models.SlugField(unique=True, max_length=255, blank=True) texte = models.TextField(db_index=True, blank=True) lien_texte = models.CharField(max_length=767, blank=True) annee = models.IntegerField(db_index=True, choices=ressource_year_choices) mois = models.SlugField(max_length=30, blank=True, choices=ressource_mois_choices) lieu = models.CharField(db_index=True, max_length=300, blank=True) page_deb = models.IntegerField(null=True, blank=True, verbose_name='Page de début') page_fin = models.IntegerField(null=True, blank=True, verbose_name='Page de fin') date_debut = models.DateField(null=True, blank=True, verbose_name='Date de début') date_fin = models.DateField(null=True, blank=True, verbose_name='Date de fin') editeur = models.CharField(db_index=True, max_length=450, blank=True) formation = models.CharField(db_index=True, max_length=300, blank=True) universite = models.CharField(db_index=True, max_length=300, blank=True, verbose_name='Université') discipline = models.CharField(db_index=True, max_length=300, blank=True) type_production = models.CharField(db_index=True, max_length=767, blank=True) type_rapport = models.CharField(db_index=True, max_length=767, blank=True) revue = models.ForeignKey(Revue, verbose_name= 'Nom de la revue attribuée', null=True, blank=True) tags = models.ManyToManyField(Tag) #auteurs = models.ManyToManyField(Auteur) auteurs = SortedManyToManyField(Auteur) categories = models.ManyToManyField(Categorie, verbose_name=u'Catégorie', null=True, blank=True) subcats = models.ManyToManyField(SousCategorie, verbose_name=u'Sous-Catégorie', null=True, blank=True) def __unicode__(self): return self.titre class Meta: ordering = ['annee', 'titre']
class Trip(models.Model): trip_name = models.CharField(max_length = 1000) pois = SortedManyToManyField(POI) #waypoint_id = models.IntegerField(default=0) def __unicode__(self): return self.trip_name
class AchievementTaskSet(models.Model): """ One Achievement is related to set of tasks. """ slug = models.SlugField( primary_key=True, help_text= "Must be unique among all achievement task sets, serves as part of URL.<br />" 'Must only contain characters "a-zA-Z0-9_-".', ) name = models.CharField(max_length=128) achievement = models.ForeignKey(Achievement, on_delete=models.CASCADE) tasks = SortedManyToManyField(Task) @receiver(post_save, sender=Review, weak=False) def handler(sender, **kwargs): review = kwargs["instance"] user = review.submit.user task = review.submit.receiver.task for achievementTaskSet in AchievementTaskSet.objects.filter( tasks__in=[task]): task_list = achievementTaskSet.tasks.all() if (Review.objects.order_by( "submit", "-time").distinct("submit").filter( score=100, submit__user=user, submit__receiver__task__in=task_list, ).values("submit__receiver__task").distinct().count() == len(task_list)): achievementTaskSet.achievement.users.add(user)
class JobListPlugin(BaseJobsPlugin): """ Store job list for JobListPlugin. """ jobopenings = SortedManyToManyField( JobOpening, blank=True, verbose_name=_('job openings'), help_text=_("Choose specific Job Openings to show or leave empty to " "show latest. Note that Job Openings from different " "app configs will not appear.")) def get_job_openings(self, namespace): """ Return the selected JobOpening for JobListPlugin. If no JobOpening are selected, return all active events for namespace and language, sorted by title. """ if self.jobopenings.exists(): return self.jobopenings.namespace(namespace).active() return (JobOpening.objects.namespace(namespace).language( self.language).active_translations(self.language).active()) def __str__(self): return force_text(self.pk) def copy_relations(self, oldinstance): self.app_config = oldinstance.app_config self.jobopenings = oldinstance.jobopenings.all()
class AchievementTaskSet(models.Model): """ One Achievement is related to set of tasks. """ slug = models.SlugField( primary_key=True, help_text= 'Must be unique among all achievement task sets, serves as part of URL.<br />' 'Must only contain characters "a-zA-Z0-9_-".') name = models.CharField(max_length=128) achievement = models.ForeignKey(Achievement, on_delete=models.CASCADE) tasks = SortedManyToManyField(Task) @receiver(post_save, sender=Review, weak=False) def handler(sender, **kwargs): review = kwargs['instance'] user = review.submit.user for achievementTaskSet in AchievementTaskSet.objects.all(): task_list = achievementTaskSet.tasks.all() solved_all = True for task in task_list: if not Review.objects.filter( submit__user=user, submit__receiver__in=task.submit_receivers.all(), score=100).exists(): solved_all = False if solved_all: achievement = Achievement.objects.get( slug=achievementTaskSet.slug) achievement.award_to(user)
class Contest(models.Model): ''' This class represents a contest. Every article, submission, team etc are in some way related to an instance of this class. Other than binding the other entities together it sets the start date for the contest, the end date, a registration end date, and a publish date. The penalty constant used to calculate team scores is also set in this model. ''' title = models.CharField(max_length=200) contact_infos = models.ManyToManyField('ContactInformation', null=True) """ The url is saved as the suffix from root, only, not the entire url """ penalty_constant = models.IntegerField('Penalty Constant', default=0) url = models.CharField( max_length=20, unique=True, help_text= 'Defines the url used to access the contest. E.g. sample.site.com/[the value inserted here]' ) start_date = models.DateTimeField(verbose_name='Start date') end_date = models.DateTimeField('End date') publish_date = models.DateTimeField('Publish date') teamreg_end_date = models.DateTimeField("Team registration close date") links = SortedManyToManyField('Link') sponsors = models.ManyToManyField('Sponsor', blank=True) css = FileBrowseField('CSS', max_length=200, directory='css/', extensions=[ '.css', ], blank=True, null=True) logo = FileBrowseField( 'Logo', max_length=200, directory='logo/', extensions=['.jpg', '.jpeg', '.png', '.gif'], blank=True, null=True, help_text='Select logo image, allowed formats jpg, jpeg, png, gif') def isPublishable(self): return self.publish_date.__lt__(getTodayDate()) def isRegOpen(self): return self.teamreg_end_date.__gt__(getTodayDate()) def clean(self): # TODO: which is better? To do clean here, or in form? # in model you can only invoke validationerror on _ALL_ fields, # not a single one if self.start_date is not None and self.end_date is not None: if self.start_date.__lt__(self.end_date) == False: raise ValidationError( 'You cannot set start date to be after the end date') def __str__(self): return self.title
class TaggedDoItYourselfShelf(models.Model): books = SortedManyToManyField( Book, sort_value_field_name='diy_sort_number', related_name='tagged_diy_shelves', through='TagThrough', through_fields=('shelf', 'book') )
class AdZone(models.Model): name = models.CharField(max_length=255) ad_units = SortedManyToManyField(AdUnit) objects = AdZoneManager() def __unicode__(self): return self.name
class Album(TimeStampedModel): user = models.ForeignKey(User, related_name='albums') name = models.CharField(max_length=255) place = models.ForeignKey('Place', related_name='tagged_in_albums', blank=True, null=True) photos = SortedManyToManyField('Photo')
class CorporateEndorsement(TimeStampedModel): corporation_name = models.CharField(max_length=128, blank=False, null=False) statement = models.TextField(blank=False, null=False) image = models.ForeignKey(Image, blank=True, null=True) individual_endorsements = SortedManyToManyField(Endorsement) def __str__(self): return self.corporation_name
class Question(models.Model): question_text = models.TextField(max_length=64000) title = models.CharField(max_length=200) choices = SortedManyToManyField('Choice', blank=True) input_field = models.CharField(max_length=200, blank=True) def __str__(self): return self.title
class FortuneCookie(BaseModel): """Fortune cookie: 29 cents; what a bargain!""" class Meta: ordering = ['fortune'] fortune = models.CharField( max_length=255, help_text=_('Confucious say...'), ) chinese_word = models.ForeignKey( 'ChineseWord', related_name='fortune_cookies', blank=True, null=True, default=None, on_delete=models.PROTECT, help_text=_('Learn Chinese.'), ) lucky_numbers = SortedManyToManyField( 'LuckyNumber', related_name='fortune_cookies', help_text=_('Lucky numbers.'), ) def __init__(self, *args, **kwargs): self._init_lucky_numbers = kwargs.pop('lucky_numbers', None) super(FortuneCookie, self).__init__(*args, **kwargs) def save(self, *args, **kwargs): # if isinstance(self.chinese_word, basestring): # self.chinese_word = \ # ChineseWord.objects.get_or_create(english_word=self.chinese_word) # elif isinstance(self.chinese_word, (tuple, list)) and \ # len(self.chinese_word): # d = dict(zip(['english_word', 'pinyin_word', 'chinese_word'], # self.chinese_word)) # self.chinese_word = ChineseWord.objects.get_or_create(**d) if not self.pk and self._init_lucky_numbers and \ isinstance(self._init_lucky_numbers, (list, tuple)): lucky_numbers = self._init_lucky_numbers else: lucky_numbers = [] super(FortuneCookie, self).save(*args, **kwargs) for number in lucky_numbers: ln = LuckyNumber.objects.get_or_create(number=int(number))[0] self.lucky_numbers.add(ln) def lucky_numbers_display(self): return u', '.join(map(six.text_type, self.lucky_numbers.all())) lucky_numbers_display.short_description = 'Lucky numbers' def __str__(self): if self.lucky_numbers.exists(): return u'{} ({})'.format(self.fortune, self.lucky_numbers_display()) else: return self.fortune
class TemplatesMixin(models.Model): """ Provides a mixins that adds a m2m relationship with the concrete Template model """ templates = SortedManyToManyField( 'django_netjsonconfig.Template', related_name='config_relations', verbose_name=_('templates'), blank=True, help_text=_('configuration templates, applied from' 'first to last')) def save(self, *args, **kwargs): created = self._state.adding super(TemplatesMixin, self).save(*args, **kwargs) if created: default = self.templates.model.objects.filter(default=True) if default: self.templates.add(*default) @classmethod def clean_templates(cls, action, instance, pk_set, **kwargs): """ validates resulting configuration of config + templates raises a ValidationError if invalid must be called from forms or APIs """ if action != 'pre_add': return # coming from signal if isinstance(pk_set, set): template_model = cls.templates.rel.model templates = template_model.objects.filter(pk__in=list(pk_set)) # coming from admin ModelForm else: templates = pk_set backend = instance.get_backend_instance(template_instances=templates) try: cls.clean_netjsonconfig_backend(backend) except ValidationError as e: message = 'There is a conflict with the specified templates. {0}' message = message.format(e.message) raise ValidationError(message) @classmethod def templates_changed(cls, action, instance, **kwargs): """ called from m2m_changed signal """ if action not in ['post_add', 'post_remove', 'post_clear']: return if instance.status != 'modified': instance.status = 'modified' instance.save() class Meta: abstract = True
class ParkingArea(models.Model): name = models.CharField(max_length=50) cars = SortedManyToManyField(Car, base_class=BaseCarThrough) def __str__(self): return self.name def get_absolute_url(self): return reverse('parkingarea', (self.pk, ))
class FeaturedPage(MetaModel, RelatableModel): name = models.CharField(max_length=100) slug = models.SlugField(unique=True) thumbnail = ImageUploaderField(upload_to=generate_image_path) generate_menu = models.BooleanField(default=True, verbose_name='Show Page Navigaiton') feature_category = SortedManyToManyField(ProductFeatureCategory, related_name='pages', blank=True) related_models = (('mantle', 'goalzero.mantle'), ('related_products', 'products.product'), ('blocks', 'sideadmin.block')) def get_absolute_url(self): return self.url() def __str__(self): return self.name def save(self, *args, **kwargs): if not self.slug: self.slug = slugify(self.name) super(FeaturedPage, self).save(*args, **kwargs) def get_menu_items(self): if not self.generate_menu: return [] menu_items = [{ 'url': '#{}'.format(block.anchor), 'name': block.menu_name } for block in self.related("blocks") if getattr(block, 'anchor', False)] if self.related('related_products'): menu_items.append({'url': "#buy", 'name': 'Buy'}) return menu_items @property def image_path(self): return 'featured_page/{}'.format(self.id) @property def content_type_id(self): return ContentType.objects.get( model=self.__class__.__name__.lower()).id def meta_description(self): return self.meta('page_description') or self.html() def meta_title(self): return self.meta('page_title') or self.name def url(self): return reverse('product_features', args=[self.slug])
class ImageROI(models.Model): data = JSONField(default=dict, blank=True) # @@@ denormed from data; could go away when Django's SQLite backend has proper # JSON support image_identifier = models.CharField(max_length=255) # @@@ this could be structured coordinates_value = models.CharField(max_length=255) # @@@ idx image_annotation = models.ForeignKey( "scaife_viewer_atlas.ImageAnnotation", related_name="roi", on_delete=models.CASCADE, ) text_parts = SortedManyToManyField("scaife_viewer_atlas.Node", related_name="roi") text_annotations = SortedManyToManyField( "scaife_viewer_atlas.TextAnnotation", related_name="roi" )
class ParkingArea(models.Model): name = models.CharField(max_length=50) cars = SortedManyToManyField(Car) def __unicode__(self): return self.name @models.permalink def get_absolute_url(self): return 'parkingarea', (self.pk, ), {}
class Metadata(models.Model): idx = models.IntegerField(help_text="0-based index", blank=True, null=True) urn = models.CharField( # TODO: Can we encode the collection into the URN too? max_length=255, unique=True, help_text="urn:cite2:<site>:metadata.atlas_v1", ) collection_urn = models.CharField( max_length=255, help_text="urn:cite2:<site>:metadata_collection.atlas_v1" ) datatype = models.CharField( # TODO: Object vs CITEObj, etc choices=[ ("str", "String"), ("int", "Integer"), ("date", "Date"), ("obj", "Object"), ("cite_urn", "CITE URN"), ], max_length=8, default="str", ) label = models.CharField(max_length=255) value = models.CharField(blank=True, null=True, max_length=255) value_obj = JSONField(default=dict, blank=True) index = models.BooleanField(default=True, help_text="Include in search index") visibility = models.CharField( choices=METADATA_VISIBLITY_CHOICES, max_length=7, default=METADATA_VISIBILITY_ALL, ) level = models.CharField( choices=[ ("text_group", "Text Group"), ("work", "Work"), ("version", "Version"), ("passage", "Passage"), ], max_length=11, default="version", help_text="Human-readable representation of the level of URN(s) to which metadata is attached", ) # TODO: Decouple level and depth, but likely refactoring depth depth = models.PositiveIntegerField() cts_relations = SortedManyToManyField( "scaife_viewer_atlas.Node", related_name="metadata_records" ) def __str__(self): return f"{self.label}: {self.value}"