class App(AppApi, BaseModel): """ This model stores all of the relevant WePay application information. Only one instance of it at a time is supported per django application, which is controlled by :ref:`WEPAY_APP_ID` setting. """ # fields returned with a lookup call client_id = models.BigIntegerField(primary_key=True) status = models.CharField(max_length=255) state = models.CharField(max_length=255) api_version = models.CharField(max_length=255) theme_object = JSONField(null=True, blank=True) gaq_domains = JSONField(null=True, blank=True) # Administrative objects attached to account, they are null=True just # for initialization of the App, but are required for proper functionality. account = models.ForeignKey( get_wepay_model_name('account'), related_name='apps', null=True, help_text="Account attached to App where you can collect money.") user = models.ForeignKey(get_wepay_model_name('user'), related_name='apps', null=True, help_text="Owner of this App") client_secret = models.CharField(max_length=255) objects = AppManager() class Meta(BaseModel.Meta): abstract = is_abstract('app') db_table = 'djwepay_app' verbose_name = 'WePay App'
class App(AppApi, BaseModel): """ This model stores all of the relevant WePay application information. Only one instance of it at a time is supported per django application, which is controlled by :ref:`WEPAY_APP_ID` setting. """ client_id = models.BigIntegerField(primary_key=True) status = models.CharField(max_length=255) theme_object = JSONField(null=True, blank=True) gaq_domains = JSONField(null=True, blank=True) client_secret = models.CharField(max_length=255) access_token = models.CharField(max_length=255) production = models.BooleanField(default=True) state = models.CharField(max_length=255) api_version = models.CharField(max_length=255) account = models.ForeignKey( get_wepay_model_name('account'), related_name='apps', null=True, blank=True) objects = AppManager() class Meta(BaseModel.Meta): abstract = is_abstract('app') db_table = 'djwepay_app' verbose_name = 'WePay App'
class UserProfile(models.Model): user = models.OneToOneField(User) array = JSONField() arrayratedmoviesindxs = JSONField() name = models.CharField(max_length=1000) lastrecs = JSONField() def __str__(self): return self.name def save(self, *args, **kwargs): create = kwargs.pop('create', None) recsvec = kwargs.pop('recsvec', None) print('create:', create) if create: super(UserProfile, self).save(*args, **kwargs) elif not recsvec: self.lastrecs = json.dumps(recsvec.tolist()) super(UserProfile, self).save(*args, **kwargs) else: nmovies = MovieData.objects.count() array = np.zeros(nmovies) ratedmovies = self.ratedmovies.all() self.arrayratedmoviesindxs = json.dumps( [m.movieindx for m in ratedmovies]) for m in ratedmovies: array[m.movieindx] = m.value self.array = json.dumps(array.tolist()) super(UserProfile, self).save(*args, **kwargs)
class CouncilorsDetail(models.Model): councilor = models.ForeignKey(Councilors, to_field="uid", related_name='each_terms') election_year = models.CharField(db_index=True, max_length=100) name = models.CharField(max_length=100) gender = models.CharField(max_length=100, blank=True, null=True) party = models.CharField(db_index=True, max_length=100, blank=True, null=True) title = models.CharField(max_length=100, blank=True, null=True) constituency = models.CharField(db_index=True, max_length=100, blank=True, null=True) county = models.CharField(db_index=True, max_length=100) district = models.CharField(db_index=True, max_length=100, blank=True, null=True) in_office = models.BooleanField(db_index=True) contact_details = JSONField(null=True) term_start = models.DateField(blank=True, null=True) term_end = JSONField(null=True) education = models.TextField(blank=True, null=True) experience = models.TextField(blank=True, null=True) remark = models.TextField(blank=True, null=True) image = models.URLField(blank=True, null=True) links = JSONField(null=True) social_media = JSONField(null=True) platform = models.TextField(blank=True, null=True) param = JSONField(null=True) def __unicode__(self): return self.name def _in_office_year(self): return CouncilorsDetail.objects.filter(councilor_id=self.councilor_id).values_list('election_year', flat=True).order_by('-election_year') in_office_year = property(_in_office_year)
class Problem(models.Model): created = CreationDateTimeField() modified = ModificationDateTimeField() author = models.ForeignKey(User, null=True) problem_title = models.CharField(_('Problem title'), max_length=255, null=True, blank=True, help_text=_('Unique verbose name of this problem')) problem_description = models.TextField(_('Description'), null=True, blank=True, help_text=_('Problem description')) input_params = JSONField(_('Input parameters'), null=True, blank=True, default='[]', help_text=_('Parameters for each experiment task. Ranges available, e.g. 1..10. Nesting available.')) result_display_params = JSONField(_('Result display discribing parameters'), null=True, blank=True, default='[]',) problem_parent = models.ForeignKey('self', null=True, blank=True, related_name='children') def __str__(self): return str(self.problem_title) def dublicate(self): return Problem.objects.create( problem_title=self.problem_title, problem_description=self.problem_description, input_params=self.input_params, result_display_params=self.result_display_params, problem_parent=self.problem_parent, )
class Candidates(models.Model): councilor = models.ForeignKey('councilors.Councilors', to_field='uid', blank=True, null=True) last_election_year = models.CharField(db_index=True, max_length=100, blank=True, null=True) election_year = models.CharField(db_index=True, max_length=100) name = models.CharField(max_length=100) birth = models.DateField(blank=True, null=True) gender = models.CharField(max_length=100, blank=True, null=True) party = models.CharField(db_index=True, max_length=100, blank=True, null=True) title = models.CharField(max_length=100, blank=True, null=True) constituency = models.IntegerField(db_index=True) county = models.CharField(db_index=True, max_length=100) district = models.CharField(db_index=True, max_length=100, blank=True, null=True) votes = models.IntegerField(blank=True, null=True) elected = models.NullBooleanField(db_index=True) contact_details = JSONField(null=True) education = models.TextField(blank=True, null=True) experience = models.TextField(blank=True, null=True) remark = models.TextField(blank=True, null=True) image = models.URLField(blank=True, null=True) links = JSONField(null=True) platform = models.TextField(blank=True, null=True) def __unicode__(self): return self.name def _not_vote_percentage(self): try: councilor = CouncilorsDetail.objects.get( councilor_id=self.councilor_id, election_year=self.last_election_year) if councilor.title == u'議長': return u'議長不參加表決' except Exception, e: return '' all_vote = Councilors_Votes.objects.filter(councilor_id=councilor.id) if all_vote: not_vote = all_vote.filter(decision__isnull=True).count() should_vote = all_vote.count() return u'%d / %d(%.1f %%)' % (not_vote, should_vote, not_vote * 100.0 / should_vote) return ''
class Question(models.Model): name = models.CharField(max_length=80) text = models.TextField(blank=True) qtype = models.CharField(max_length=1, choices=QUESTION_TYPES) choices = JSONField( blank=True, default= '["choice/label1", "choice/label2", "choice/label3", "choice/label4"]') value_map = JSONField(blank=True, default='[-3, 3]') user = models.ForeignKey(User, default=None, null=True) def __unicode__(self): return self.name
class Variant(models.Model): PAIR_TYPE_CHOICES = ( ('question', _(u'вопрос')), ('answer', _(u'ответ')) ) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) text = models.TextField(_(u'текст ответа'), null=True, blank=True) pair = models.ForeignKey('self', null=True, blank=True, verbose_name=_(u'пара')) pair_type = models.CharField(_(u'тип пары'), max_length=10, default='question', choices=PAIR_TYPE_CHOICES) right_answer = models.BooleanField(default=False) page = models.ForeignKey(Page, related_name="variants") number = models.IntegerField(_(u'Порядок'), default=1) is_correct = models.BooleanField(_(u'правильность заполнения вопроса'), default=True) code_errors = JSONField(_(u'коды ошибок'), default={}, blank=True, null=True) reflexy = models.TextField(_(u'текст рефлексии'), null=True, blank=True) def __unicode__(self): if self.text: return self.text return u"Ответ на вопрос с id %s" % self.id class Meta: verbose_name = _(u'Ответ') verbose_name_plural = _(u'Ответы') ordering = ('number', 'created_at', 'text', )
class Job(models.Model): """Job information""" STATUS_OK = 0 STATUS_FAILED = 1 ci_id = models.CharField(max_length=16, blank=False, help_text='Jenkins job ID') ci_name = models.CharField(max_length=32, blank=False, help_text='Name of the Jenkins project,' 'e.g. validate_drp') ci_dataset = models.CharField(max_length=16, blank=False, help_text='Name of the dataset, e.g cfht') ci_label = models.CharField(max_length=16, blank=False, help_text='Name of the platform, eg. centos-7') date = models.DateTimeField(auto_now_add=True, help_text='Datetime when job was registered') ci_url = models.URLField(null=False, help_text='Jenkins job URL') status = models.SmallIntegerField(default=STATUS_OK, help_text='Job status, 0=OK, 1=Failed') blobs = JSONField(null=True, blank=True, default=None, help_text='Data blobs produced by the job.', decoder=None) def __str__(self): return self.ci_id
class Statistic(models.Model): project = models.ForeignKey(Project, verbose_name=_("Project"), related_name="statistics") day = models.DateField(_("Day"), default=timezone.now) data = JSONField(_("Data")) class Meta: ordering = ("-day",) @property def js_date(self): return calendar.timegm(self.day.timetuple()) * 1000 def __unicode__(self): return "<Statistic - {0}>".format(self.day) def time_series(self, t): stack = t.split(".") def get_it(pos, current): v = current.get(stack[pos], None) if v and pos < len(stack)-1: return get_it(pos+1, v) else: if v: return v else: return 0 return [self.js_date, get_it(0, self.data)] def same_data(self, other): if other: return other.data == self.data return False
class Configuration(models.Model): """Configuration information""" configuration = JSONField(decoder=None, help_text='Configuration used.') creation_date = models.DateTimeField( auto_now=True, help_text='Datetime when the configuration was created') process = models.ForeignKey(Process, related_name='configuration_process')
class MovieData(models.Model): title = models.CharField(max_length=100) array = JSONField() ndim = models.IntegerField(default=300) description = models.TextField() def __str__(self): return self.title
class PZoneHistory(models.Model): pzone = models.ForeignKey(PZone, related_name="history") data = JSONField(default=[]) date = models.DateTimeField(auto_now_add=True) class Meta: # we want the most recently created to come out first ordering = ["-date"]
class Thing(models.Model): key = models.CharField(max_length=512) value = JSONField() content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() content_object = generic.GenericForeignKey('content_type', 'object_id') created = models.DateTimeField(default=datetime.datetime.now) modified = models.DateTimeField(auto_now=True) @classmethod def has_key(klass, key, object_id=None, content_object=None): qs = klass.objects.filter(key=key) if object_id: qs = qs.objects.filter(object_id=object_id) if content_object: qs = qs.objects.filter(object_id=object_id) return bool(qs.count()) @classmethod def get(klass, *args, **kwargs): key = kwargs.get('key', None) object_id = kwargs.get('object_id', None) content_object = kwargs.get('content_object', None) if key: return klass.objects.get(key=key) elif object_id and content_object: return klass.objects.filter(object_id=object_id, content_object=content_object) elif object_id and not content_object: return klass.objects.filter(object_id=object_id) elif content_object and not object_id: return klass.objects.filter(content_object=content_object) else: raise klass.DoesNotExist( 'No objects exist for given argument combination %s' % kwargs) def remove_key(klass, *args, **kwargs): key = kwargs.get('key', None) object_id = kwargs.get('object_id', None) content_object = kwargs.get('content_object', None) if key: return klass.objects.filter(key=key).delete() elif object_id and content_object: return klass.objects.filter( object_id=object_id, content_object=content_object).delete() elif object_id and not content_object: return klass.objects.filter(object_id=object_id) elif content_object and not object_id: return klass.objects.filter(content_object=content_object).delete() else: raise klass.DoesNotExist( 'No objects exist for given argument combination %s' % kwargs)
class PayPalPayment(models.Model): paypal_id = models.CharField(max_length=64, db_index=True) user = models.ForeignKey(User, db_index=True, on_delete=models.PROTECT) response_data = JSONField() executed = models.BooleanField(default=False) created = models.DateTimeField(auto_now_add=True, db_index=True) notes = models.CharField(max_length=64) class Meta: unique_together = (('user', 'created'), ) # dangerous? @staticmethod def from_session(request): import paypalrestsdk try: payment_id = request.session["paypal-payment-to-execute"] del request.session["paypal-payment-to-execute"] except KeyError: raise ValueError("User session lost track of payment object.") payment = paypalrestsdk.Payment.find(payment_id) try: rec = PayPalPayment.objects.get(paypal_id=payment.id) except PayPalPayment.DoesNotExist: raise ValueError( "Trying to complete a payment that does not exist in our database: " + payment.id) if payment.state != "created" or rec.executed: raise ValueError( "Trying to complete an already-executed payment: %s, %s (%s)" + (payment.state, str(rec.executed), payment.id)) return (payment, rec) @staticmethod def execute(request, notes_must_match): # Get object. (payment, rec) = PayPalPayment.from_session(request) # Validate. if rec.notes != notes_must_match: raise ValueError( "Trying to complete the wrong sort of payment: %s" % payment.id) # Execute. if not payment.execute({"payer_id": request.GET["PayerID"]}): raise ValueError("Error executing PayPal.Payment (%s): " + (payment.id, repr(payment.error))) # Update our database record of the payment. rec.response_data = payment.to_dict() rec.executed = True rec.save() return (payment, rec)
class Bills(models.Model): proposer = models.ManyToManyField('councilors.CouncilorsDetail', blank=True, null=True, through='Councilors_Bills', db_index=True) uid = models.TextField(unique=True, db_index=True) election_year = models.CharField(max_length=100, db_index=True) county = models.CharField(max_length=100, db_index=True) type = models.TextField(blank=True, null=True) category = models.TextField(blank=True, null=True) abstract = models.TextField(blank=True, null=True) description = models.TextField(blank=True, null=True) methods = models.TextField(blank=True, null=True) last_action = models.TextField(blank=True, null=True) proposed_by = models.TextField(blank=True, null=True) petitioned_by = models.TextField(blank=True, null=True) brought_by = models.TextField(blank=True, null=True) related_units = models.TextField(blank=True, null=True) committee = models.TextField(blank=True, null=True) bill_no = models.TextField(blank=True, null=True) execution = models.TextField(blank=True, null=True) motions = JSONField(null=True) remark = models.TextField(blank=True, null=True) links = models.TextField(blank=True, null=True) param = JSONField(null=True) def __unicode__(self): return self.uid @property def sorted_proposer_set(self): return self.proposer.filter( councilors_bills__petition=False).order_by('councilors_bills__id') @property def sorted_petition_set(self): return self.proposer.filter( councilors_bills__petition=True).order_by('councilors_bills__id') @property def primary_proposer(self): return self.proposer.filter(councilors_bills__bill_id=self.uid, councilors_bills__priproposer=True, councilors_bills__petition=False)
class WRSPending(models.Model): """WRSPending models""" product = JSONField() inv_station_no = models.ForeignKey(InventoryStat, related_name="inv_wFK") cost_center_no = models.ForeignKey(CostCenter, related_name="cc_wFK") wrs_number = models.CharField(max_length=8) def __str__(self): return str(self.inv_station_no)
class Service(models.Model): name = models.CharField(max_length=64) secret = models.CharField(max_length=128) service_id = models.CharField(max_length=128) ips = JSONField(default=[]) validate_ip = models.BooleanField(default=True) def __str__(self): return self.name
class Sittings(models.Model): uid = models.CharField(max_length=100, unique=True) county = models.CharField(max_length=100, blank=True, null=True) name = models.CharField(max_length=100, blank=True, null=True) committee = models.TextField(blank=True, null=True) date = models.DateField() election_year = models.CharField(max_length=100) links = JSONField(null=True) def __unicode__(self): return self.name
class Profile(AbstractBase): user = models.OneToOneField(User, unique=True, related_name='profile') #first_name = models.CharField(verbose_name="First Name", max_length=30,null=True,blank=True) surname = models.CharField("User Surname",max_length=24) salutation = models.CharField(verbose_name="Salutation",max_length=12) birthdate = models.DateField("Birthday of User",null=True) sex = models.IntegerField(max_length=1,choices=GENDERS,default=MALE) address_1 = models.CharField(max_length=150,null=True) address_2 = models.CharField(max_length=150,blank=True) address_3 = models.CharField(max_length=150,blank=True) district = models.ForeignKey(District,related_name='profile_districts', null=True, default=None ) country = models.ForeignKey(Country,related_name='profile_countries', null=True, default=None ) division = models.ForeignKey(Division,related_name='profile_divisions', null=True, default=None ) region = models.ForeignKey(Region,related_name='profile_regions', null=True, default=None ) phone = models.CharField(max_length=15) mobile = models.CharField(max_length=15,null=True,blank=True) postcode = models.CharField(max_length=6,null=True) privacy = models.BooleanField(default=0) nickname = models.CharField(max_length=24,blank=True,null=True) def get_user_photo_file_name(self,filename): return 'images/user_photos/%s_%s' % (str(time.time()).replace('.','_'),filename ) photo = models.ImageField(upload_to=get_user_photo_file_name,blank=True,null=True) extra = JSONField(default="{}",blank=True) def __unicode__(self): return "%s " % self.user.first_name def get_absolute_url(self): return reverse('users-detail', args=[self.id] ) def get_photo(self): if self.photo: return self.photo else: if self.sex == MALE: return 'images/default/male_no_image_available.png' else: return 'images/default/female_no_image_available.jpg' @receiver(post_save, sender=User) def user_post_save_tasks(sender, instance, created, **kwargs): if created: profile, created = Profile.objects.get_or_create(user=instance) token, created = Token.objects.get_or_create(user=instance)
class QA(models.Model): """QA information""" name = models.CharField(max_length=45, help_text='QA name') description = models.TextField(help_text='QA Description') paname = models.CharField(max_length=45, help_text='Associate PA name') metric = JSONField(decoder=None, help_text='JSON structure with the QA result') job = models.ForeignKey(Job, related_name='job_qas') def __str__(self): return str(self.name)
class UserProfile(models.Model): user = models.ForeignKey(User, unique=True, db_index=True) massemail = models.BooleanField(default=True) # may we send you mail? old_id = models.IntegerField( blank=True, null=True) # from the pre-2012 GovTrack database last_mass_email = models.IntegerField(default=0) # monetization paid_features = JSONField( default={}, null=True ) # maps feature name to tuple (payment ID, sale ID or None if not useful) def lists(self): # make sure the 'default' list exists SubscriptionList.objects.get_or_create(user=self.user, is_default=True, defaults={ "name": "Email Updates", "email": 1 }) return SubscriptionList.objects.filter(user=self.user).order_by('name') def lists_with_email(self): # return lists with trackers with email updates turned on return SubscriptionList.objects.filter( user=self.user, email__gt=0, trackers__id__gt=0).distinct().order_by('name') def get_ad_free_message(self): if not self.paid_features: return False from datetime import datetime, timedelta if self.paid_features.get("ad_free_year"): ad_free_pmt = self.paid_features['ad_free_year'] pmt = PayPalPayment.objects.get(paypal_id=ad_free_pmt[0]) if pmt.created > (datetime.now() - timedelta(days=0.5)): return "Thanks for your one-year subscription to an ad-free GovTrack!" else: return "You went ad-free on %s. Your subscription expires on %s. Thanks!" % ( pmt.created.strftime("%x"), pmt.created.replace(year=pmt.created.year + 1).strftime("%x")) elif self.paid_features.get("ad_free_life"): ad_free_pmt = self.paid_features['ad_free_life'] pmt = PayPalPayment.objects.get(paypal_id=ad_free_pmt[0]) if pmt.created > (datetime.now() - timedelta(days=0.5)): return "Thanks for your subscription to an ad-free GovTrack for life!" else: return "You went ad-free for life on %s. Thanks!" % pmt.created.strftime( "%x") else: return False
class Account(AccountApi, BaseModel): account_id = models.BigIntegerField(primary_key=True) user = models.ForeignKey( get_wepay_model_name('user'), related_name='accounts', null=True) name = models.CharField(max_length=255) state = models.CharField(max_length=255) description = models.CharField(max_length=255) reference_id = models.CharField(max_length=255, blank=True) gaq_domains = JSONField(null=True, blank=True) theme_object = JSONField(null=True, blank=True) type = models.CharField(max_length=255) create_time = models.BigIntegerField(null=True) balances = JSONField(null=True, blank=True) statuses = JSONField(null=True, blank=True) action_reasons = JSONField(null=True, blank=True) country = models.CharField(max_length=2) currencies = JSONField(null=True, blank=True) objects = AccountManager() def __str__(self): return "%s - %s" % (self.pk, self.name) class Meta(BaseModel.Meta): abstract = is_abstract('account') db_table = 'djwepay_account' verbose_name = 'WePay Account'
class Manifestation(Resource): data = JSONField(null=True) community = GenericForeignKey(ct_field="community_type", fk_field="community_id") community_type = models.ForeignKey(ContentType, related_name="+") community_id = models.PositiveIntegerField() task = models.CharField(max_length=255, null=True, blank=True) completed_at = models.DateTimeField(null=True, blank=True) @staticmethod def generate_config(allowed_config, **kwargs): warnings.warn( "Manifestation.generate_config deprecated in favor for " "Community.filter_growth_configuration and Community.filter_scope_configuration" ) config = { key: value for key, value in kwargs.items() if key in allowed_config } return config def get_data(self, async=False): from core.tasks import get_manifestation_data if self.data: return self.data if self.task: result = AsyncResult(self.task) if not result.ready(): raise DSProcessUnfinished("Manifest processing is not done") elif result.successful(): self.data = result.result elif result.failed(): self.data = str(result.result) else: raise AssertionError( "get_data is not handling AsyncResult with status: {}". format(result.status)) self.status = celery_status_code(result.status) elif async: self.task = get_manifestation_data.delay(self.id) self.status = celery_status_code(PENDING) self.save() raise DSProcessUnfinished("Manifest started processing") else: self.data = get_manifestation_data(self.id) self.status = celery_status_code(SUCCESS) self.completed_at = datetime.now() self.save() return self.data
class BaseGeoModel(models.Model): name = models.CharField(max_length=255) code = models.CharField(max_length=50,unique=True) slug = models.CharField(max_length=255,unique=True) extra = JSONField(default="{}",blank=True) def __unicode__(self): return " %s " % self.name class Meta: abstract = True
class Votes(models.Model): voter = models.ManyToManyField('councilors.CouncilorsDetail', through='Councilors_Votes') uid = models.CharField(max_length=110, unique=True) sitting = models.ForeignKey('sittings.Sittings', to_field="uid", related_name='votes') vote_seq = models.CharField(max_length=10) date = models.DateField() content = models.TextField() summary = models.TextField(blank=True, null=True) conflict = models.NullBooleanField() result = models.CharField(blank=True, null=True, max_length=50) results = JSONField(null=True) def __unicode__(self): return self.content
class Measurement(models.Model): """Measurement of a metric by a job. """ metric = models.ForeignKey(Metric, null=False) job = models.ForeignKey(Job, null=False, related_name='measurements') value = models.FloatField(help_text='Metric scalar measurement') metadata = JSONField(null=True, blank=True, default=None, help_text='Measurement metadata', decoder=None) def __float__(self): return self.value
class SketchMapper(models.Model): name = models.CharField(max_length=200, unique=True) mapper = JSONField(null=False, blank=False) owner = models.ForeignKey(User) access = models.IntegerField(choices=SKETCH_ACCESS_LEVELS) def clean(self): from django.core.exceptions import ValidationError from mappermanager import mappingManager print "mpp", self.mapper, type(self.mapper) try: mappingManager.validateMapping(self.mapper) except Exception, e: raise ValidationError(str(e))
class Metric(models.Model): """Metric definition. """ metric = models.CharField(max_length=16, primary_key=True, help_text='Metric name') # some metrics may not have unit unit = models.CharField(max_length=16, null=True, blank=True, default='', help_text='Metric unit, astropy compatible string') description = models.TextField(help_text='Metric description') operator = models.CharField(max_length=2, blank=False, default='<', help_text='Operator used to test measurement' 'value against metric specification') # some metrics may not have associated parameters parameters = JSONField(null=True, blank=True, default=None, help_text='Parameters used to define the metric', decoder=None) specs = JSONField(null=True, blank=True, default=None, help_text='Array of metric specification', decoder=None) reference = JSONField(null=True, blank=True, default=None, help_text='Metric reference', decoder=None) def __str__(self): return self.metric
class Course(BaseModel): is_active = models.BooleanField(_(u'активен?'), default=True) name = models.CharField(_(u'название курса'), max_length=140, blank=True, null=True) description = models.TextField(_(u'описание'), blank=True) created_by = models.ForeignKey('account.Account', related_name='courses', verbose_name=_(u'создатель'), blank=True, null=True) teacher = models.ManyToManyField('account.Account', related_name='courses_teachers', verbose_name=_(u'преподователь'), blank=True, null=True) code_errors = JSONField(_(u'ошибки редактирования урока'), default={}, blank=True, null=True) is_correct = models.BooleanField(_(u'урок составлен верно?'), default=True) picture = ImageField(upload_to=course_picture_upload, blank=True, null=True) @property def type(self): return 'course' class Meta: verbose_name = _(u'Курс') verbose_name_plural = _(u'Курсы') app_label = 'quizy' def __unicode__(self): if self.name: return self.name return _(u"Курс без именени") @property def enroll_number(self): enrolls = {} for c in LessonEnroll.objects.filter(lesson__course=self): enrolls.update({ c.pk: c }) for c in self.course_enrolls.filter(course=self): enrolls.update({ c.pk: c }) return { 'number': len(enrolls.keys()) } def get_first_lesson(self): lessons = self.lesson_set.all().order_by('number')[:1] if lessons: return lessons[0]
def register(target_model, options): logging.info('[denorm.register] %s' % target_model) if not hasattr(target_model, '_meta'): raise AttributeError('The model being registered must derive from Model.') target = util.get_model_name(target_model) target_options = target_model._meta # register signals for target. use dispatch_uid to prevent duplicates. # about signals: https://docs.djangoproject.com/en/1.8/topics/signals/ # built-in signals: https://docs.djangoproject.com/en/1.8/ref/signals/ db_signals.post_init.connect(receivers.target_model_post_init, sender=target_model, dispatch_uid='denorm_target_%s_post_init'%target) db_signals.pre_save.connect(receivers.target_model_pre_save, sender=target_model, dispatch_uid='denorm_target_%s_pre_save'%target) db_signals.post_save.connect(receivers.target_model_post_save, sender=target_model, dispatch_uid='denorm_target_%s_post_save'%target) target_graph = core.TARGET_GRAPH[target_model] = core.TARGET_GRAPH.get(target_model, {}) for source, source_dict in options['sources'].iteritems(): strategy = source_dict.get('strategy', 'cursor') # options are: [cursor, mapreduce]. defaults to cursor. # TODO: support storage options 'list' and 'dict' storage = source_dict.get('storage', 'scalar') # choices: [scalar, shared_dict] if storage == 'scalar': target_foreign_key = target_options.get_field(source) # if field did not exist, then get_field would have raised FieldDoesNotExist if not isinstance(target_foreign_key, ForeignKey): raise AttributeError('The source field %s.%s must be a ForeignKey' % (target, source)) source_model = target_foreign_key.rel.to elif storage == 'shared_dict': target_foreign_key_list = target_options.get_field(Inflector().pluralize(source)) # if field did not exist, then get_field would have raised FieldDoesNotExist if not isinstance(target_foreign_key_list, tb_fields.ListField): raise AttributeError('The target field %s.%s must be a ListField' % (target, source)) # model must be explicitly configured, because target field does not specify it source_model = source_dict.get('model') # create denorm data field try: target_options.get_field('denorm_data') except FieldDoesNotExist: # field should not exist. now let's create it. denorm_data_field = JSONField(name='denorm_data', null=True, blank=True, decoder_kwargs={'cls': json_fields.JSONDecoder, 'parse_float':float}) denorm_data_field.contribute_to_class(target_model, 'denorm_data') else: # field was already created on prior source field # TODO: do at beginning of target model configuration to make sure developer did not define it pass else: logging.error('[denorm.register] invalid storage option %s' % storage) source_options = source_model._meta # register signals for source. use dispatch_uid to prevent duplicates. db_signals.post_init.connect(receivers.source_model_post_init, sender=source_model, dispatch_uid='denorm_source_%s_post_init'%source) db_signals.pre_save.connect(receivers.source_model_pre_save, sender=source_model, dispatch_uid='denorm_source_%s_pre_save'%source) db_signals.post_save.connect(receivers.source_model_post_save, sender=source_model, dispatch_uid='denorm_source_%s_post_save'%source) # FIXME: it's quirky that label and throttles must be configured under each target-source in app's denorm_fields, # FIXME: but it gets applied here for entire source (not target dependent). it probably should be configured once # FIXME: per source, but how do accomplish that in the current configuration design? source_graph = core.SOURCE_GRAPH[source_model] = core.SOURCE_GRAPH.get(source_model, { 'label': source_dict.get('label'), 'throttles': source_dict.get('throttles'), 'fields': {} }) source_graph_fields = source_graph['fields'] # mark model as registered for denormalization source_model._denorm_registered = True # clone list, so that if we add _id below, it doesn't corrupt original list denorm_field_names = list(source_dict['fields']) target_graph[source] = { 'fields': denorm_field_names, 'storage': storage, 'source_model': source_model # important for shared_dict storage, because we don't know source model based on list field } for i, denorm_field_name in enumerate(denorm_field_names): source_field = source_options.get_field(denorm_field_name) # if field did not exist, then get_field would have raised FieldDoesNotExist target_field_name = '%s_%s' % (source, denorm_field_name) if storage == 'scalar': try: target_options.get_field(target_field_name) except FieldDoesNotExist: # field should not exist, so we're good pass else: raise AttributeError('The denorm field %s.%s must not already exist' % (target_model.__name__, target_field_name)) # create target field of same type as source_field target_field = _copy_field(source_field, target_field_name, target) target_field.contribute_to_class(target_model, target_field_name) #print('added field %s with name %s, column %s' % (target_field, target_field_name, target_field.column)) #print('added field %s with name %s' % (target_model._meta.get_field(target_field_name), target_field_name)) else: assert(storage == 'shared_dict') # denorm_data field was already created outside this iteration loop pass # if source field is a foreign key, then we reference its key rather than the actual related field, # because we are not deferencing further than the key, and do not want to do an extra db lookup. if isinstance(source_field, ForeignKey): denorm_field_name += '_id' denorm_field_names[i] = denorm_field_name source_field_graph = source_graph_fields[denorm_field_name] = source_graph_fields.get(denorm_field_name, []) source_field_graph.append({ 'target_model': target_model, 'source': source, 'strategy': strategy, 'storage': storage, 'shards': source_dict.get('shards') and util.convert_func_to_string(source_dict['shards']) })