class EmailTask(models.Model): # Object being used to generate this email object_id = models.PositiveIntegerField() object_model = models.ForeignKey(ContentType, related_name='email_model') act_on = GenericForeignKey('object_model', 'object_id') # Event type of this email event_id = models.PositiveIntegerField() event_model = models.ForeignKey(ContentType, related_name='email_type') related_event = GenericForeignKey('event_model', 'event_id') completed_on = models.DateTimeField(blank=True, null=True) scheduled_for = models.DateTimeField(default=datetime.now) scheduled_at = models.DateTimeField(auto_now_add=True) task_id = models.CharField(max_length=36, blank=True, default='', help_text='guid with dashes') @property def completed(self): return bool(self.completed_on) def schedule(self): """ Submits this task to Celery for processing. """ tasks.send_event_email.apply_async(args=[self], eta=self.scheduled_for) def send_email(self): self.related_event.send_email(self.act_on)
class Follow(models.Model): # generic foreign key allows relation to either user types follower_content_type = models.ForeignKey( ContentType, related_name='follower_content_type') follower_object_id = models.PositiveIntegerField() follower = GenericForeignKey('follower_content_type', 'follower_object_id') followee_content_type = models.ForeignKey(ContentType) followee_object_id = models.PositiveIntegerField() followee = GenericForeignKey('followee_content_type', 'followee_object_id') # connect the manager objects = FollowManager() def save(self, *args, **kwargs): if self.follower_content_type == self.followee_content_type and self.follower_object_id == self.followee_object_id: raise ValidationError( "Follower and Followee must be different people") super(Follow, self).save(*args, **kwargs) class Meta: unique_together = ('follower_content_type', 'follower_object_id', 'followee_content_type', 'followee_object_id') app_label = 'Users'
class VersionMixin(models.Model): _manipulator = None action_id = PositiveIntegerField(null=True) # action definition action_name = CharField(max_length=16, null=True) manipulator_id = VersionManipulatorIdField(max_length=255) revert_data = jsonfield.JSONField( help_text="The serialized form of this version of the model.") # serialized object representation revert_fields = jsonfield.JSONField( help_text="The serialized form of affected model fields.") versioned_type = models.ForeignKey(ContentType, related_name='version_versioned') versioned_id = PositiveIntegerField() # versioned object relation versioned = GenericForeignKey('versioned_type', 'versioned_id') versioned_related_type = models.ForeignKey( ContentType, related_name='version_versioned_related', null=True) # versioned_related object relation versioned_related_id = PositiveIntegerField(null=True) versioned_related = GenericForeignKey('versioned_related_type', 'versioned_related_id') created_at = models.DateTimeField(auto_now_add=True) # timestamp and created_by updated_at = models.DateTimeField(auto_now=True) created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=PROTECT, null=True) class Meta: abstract = True def get_manipulator(self): if not self._manipulator: from libs.version.manipulator import factory_manipulator self._manipulator = factory_manipulator(self, self.manipulator_id) return self._manipulator def __unicode__(self): return 'Version({}):{}:{}'.format(self.id, self.action_name, self.action_code)
class Transaction(MoneyBase): """ Transaction(no more words) """ user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_("User")) actor_ctype = models.ForeignKey(ContentType, verbose_name=_("Object Content Type"), null=True, blank=True, related_name='transaction_object', on_delete=models.SET_NULL) actor_oid = models.CharField(max_length=255, verbose_name=_("ID of object"), blank=True) actor = GenericForeignKey('actor_ctype', 'actor_oid') date = models.DateTimeField(verbose_name=_("Date"), default=now) status = models.IntegerField(_("Transaction status"), choices=TRANSACTION_STATUS, default=TRANSACTION_UNKNOWN) target_ctype = models.ForeignKey(ContentType, verbose_name=_("Target Content Type"), null=True, blank=True, related_name='transaction_target', on_delete=models.SET_NULL) target_oid = models.CharField(max_length=255, verbose_name=_("ID of target"), blank=True) target = GenericForeignKey('target_ctype', 'target_oid') objects = FinancialManager() class Meta: unique_together = ('user', 'actor_ctype', 'actor_oid', 'date', 'amount', 'currency') verbose_name = _("Transaction") verbose_name_plural = _("Transactions") # def __unicode__(self): # return '%s -> %s' % (self.user, self.date) def __str__(self): return _("User: %(user)s :: Date: %(date)s :: Object: %(actor)s :: Amount: %(amount)s %(currency)s") %\ { 'user': self.user.username, 'date': self.date, 'actor': self.actor, 'amount': self.amount, 'currency': self.currency}
class Instance(AbstractInstance): """Normal Instance implementation for Tasks.""" class Meta: app_label = 'core' db_table = 'norc_instance' objects = QuerySetManager() # The object that spawned this instance. task_type = ForeignKey(ContentType, related_name='instances') task_id = PositiveIntegerField() task = GenericForeignKey('task_type', 'task_id') # The schedule from whence this instance spawned. schedule_type = ForeignKey(ContentType, null=True) schedule_id = PositiveIntegerField(null=True) schedule = GenericForeignKey('schedule_type', 'schedule_id') def run(self): return self.task.start(self) @property def timeout(self): return self.task.timeout @property def source(self): return self.task.get_name() @property def log_path(self): return 'tasks/%s/%s/%s-%s' % (self.task.__class__.__name__, self.task.get_name(), self.task.get_name(), self.id) def get_revision(self): """ Hook to provide revision tracking functionality. Redirects to Task.get_revision() for ease with normal task/instance setups. Other instances implementations might need to customize. """ return self.task.get_revision() def __unicode__(self): return u'[Instance #%s of %s]' % (self.id, str(self.task)[1:-1]) __repr__ = __unicode__
class TaggedItem(models.Model): """ Holds the relationship between a tag and the item being tagged. """ tag = models.ForeignKey(Tag, verbose_name=_('tag'), related_name='items', on_delete=models.CASCADE) content_type = models.ForeignKey(ContentType, verbose_name=_('content type'), on_delete=models.CASCADE) if getattr(settings, 'TAGGING_OBJECT_ID_TYPE', "") == "uuid": object_id = models.UUIDField(_('object id'), db_index=True) else: object_id = models.PositiveIntegerField(_('object id'), db_index=True) object = GenericForeignKey('content_type', 'object_id') objects = TaggedItemManager() class Meta: # Enforce unique tag association per object unique_together = (('tag', 'content_type', 'object_id'), ) verbose_name = _('tagged item') verbose_name_plural = _('tagged items') def __unicode__(self): return u'%s [%s]' % (self.object, self.tag)
class Comment(models.Model): content = models.TextField(max_length=600, null=False, verbose_name=_("content")) author = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_("author")) vote_count = models.IntegerField(default=0) comment_votes = GenericRelation("Vote") created = models.DateTimeField(verbose_name=_("created time")) last_modified = models.DateTimeField() ## enable generic foreign key relationship with other classes, such as Page, MainPost, ReplyPost. content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() content_object = GenericForeignKey('content_type', 'object_id') def __unicode__(self): return self.content[:25] def save(self, *args, **kwargs): ''' On save, update timestamps ''' if not self.created: self.created = timezone.now() self.last_modified = timezone.now() return super(Comment, self).save(*args, **kwargs) def get_vote_count(self): return self.comment_votes.filter( choice=1).count() - self.comment_votes.filter(choice=-1).count() class Meta: get_latest_by = "-last_modified"
class Comment(TimeStampedModel): text = models.CharField(_('comment'), max_length=1600) author = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_('author')) ip = models.GenericIPAddressField(_("author's IP address"), null=True) complaint = models.BooleanField(_('complaint'), default=False) rejected = models.BooleanField(_('rejected'), default=False) content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() content_object = GenericForeignKey('content_type', 'object_id') def get_absolute_url(self): return '{url}#{anchor}'.format( url=self.content_object.get_absolute_url(), anchor=self.anchor, ) @cached_property def anchor(self): return 'comment{}'.format(self.pk) def __str__(self): return 'Comment #{c.id} by {c.author.username}'.format(c=self) class Meta: verbose_name = _('comment') verbose_name_plural = _('comments') ordering = '-created',
class Event(models.Model): type = models.ForeignKey(EventType) user = models.ForeignKey(User, related_name='events') date = models.DateTimeField(auto_now_add=True) target_type = models.ForeignKey(ContentType, verbose_name=_('target type'), related_name="%(class)s") target_pk = models.TextField(_('target ID')) target_object = GenericForeignKey(ct_field="target_type", fk_field="target_pk") extra_data = JSONField(null=True, blank=True) details = models.TextField(max_length=500) site = models.ForeignKey(Site, null=True) objects = models.Manager() on_site = CurrentSiteManager() class Meta: app_label = 'notifications' def __unicode__(self): return self.details def get_related_obj_by_role_name(self, role_name): try: role = EventObjectRole.objects.get(name=role_name) related_objects = self.eventobjectrolerelation_set.filter(role=role) if len(related_objects): return related_objects[0].target_object return None except EventObjectRole.DoesNotExist: return None
class NotificationPreferences(models.Model): user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="notifications") event_type = models.CharField(max_length=32, blank=False, null=False) content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() content_object = GenericForeignKey('content_type', 'object_id') is_active = models.BooleanField(default=True) class Meta: unique_together = ("user", "event_type", "content_type", "object_id") @staticmethod def on_save_application(sender, instance, created, **kwargs): if created: content_type = ContentType.objects.get_for_model(type(instance)) groups = instance.department.groups.filter( system_name__isnull=False) user_model = get_user_model() for user in user_model.objects.filter(groups__in=groups): NotificationPreferences(user=user, event_type='ExecutionFinish', content_type=content_type, object_id=instance.id, is_active=True).save()
class Rating(models.Model): """ A rating that can be given to a piece of content. """ value = models.IntegerField(_("Value")) rating_date = models.DateTimeField(_("Rating date"), auto_now_add=True, null=True) content_type = models.ForeignKey("contenttypes.ContentType") object_pk = models.IntegerField() content_object = GenericForeignKey("content_type", "object_pk") user = models.ForeignKey(get_user_model_name(), verbose_name=_("Rater"), null=True, related_name="%(class)ss") class Meta: verbose_name = _("Rating") verbose_name_plural = _("Ratings") def save(self, *args, **kwargs): """ Validate that the rating falls between the min and max values. """ valid = map(str, settings.RATINGS_RANGE) if str(self.value) not in valid: raise ValueError("Invalid rating. %s is not in %s" % (self.value, ", ".join(valid))) super(Rating, self).save(*args, **kwargs)
class GenericTaggedItemBase(ItemBase): object_id = models.IntegerField(verbose_name=_('object'), db_index=True) content_type = models.ForeignKey( ContentType, verbose_name=_('content type'), related_name="%(app_label)s_%(class)s_tagged_items") content_object = GenericForeignKey() class Meta: abstract = True @classmethod def lookup_kwargs(cls, instance): return { 'object_id': instance.pk, 'content_type': ContentType.objects.get_for_model(instance) } @classmethod def bulk_lookup_kwargs(cls, instances): # TODO: instances[0], can we assume there are instances. return { "object_id__in": [instance.pk for instance in instances], "content_type": ContentType.objects.get_for_model(instances[0]), } @classmethod def tags_for(cls, model, instance=None): ct = ContentType.objects.get_for_model(model) kwargs = {"%s__content_type" % cls.tag_relname(): ct} if instance is not None: kwargs["%s__object_id" % cls.tag_relname()] = instance.pk return cls.tag_model().objects.filter(**kwargs).distinct()
class GroupObjectRoleMapping(models.Model): """ represents assignment of a role to a group in the context of a specific object. """ if "geonode.contrib.groups" in settings.INSTALLED_APPS: group = models.ForeignKey(Group, related_name="role_mappings") object_ct = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() object = GenericForeignKey('object_ct', 'object_id') role = models.ForeignKey(ObjectRole, related_name="group_mappings") def __unicode__(self): return u"%s | %s -> %s" % ( unicode(self.object), unicode(self.group), unicode(self.role)) class Meta: unique_together = (('group', 'object_ct', 'object_id', 'role'), ) else: pass
class QuestionTakes(models.Model): sit = models.ForeignKey(Sitting, verbose_name=_('Sitting')) question_take_time = models.DateTimeField( verbose_name=_("Question take time"), auto_now_add=True, null=True) content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() content_object = GenericForeignKey('content_type', 'object_id') def __str__(self): return str(self.content_object) + str(self.question_take_time) def get_left_time(self, question): left_time = (self.question_take_time + timedelta( seconds=question.seconds_to_answer)) - datetime.now() return int( left_time.total_seconds()) if left_time.total_seconds() >= 0 else 0 @staticmethod def take(sit, question): test_take = QuestionTakes.objects.filter( sit=sit, object_id=question.id, content_type__pk=ContentType.objects.get_for_model(question).id) if test_take.count() == 0: qt = QuestionTakes(sit=sit, content_object=question) qt.save() return qt else: return test_take[0] class Meta: verbose_name = _('question take') verbose_name_plural = _('question takes')
class Certification(models.Model): certifier = models.ForeignKey(User) object_ct = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() object = GenericForeignKey('object_ct', 'object_id') objects = CertificationManager()
class Report(MapEntityMixin, PicturesMixin, TimeStampedModelMixin): """ User reports, mainly submitted via *Geotrek-rando*. """ name = models.CharField(verbose_name=_(u"Name"), max_length=256) email = models.EmailField(verbose_name=_(u"Email")) comment = models.TextField(blank=True, default="", verbose_name=_(u"Comment")) category = models.ForeignKey('ReportCategory', null=True, blank=True, default=None, verbose_name=_(u"Category")) status = models.ForeignKey('ReportStatus', null=True, blank=True, default=None, verbose_name=_(u"Status")) geom = gis_models.PointField(null=True, blank=True, default=None, verbose_name=_(u"Location"), srid=settings.SRID) context_content_type = models.ForeignKey(ContentType, null=True, blank=True, editable=False) context_object_id = models.PositiveIntegerField(null=True, blank=True, editable=False) context_object = GenericForeignKey('context_content_type', 'context_object_id') objects = gis_models.GeoManager() class Meta: db_table = 'f_t_signalement' verbose_name = _(u"Report") verbose_name_plural = _(u"Reports") ordering = ['-date_insert'] def __unicode__(self): return self.name @property def name_display(self): return u'<a data-pk="%s" href="%s" title="%s" >%s</a>' % ( self.pk, self.get_detail_url(), self, self) @classmethod def get_create_label(cls): return _(u"Add a new feedback") @property def geom_wgs84(self): return self.geom.transform(4326, clone=True) @property def comment_text(self): return HTMLParser.unescape.__func__(HTMLParser, self.comment)
class Document(models.Model): '''-- Document Model is used to manage files in our project. :Fields: | **file_upload** -- FileField object to store files. | **created** -- Record created time. | **content_type** -- File content types. | **accessURL** -- The url link to files and is created when file is saved. ''' # file objects file_upload = models.FileField(upload_to='documents', null=True, blank=True) created = models.DateTimeField(auto_now_add=True, null=True) content_type = models.ForeignKey(ContentType, null=True, blank=True) object_id = models.PositiveIntegerField(null=True, blank=True) content_object = GenericForeignKey('content_type', 'object_id') # The url link to this file accessURL = models.URLField(max_length=200, blank=True, null=True) def get_absolute_url(self): ''' :returns: Absolute URL of Document. ''' return self.file_upload.url def __unicode__(self): return os.path.basename(self.file_upload.name) def save(self, *args, **kwargs): ''' The *file_upload* field has to be saved before saving its URL to *accessURL* ''' super(Document, self).save(*args, **kwargs) self.accessURL = self.file_upload.url super(Document, self).save(*args, **kwargs)
class BaseGenericObjectPermission(models.Model): content_type = models.ForeignKey(ContentType) object_pk = models.CharField(_('object ID'), max_length=255) content_object = GenericForeignKey(fk_field='object_pk') class Meta: abstract = True
class StateLog(models.Model): timestamp = models.DateTimeField(default=now) by = models.ForeignKey(getattr(settings, 'AUTH_USER_MODEL', 'auth.User'), blank=True, null=True) state = models.CharField(max_length=255, db_index=True) transition = models.CharField(max_length=255) content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField(db_index=True) content_object = GenericForeignKey('content_type', 'object_id') objects = StateLogManager() class Meta: get_latest_by = 'timestamp' def __str__(self): return '{} - {} - {}'.format( self.timestamp, self.content_object, self.transition ) def get_state_display(self): fsm_obj = self.content_object for field in fsm_obj._meta.fields: if isinstance(field, FSMFieldMixin): state_display = dict(field.flatchoices).get(self.state, self.state) return force_text(state_display, strings_only=True)
class StoredOEmbed(models.Model): match = models.TextField() response_json = models.TextField() resource_type = models.CharField(choices=RESOURCE_CHOICES, editable=False, max_length=8) date_added = models.DateTimeField(auto_now_add=True) date_expires = models.DateTimeField(blank=True, null=True) maxwidth = models.IntegerField(blank=True, null=True) maxheight = models.IntegerField(blank=True, null=True) # generic bits object_id = models.IntegerField(blank=True, null=True) content_type = models.ForeignKey(ContentType, blank=True, null=True, related_name="related_%(class)s") content_object = GenericForeignKey() class Meta: ordering = ('-date_added', ) verbose_name = 'stored OEmbed' verbose_name_plural = 'stored OEmbeds' if 'mysql' not in db_engine: unique_together = ('match', 'maxwidth', 'maxheight') def __unicode__(self): return self.match @property def response(self): return simplejson.loads(self.response_json)
class Vote(models.Model): VOTE_UP = 1 VOTE_DOWN = -1 VOTE_NONE = 0 voter = models.ForeignKey(Voter) client_identifier = models.ForeignKey(ClientIdentifier) content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() content_object = GenericForeignKey() created = models.DateTimeField(auto_now_add=True) choice = models.SmallIntegerField() objects = VoteQuerySet.as_manager() @classmethod def votes_for(cls, model, instance=None): ct = ContentType.objects.get_for_model(model) kwargs = {"content_type": ct} if instance is not None: kwargs["object_id"] = instance.pk return cls.objects.filter(**kwargs) class Meta: unique_together = ('voter', 'content_type', 'object_id')
class History(models.Model): date = models.DateTimeField(verbose_name=_('date'), default=datetime.now) user = models.ForeignKey('auth.User', verbose_name=_('user'), null=True, blank=True, default=None, on_delete=models.SET_NULL) content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() content_object = GenericForeignKey('content_type', 'object_id') field_name = models.CharField(max_length=64, default='') old_value = models.TextField(default='') new_value = models.TextField(default='') objects = HistoryManager() class Meta: app_label = 'ralph_assets' verbose_name = _('history change') verbose_name_plural = _('history changes') ordering = ('-date', ) def __unicode__(self): return 'in {} (id: {}) change {}: {} -> {}'.format( self.content_type, self.object_id, self.field_name, self.old_value, self.new_value) @classmethod def get_history_url_for_object(cls, obj): content_type = ContentType.objects.get_for_model(obj.__class__) return reverse('history_for_model', kwargs={ 'content_type': content_type.id, 'object_id': obj.id, })
class Staff(models.Model): first_name = models.CharField(max_length=255, help_text=_("Enter the name of the staff being rounded")) last_name = models.CharField(max_length=255, help_text=_("Enter the name of the staff being rounded")) active = models.CharField(max_length=10, choices=ACTIVE_CHOICES) is_manager = models.BooleanField(default=False) position = models.ForeignKey(Position) department = models.ForeignKey(Department) contract_type = models.ForeignKey(ContractType) date_hired = models.DateTimeField(default=add_a_datetime) last_incident = models.DateField(default=add_a_date) limit = models.Q(app_label='staff', model='genericmodela') | models.Q(app_label='staff', model='genericmodelb') content_type = models.ForeignKey(ContentType, limit_choices_to=limit) object_id = models.PositiveIntegerField() generic_object = GenericForeignKey("content_type", "object_id") class Meta: verbose_name_plural = "staff" ordering = ("last_name", "first_name",) def name(self): return "%s, %s" % (self.last_name, self.first_name) def status(self): return ACTIVE_CHOICES_DISPLAY[self.active] def __unicode__(self): return self.name()
class MaterialMovement(models.Model): TYPE_CHOICES = (('E', _(u'Input')), ('S', _(u'Output'))) material_cluster = models.ForeignKey(MaterialCluster, verbose_name=_(u'Material cluster')) type = models.CharField(_(u'Type'), max_length=1, choices=TYPE_CHOICES) qty_before_mov = models.IntegerField(_(u'Quantity before movement')) quantity = models.IntegerField(_(u'Movemented quantity')) mov_date = models.DateField(_(u'Movement date'), auto_now_add=True) unit_cost = models.DecimalField(_(u'Unit cost'), max_digits=20, decimal_places=2) origin = GenericForeignKey() content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() @property def total_cost(self): return self.quantity * self.unit_cost class Meta: ordering = ('-mov_date', ) verbose_name = _(u'Material movement registry') verbose_name_plural = _('Material movements registry') def __unicode__(self): return _( u"%(type)s %(quantity)s units of %(material)s at %(date)s") % { 'type': self.get_type_display(), 'quantity': self.quantity, 'material': self.material_cluster.material.description, 'date': self.mov_date }
class Permittee(models.Model): """ Links permissions to their owners using the C{contenttypes} framework, where permittees are not necessarily C{django.contrib.auth.models.User} instances. @cvar objects: L{PermitteeManager} for the class @ivar object_type: The C{ContentType} indicating the class of the permittee. @type object_type: ForeignKey to C{ContentType} @ivar object_id: The id of the permittee. @type object_id: positive C{int} @ivar object: the object for this permittee. @type object: varies """ objects = PermitteeManager("object_type", "object_id") object_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() object = GenericForeignKey("object_type", "object_id") def __unicode__(self): return u"%s" % self.object class Meta: unique_together=(("object_type", "object_id"),)
class Metadata(models.Model): '''Metadata assoicated with a site, a device, or a sensor''' content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() content_object = GenericForeignKey('content_type', 'object_id') key = models.CharField(max_length=255) value = models.TextField(blank=True) timestamp = models.DateTimeField(default=timezone.now, blank=True)
class SimilarItem(models.Model): content_type = models.ForeignKey(ContentType, related_name='similar_items') object_id = models.IntegerField() content_object = GenericForeignKey('content_type', 'object_id') similar_content_type = models.ForeignKey(ContentType, related_name='similar_items_set') similar_object_id = models.IntegerField() similar_object = GenericForeignKey('similar_content_type', 'similar_object_id') score = models.FloatField(default=0) objects = SimilarItemManager() def __unicode__(self): return u'%s (%s)' % (self.similar_object, self.score)
class ImageAttachment(models.Model): image = models.ImageField(upload_to=generate_image_path) date = models.DateTimeField(auto_now=True) uploader = models.ForeignKey(settings.AUTH_USER_MODEL) # object that owns this image. content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() content_object = GenericForeignKey('content_type', 'object_id')
class Tag(models.Model): name = models.CharField(max_length=255) content_type = models.ForeignKey(ContentType, null=True, on_delete=models.CASCADE) object_id = models.PositiveIntegerField(null=True) content_object = GenericForeignKey('content_type', 'object_id') def __unicode__(self): return self.name
class TaggedItem(RESTFrameworkModel): tag = models.ForeignKey(Tag, related_name='items') content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() content_object = GenericForeignKey('content_type', 'object_id') def __unicode__(self): return self.tag.tag_name