class Uninersity2035Id(models.Model): class Meta: app_label = "unti2035" course_id = CourseKeyField(max_length=255, db_index=True, unique=True, verbose_name='Course ID') unti2035_id = models.CharField(max_length=255, unique=True) def __str__(self): return "Course: {}".format(self.course_id)
class VerificationCheckpoint(DeprecatedModelMixin, models.Model): # pylint: disable=model-missing-unicode """ DEPRECATED - do not use. To be removed in a future Open edX release (Hawthorn). """ course_id = CourseKeyField(max_length=255, db_index=True) checkpoint_location = models.CharField(max_length=255) photo_verification = models.ManyToManyField( SoftwareSecurePhotoVerification) class Meta(object): app_label = "verify_student" unique_together = ('course_id', 'checkpoint_location')
class SkippedReverification(DeprecatedModelMixin, models.Model): # pylint: disable=model-missing-unicode """ DEPRECATED - do not use. To be removed in a future Open edX release (Hawthorn). """ user = models.ForeignKey(User) course_id = CourseKeyField(max_length=255, db_index=True) checkpoint = models.ForeignKey(VerificationCheckpoint, related_name="skipped_checkpoint") created_at = models.DateTimeField(auto_now_add=True) class Meta(object): app_label = "verify_student" unique_together = (('user', 'course_id'),)
class TileConfiguration(ConfigurationModel): """ Stores a list of tiles presented on the front page. """ site = models.CharField(max_length=32, default='default', blank=False) course_id = CourseKeyField(max_length=255, db_index=True) class Meta(ConfigurationModel.Meta): app_label = 'branding_stanford' def __unicode__(self): return u"{0} {1} {2}".format(self.site, self.course_id, self.enabled)
class CourseActionState(models.Model): """ A django model for maintaining state data for course actions that take a long time. For example: course copying (reruns), import, export, and validation. """ class Meta(object): """ For performance reasons, we disable "concrete inheritance", by making the Model base class abstract. With the "abstract base class" inheritance model, tables are only created for derived models, not for the parent classes. This way, we don't have extra overhead of extra tables and joins that would otherwise happen with the multi-table inheritance model. """ abstract = True # FIELDS # Created is the time this action was initiated created_time = models.DateTimeField(auto_now_add=True) # Updated is the last time this entry was modified updated_time = models.DateTimeField(auto_now=True) # User who initiated the course action created_user = models.ForeignKey( User, # allow NULL values in case the action is not initiated by a user (e.g., a background thread) null=True, # set on_delete to SET_NULL to prevent this model from being deleted in the event the user is deleted on_delete=models.SET_NULL, # add a '+' at the end to prevent a backward relation from the User model related_name='created_by_user+') # User who last updated the course action updated_user = models.ForeignKey( User, # allow NULL values in case the action is not updated by a user (e.g., a background thread) null=True, # set on_delete to SET_NULL to prevent this model from being deleted in the event the user is deleted on_delete=models.SET_NULL, # add a '+' at the end to prevent a backward relation from the User model related_name='updated_by_user+') # Course that is being acted upon course_key = CourseKeyField(max_length=255, db_index=True) # Action that is being taken on the course action = models.CharField(max_length=100, db_index=True) # Current state of the action. state = models.CharField(max_length=50) # MANAGERS objects = CourseActionStateManager()
class CertificateTemplate(TimeStampedModel): """A set of custom web certificate templates. Web certificate templates are Django web templates to replace PDF certificate. A particular course may have several kinds of certificate templates (e.g. honor and verified). """ name = models.CharField( max_length=255, help_text=_(u'Name of template.'), ) description = models.CharField( max_length=255, null=True, blank=True, help_text=_(u'Description and/or admin notes.'), ) template = models.TextField(help_text=_(u'Django template HTML.'), ) organization_id = models.IntegerField( null=True, blank=True, db_index=True, help_text=_(u'Organization of template.'), ) course_key = CourseKeyField( max_length=255, null=True, blank=True, db_index=True, ) mode = models.CharField( max_length=125, choices=GeneratedCertificate.MODES, default=GeneratedCertificate.MODES.honor, null=True, blank=True, help_text=_(u'The course mode for this template.'), ) is_active = models.BooleanField( help_text=_(u'On/Off switch.'), default=False, ) def __unicode__(self): return u'%s' % (self.name, ) class Meta(object): get_latest_by = 'created' unique_together = (('organization_id', 'course_key', 'mode'), ) app_label = "certificates"
class UserCourseTag(models.Model): """ Per-course user tags, to be used by various things that want to store tags about the user. Added initially to store assignment to experimental groups. """ user = models.ForeignKey(User, db_index=True, related_name="+") key = models.CharField(max_length=255, db_index=True) course_id = CourseKeyField(max_length=255, db_index=True) value = models.TextField() class Meta(object): unique_together = ("user", "course_id", "key")
class StudentGradebookHistory(TimeStampedModel): """ A running audit trail for the StudentGradebook model. Listens for post_save events and creates/stores copies of gradebook entries. """ user = models.ForeignKey(User, db_index=True) course_id = CourseKeyField(db_index=True, max_length=255, blank=True) grade = models.FloatField() proforma_grade = models.FloatField() progress_summary = models.TextField(blank=True) grade_summary = models.TextField() grading_policy = models.TextField() is_passed = models.BooleanField(db_index=True, default=False) @receiver(post_save, sender=StudentGradebook) def save_history(sender, instance, **kwargs): # pylint: disable=no-self-argument, unused-argument """ Event hook for creating gradebook entry copies """ history_entries = StudentGradebookHistory.objects.filter( user=instance.user, course_id=instance.course_id) latest_history_entry = None if len(history_entries): latest_history_entry = history_entries[0] create_history_entry = False if latest_history_entry is not None: if (latest_history_entry.grade != instance.grade or latest_history_entry.proforma_grade != instance.proforma_grade or latest_history_entry.progress_summary != instance.progress_summary or latest_history_entry.grade_summary != instance.grade_summary or latest_history_entry.grading_policy != instance.grading_policy or latest_history_entry.is_passed != instance.is_passed): create_history_entry = True else: create_history_entry = True if create_history_entry: new_history_entry = StudentGradebookHistory( user=instance.user, course_id=instance.course_id, grade=instance.grade, proforma_grade=instance.proforma_grade, progress_summary=instance.progress_summary, grade_summary=instance.grade_summary, grading_policy=instance.grading_policy, is_passed=instance.is_passed) new_history_entry.save()
class CertificateGenerationCourseSetting(TimeStampedModel): """Enable or disable certificate generation for a particular course. This controls whether students are allowed to "self-generate" certificates for a course. It does NOT prevent us from batch-generating certificates for a course using management commands. In general, we should only enable self-generated certificates for a course once we successfully generate example certificates for the course. This is enforced in the UI layer, but not in the data layer. """ course_key = CourseKeyField(max_length=255, db_index=True) enabled = models.BooleanField(default=False) class Meta(object): get_latest_by = 'created' app_label = "certificates" @classmethod def is_enabled_for_course(cls, course_key): """Check whether self-generated certificates are enabled for a course. Arguments: course_key (CourseKey): The identifier for the course. Returns: boolean """ try: latest = cls.objects.filter(course_key=course_key).latest() except cls.DoesNotExist: return False else: return latest.enabled @classmethod def set_enabled_for_course(cls, course_key, is_enabled): """Enable or disable self-generated certificates for a course. Arguments: course_key (CourseKey): The identifier for the course. is_enabled (boolean): Whether to enable or disable self-generated certificates. """ CertificateGenerationCourseSetting.objects.create( course_key=course_key, enabled=is_enabled )
class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( name='CourseMessage', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('course_key', CourseKeyField(db_index=True, max_length=255, blank=True)), ('message', models.TextField(null=True, blank=True)), ], ), migrations.CreateModel( name='GlobalStatusMessage', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('change_date', models.DateTimeField(auto_now_add=True, verbose_name='Change date')), ('enabled', models.BooleanField(default=False, verbose_name='Enabled')), ('message', models.TextField(null=True, blank=True)), ('changed_by', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, editable=False, to=settings.AUTH_USER_MODEL, null=True, verbose_name='Changed by')), ], options={ 'ordering': ('-change_date', ), 'abstract': False, }, ), migrations.AddField( model_name='coursemessage', name='global_message', field=models.ForeignKey(to='status.GlobalStatusMessage'), ), ]
class Optout(models.Model): """ Stores users that have opted out of receiving emails from a course. """ # Allowing null=True to support data migration from email->user. # We need to first create the 'user' column with some sort of default in order to run the data migration, # and given the unique index, 'null' is the best default value. user = models.ForeignKey(User, db_index=True, null=True) course_id = CourseKeyField(max_length=255, db_index=True) class Meta(object): app_label = "bulk_email" unique_together = ('user', 'course_id')
class UniversityIDSettings(models.Model): """ This model stores university id settings for each course. """ course_key = CourseKeyField(primary_key=True, max_length=255, db_index=True) registration_end_date = models.DateField(null=True, blank=True, verbose_name=_('Registration End Date')) terms_and_conditions = models.TextField(null=True, blank=True, verbose_name=_('Terms and Conditions')) def __unicode__(self): return unicode(self.course_key) class Meta: app_label = 'edraak_university'
class CourseMessage(models.Model): """ Model that allows the user to specify messages for individual courses. This is not a ConfigurationModel because using it's not designed to support multiple configurations at once, which would be problematic if separate courses need separate error messages. """ global_message = models.ForeignKey(GlobalStatusMessage) course_key = CourseKeyField(max_length=255, blank=True, db_index=True) message = models.TextField(blank=True, null=True) def __unicode__(self): return unicode(self.course_key)
class Migration(migrations.Migration): dependencies = [ ('grades', '0004_visibleblocks_course_id'), ] operations = [ migrations.AlterField( model_name='coursepersistentgradesflag', name='course_id', field=CourseKeyField(max_length=255, db_index=True), ), ]
class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( name='UserCourseTag', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('key', models.CharField(max_length=255, db_index=True)), ('course_id', CourseKeyField(max_length=255, db_index=True)), ('value', models.TextField()), ('user', models.ForeignKey(related_name='+', to=settings.AUTH_USER_MODEL)), ], ), migrations.CreateModel( name='UserOrgTag', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)), ('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)), ('key', models.CharField(max_length=255, db_index=True)), ('org', models.CharField(max_length=255, db_index=True)), ('value', models.TextField()), ('user', models.ForeignKey(related_name='+', to=settings.AUTH_USER_MODEL)), ], ), migrations.CreateModel( name='UserPreference', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('key', models.CharField(db_index=True, max_length=255, validators=[django.core.validators.RegexValidator(b'[-_a-zA-Z0-9]+')])), ('value', models.TextField()), ('user', models.ForeignKey(related_name='preferences', to=settings.AUTH_USER_MODEL)), ], ), migrations.AlterUniqueTogether( name='userpreference', unique_together=set([('user', 'key')]), ), migrations.AlterUniqueTogether( name='userorgtag', unique_together=set([('user', 'org', 'key')]), ), migrations.AlterUniqueTogether( name='usercoursetag', unique_together=set([('user', 'course_id', 'key')]), ), ]
class VerifiedTrackCohortedCourse(models.Model): """ Tracks which courses have verified track auto-cohorting enabled. """ course_key = CourseKeyField( max_length=255, db_index=True, unique=True, help_text=ugettext_lazy(u"The course key for the course we would like to be auto-cohorted.") ) verified_cohort_name = models.CharField(max_length=100, default=DEFAULT_VERIFIED_COHORT_NAME) enabled = models.BooleanField() def __unicode__(self): return u"Course: {}, enabled: {}".format(unicode(self.course_key), self.enabled) @classmethod def verified_cohort_name_for_course(cls, course_key): """ Returns the given cohort name for the specific course. Args: course_key (CourseKey): a course key representing the course we want the verified cohort name for Returns: The cohort name if the course key has one associated to it. None otherwise. """ try: config = cls.objects.get(course_key=course_key) return config.verified_cohort_name except cls.DoesNotExist: return None @classmethod def is_verified_track_cohort_enabled(cls, course_key): """ Checks whether or not verified track cohort is enabled for the given course. Args: course_key (CourseKey): a course key representing the course we want to check Returns: True if the course has verified track cohorts is enabled False if not """ try: return cls.objects.get(course_key=course_key).enabled except cls.DoesNotExist: return False
class CreditCourse(models.Model): """ Model for tracking a credit course. """ course_key = CourseKeyField(max_length=255, db_index=True, unique=True) enabled = models.BooleanField(default=False) CREDIT_COURSES_CACHE_KEY = "credit.courses.set" @classmethod def is_credit_course(cls, course_key): """ Check whether the course has been configured for credit. Args: course_key (CourseKey): Identifier of the course. Returns: bool: True iff this is a credit course. """ credit_courses = cache.get(cls.CREDIT_COURSES_CACHE_KEY) if credit_courses is None: credit_courses = set( unicode(course.course_key) for course in cls.objects.filter(enabled=True)) cache.set(cls.CREDIT_COURSES_CACHE_KEY, credit_courses) return unicode(course_key) in credit_courses @classmethod def get_credit_course(cls, course_key): """ Get the credit course if exists for the given 'course_key'. Args: course_key(CourseKey): The course identifier Raises: DoesNotExist if no CreditCourse exists for the given course key. Returns: CreditCourse if one exists for the given course key. """ return cls.objects.get(course_key=course_key, enabled=True) def __unicode__(self): """Unicode representation of the credit course. """ return unicode(self.course_key)
class WaffleFlagCourseOverrideModel(ConfigurationModel): """ Used to force a waffle flag on or off for a course. """ OVERRIDE_CHOICES = Choices(('on', _('Force On')), ('off', _('Force Off'))) ALL_CHOICES = OVERRIDE_CHOICES + Choices('unset') KEY_FIELDS = ('waffle_flag', 'course_id') # The course that these features are attached to. waffle_flag = CharField(max_length=255, db_index=True) course_id = CourseKeyField(max_length=255, db_index=True) override_choice = CharField(choices=OVERRIDE_CHOICES, default=OVERRIDE_CHOICES.on, max_length=3) @classmethod @request_cached def override_value(cls, waffle_flag, course_id): """ Returns whether the waffle flag was overridden (on or off) for the course, or is unset. Arguments: waffle_flag (String): The name of the flag. course_id (CourseKey): The course id for which the flag may have been overridden. If the current config is not set or disabled for this waffle flag and course id, returns ALL_CHOICES.unset. Otherwise, returns ALL_CHOICES.on or ALL_CHOICES.off as configured for the override_choice. """ if not course_id or not waffle_flag: return cls.ALL_CHOICES.unset effective = cls.objects.filter(waffle_flag=waffle_flag, course_id=course_id).order_by('-change_date').first() if effective and effective.enabled: return effective.override_choice return cls.ALL_CHOICES.unset class Meta(object): app_label = "waffle_utils" verbose_name = 'Waffle flag course override' verbose_name_plural = 'Waffle flag course overrides' def __unicode__(self): enabled_label = "Enabled" if self.enabled else "Not Enabled" # pylint: disable=no-member return u"Course '{}': Persistent Grades {}".format(text_type(self.course_id), enabled_label)
class CourseUserGroup(models.Model): """ This model represents groups of users in a course. Groups may have different types, which may be treated specially. For example, a user can be in at most one cohort per course, and cohorts are used to split up the forums by group. """ default_cohort_name = "default_cohort" class Meta(object): unique_together = (('name', 'course_id'), ) name = models.CharField(max_length=255, help_text=("What is the name of this group? " "Must be unique within a course.")) users = models.ManyToManyField(User, db_index=True, related_name='course_groups', help_text="Who is in this group?") # Note: groups associated with particular runs of a course. E.g. Fall 2012 and Spring # 2013 versions of 6.00x will have separate groups. course_id = CourseKeyField( max_length=255, db_index=True, help_text="Which course is this group associated with?", ) # For now, only have group type 'cohort', but adding a type field to support # things like 'question_discussion', 'friends', 'off-line-class', etc COHORT = 'cohort' # If changing this string, update it in migration 0006.forwards() as well GROUP_TYPE_CHOICES = ((COHORT, 'Cohort'), ) group_type = models.CharField(max_length=20, choices=GROUP_TYPE_CHOICES) @classmethod def create(cls, name, course_id, group_type=COHORT): """ Create a new course user group. Args: name: Name of group course_id: course id group_type: group type """ return cls.objects.get_or_create(course_id=course_id, group_type=group_type, name=name) def __unicode__(self): return self.name
class CourseEditLTIFieldsEnabledFlag(ConfigurationModel): """ Enables the editing of "request username" and "request email" fields of LTI consumer for a specific course. """ KEY_FIELDS = ('course_id', ) course_id = CourseKeyField(max_length=255, db_index=True) @classmethod @request_cached def lti_access_to_learners_editable(cls, course_id, is_already_sharing_learner_info): """ Looks at the currently active configuration model to determine whether the feature that enables editing of "request username" and "request email" fields of LTI consumer is available or not. Backwards Compatibility: Enable this feature for a course run who was sharing learner username/email in the past. Arguments: course_id (CourseKey): course id for which we need to check this configuration is_already_sharing_learner_info (bool): indicates whether LTI consumer is already sharing edX learner username/email. """ course_specific_config = ( CourseEditLTIFieldsEnabledFlag.objects.filter( course_id=course_id).order_by('-change_date').first()) if is_already_sharing_learner_info: if not course_specific_config: CourseEditLTIFieldsEnabledFlag.objects.create( course_id=course_id, enabled=True) return True return course_specific_config.enabled if course_specific_config else False def __unicode__(self): en = "Not " if self.enabled: en = "" return u"Course '{course_id}': Edit LTI access to Learner information {en}Enabled".format( course_id=unicode(self.course_id), en=en, )
class StudentModule(models.Model): '''Mocks the courseware.models.StudentModule class attributes declared in StudentModule but not yet needed for mocking are remarked out with a '#!' They are here to A) Help understand context of the class without requiring opening the courseware/models.py file B) Be available to quickly update this mock when needed ''' #! MODEL_TAGS = ['course_id', 'module_type'] # For a homework problem, contains a JSON # object consisting of state #! MODULE_TYPES = (('problem', 'problem'), #! ('video', 'video'), #! ('html', 'html'), #! ('course', 'course'), #! ('chapter', 'Section'), #! ('sequential', 'Subsection'), #! ('library_content', 'Library Content')) #! module_state_key = LocationKeyField(max_length=255, db_index=True, db_column='module_id') student = models.ForeignKey(User, db_index=True) course_id = CourseKeyField(max_length=255, db_index=True) #! class Meta(object): #! app_label = "courseware" #! unique_together = (('student', 'module_state_key', 'course_id'),) #! # Internal state of the object #! state = models.TextField(null=True, blank=True) #! # Grade, and are we done? #! grade = models.FloatField(null=True, blank=True, db_index=True) #! max_grade = models.FloatField(null=True, blank=True) #! DONE_TYPES = ( #! ('na', 'NOT_APPLICABLE'), #! ('f', 'FINISHED'), #! ('i', 'INCOMPLETE'), #! ) #! done = models.CharField(max_length=8, choices=DONE_TYPES, default='na', db_index=True) # the production model sets 'auto_now_add=True' andn 'db_index=True' created = models.DateTimeField() modified = models.DateTimeField()
class StudentFieldOverride(TimeStampedModel): """ Holds the value of a specific field overriden for a student. This is used by the code in the `courseware.student_field_overrides` module to provide overrides of xblock fields on a per user basis. """ course_id = CourseKeyField(max_length=255, db_index=True) location = LocationKeyField(max_length=255, db_index=True) student = models.ForeignKey(User, db_index=True) class Meta(object): app_label = "courseware" unique_together = (('course_id', 'field', 'location', 'student'), ) field = models.CharField(max_length=255) value = models.TextField(default='null')
class CourseHLSPlaybackEnabledFlag(ConfigurationModel): """ Enables HLS Playback for a specific course. Global feature must be enabled for this to take effect. """ KEY_FIELDS = ('course_id', ) course_id = CourseKeyField(max_length=255, db_index=True) def __unicode__(self): not_en = "Not " if self.enabled: not_en = "" return u"Course '{course_key}': HLS Playback {not_enabled}Enabled".format( course_key=unicode(self.course_id), not_enabled=not_en)
class CourseVideoUploadsEnabledByDefault(ConfigurationModel): """ Enables video uploads enabled by default feature for a specific course. Its global feature must be enabled for this to take effect. """ KEY_FIELDS = ('course_id', ) course_id = CourseKeyField(max_length=255, db_index=True) def __unicode__(self): not_en = "Not " if self.enabled: not_en = "" return u"Course '{course_key}': Video Uploads {not_enabled}Enabled by default.".format( course_key=unicode(self.course_id), not_enabled=not_en)
class VIPCoursePrice(models.Model): """ VIP course price """ SUBSCRIBE_NORMAL = 0 SUBSCRIBE_PAY = 1 SUBSCRIBE_TYPE_CHOICES = ( (SUBSCRIBE_NORMAL, _(u'subscribe normal')), (SUBSCRIBE_PAY, _(u'subscribe pay')), ) course_id = CourseKeyField(max_length=255, db_index=True) subscribe = models.IntegerField(default=SUBSCRIBE_NORMAL, choices=SUBSCRIBE_TYPE_CHOICES) class Meta(object): app_label = 'membership' @classmethod def get_course_subscribe_type(cls): """ 订阅期内课程类型(是否还需收费) """ subscribe_type = {} for course in cls.objects.all(): subscribe_type.setdefault(course.subscribe, []).append(course.course_id) return subscribe_type @classmethod def get_vip_course_price_data(cls): ''' vip订阅课程类型数据 ''' course_prices = cls.objects.filter() course_price_dict = {} for c in course_prices: course_price_dict[str(c.course_id)] = int(c.subscribe) return course_price_dict @classmethod def is_subscribe_pay(cls, course_id): """ 订阅期内该课程类型,是否收费 """ return cls.objects.filter(course_id=course_id, subscribe=cls.SUBSCRIBE_PAY).exists()
class Migration(migrations.Migration): dependencies = [ ('grades', '0005_multiple_course_flags'), ] operations = [ migrations.CreateModel( name='PersistentCourseGrade', fields=[ ('created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, verbose_name='created', editable=False)), ('modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, verbose_name='modified', editable=False)), ('id', coursewarehistoryextended.fields.UnsignedBigIntAutoField( serialize=False, primary_key=True)), ('user_id', models.IntegerField(db_index=True)), ('course_id', CourseKeyField(max_length=255)), ('course_edited_timestamp', models.DateTimeField( verbose_name='Last content edit timestamp')), ('course_version', models.CharField( max_length=255, verbose_name='Course content version identifier', blank=True)), ('grading_policy_hash', models.CharField(max_length=255, verbose_name='Hash of grading policy')), ('percent_grade', models.FloatField()), ('letter_grade', models.CharField(max_length=255, verbose_name='Letter grade for course')), ], ), migrations.AlterUniqueTogether( name='persistentcoursegrade', unique_together=set([('course_id', 'user_id')]), ), ]
class Role(models.Model): objects = NoneToEmptyManager() name = models.CharField(max_length=30, null=False, blank=False) users = models.ManyToManyField(User, related_name="roles") course_id = CourseKeyField(max_length=255, blank=True, db_index=True) class Meta(object): # use existing table that was originally created from django_comment_client app db_table = 'django_comment_client_role' def __unicode__(self): # pylint: disable=no-member return self.name + " for " + (self.course_id.to_deprecated_string() if self.course_id else "all courses") # TODO the name of this method is a little bit confusing, # since it's one-off and doesn't handle inheritance later def inherit_permissions(self, role): """ Make this role inherit permissions from the given role. Permissions are only added, not removed. Does not handle inheritance. """ if role.course_id and role.course_id != self.course_id: logging.warning( "%s cannot inherit permissions from %s due to course_id inconsistency", self, role, ) for per in role.permissions.all(): self.add_permission(per) def add_permission(self, permission): self.permissions.add( Permission.objects.get_or_create(name=permission)[0]) def has_permission(self, permission): """Returns True if this role has the given permission, False otherwise.""" course = modulestore().get_course(self.course_id) if course is None: raise ItemNotFoundError(self.course_id) if permission_blacked_out(course, {self.name}, permission): return False return self.permissions.filter(name=permission).exists()
class CourseGoal(models.Model): """ Represents a course goal set by the user. """ user = models.ForeignKey(User, blank=False) course_key = CourseKeyField(max_length=255, db_index=True) goal_key = models.CharField(max_length=100, choices=GOAL_KEY_CHOICES, default=GOAL_KEY_CHOICES.unsure) def __unicode__(self): return 'CourseGoal: {user} set goal to {goal} for course {course}'.format( user=self.user.username, course=self.course_key, goal_key=self.goal_key, ) class Meta: unique_together = ("user", "course_key")
class OfflineComputedGradeLog(models.Model): """ Log of when offline grades are computed. Use this to be able to show instructor when the last computed grades were done. """ class Meta(object): app_label = "courseware" ordering = ["-created"] get_latest_by = "created" course_id = CourseKeyField(max_length=255, db_index=True) created = models.DateTimeField(auto_now_add=True, null=True, db_index=True) seconds = models.IntegerField(default=0) # seconds elapsed for computation nstudents = models.IntegerField(default=0) def __unicode__(self): return "[OCGLog] %s: %s" % (text_type(self.course_id), self.created) # pylint: disable=no-member
class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( name='Permission', fields=[ ('name', models.CharField(max_length=30, serialize=False, primary_key=True)), ], options={ 'db_table': 'django_comment_client_permission', }, ), migrations.CreateModel( name='Role', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('name', models.CharField(max_length=30)), ('course_id', CourseKeyField(db_index=True, max_length=255, blank=True)), ('users', models.ManyToManyField(related_name='roles', to=settings.AUTH_USER_MODEL)), ], options={ 'db_table': 'django_comment_client_role', }, ), migrations.AddField( model_name='permission', name='roles', field=models.ManyToManyField(related_name='permissions', to='django_comment_common.Role'), ), ]