From 7f3a443409bf71732684c4e6953a715568b2995d Mon Sep 17 00:00:00 2001 From: David Ormsbee Date: Sun, 22 Jul 2012 15:35:24 -0400 Subject: [PATCH] Change over to new reg fields (styling still broken) --- ...e_approved_demographic_fields_fall_2012.py | 188 ++++++++++++++++++ common/djangoapps/student/models.py | 40 +++- common/djangoapps/student/views.py | 21 +- lms/templates/signup_modal.html | 41 ++-- 4 files changed, 242 insertions(+), 48 deletions(-) create mode 100644 common/djangoapps/student/migrations/0016_create_approved_demographic_fields_fall_2012.py diff --git a/common/djangoapps/student/migrations/0016_create_approved_demographic_fields_fall_2012.py b/common/djangoapps/student/migrations/0016_create_approved_demographic_fields_fall_2012.py new file mode 100644 index 0000000000..d9bb666b65 --- /dev/null +++ b/common/djangoapps/student/migrations/0016_create_approved_demographic_fields_fall_2012.py @@ -0,0 +1,188 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Deleting field 'UserProfile.occupation' + db.delete_column('auth_userprofile', 'occupation') + + # Deleting field 'UserProfile.telephone_number' + db.delete_column('auth_userprofile', 'telephone_number') + + # Deleting field 'UserProfile.date_of_birth' + db.delete_column('auth_userprofile', 'date_of_birth') + + # Deleting field 'UserProfile.country' + db.delete_column('auth_userprofile', 'country') + + # Adding field 'UserProfile.year_of_birth' + db.add_column('auth_userprofile', 'year_of_birth', + self.gf('django.db.models.fields.IntegerField')(db_index=True, null=True, blank=True), + keep_default=False) + + # Adding field 'UserProfile.level_of_education' + db.add_column('auth_userprofile', 'level_of_education', + self.gf('django.db.models.fields.CharField')(db_index=True, max_length=6, null=True, blank=True), + keep_default=False) + + # Adding field 'UserProfile.goals' + db.add_column('auth_userprofile', 'goals', + self.gf('django.db.models.fields.TextField')(null=True, blank=True), + keep_default=False) + + # Adding index on 'UserProfile', fields ['gender'] + db.create_index('auth_userprofile', ['gender']) + + + def backwards(self, orm): + # Removing index on 'UserProfile', fields ['gender'] + db.delete_index('auth_userprofile', ['gender']) + + # Adding field 'UserProfile.occupation' + db.add_column('auth_userprofile', 'occupation', + self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True), + keep_default=False) + + # Adding field 'UserProfile.telephone_number' + db.add_column('auth_userprofile', 'telephone_number', + self.gf('django.db.models.fields.CharField')(max_length=25, null=True, blank=True), + keep_default=False) + + # Adding field 'UserProfile.date_of_birth' + db.add_column('auth_userprofile', 'date_of_birth', + self.gf('django.db.models.fields.DateField')(null=True, blank=True), + keep_default=False) + + # Adding field 'UserProfile.country' + db.add_column('auth_userprofile', 'country', + self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True), + keep_default=False) + + # Deleting field 'UserProfile.year_of_birth' + db.delete_column('auth_userprofile', 'year_of_birth') + + # Deleting field 'UserProfile.level_of_education' + db.delete_column('auth_userprofile', 'level_of_education') + + # Deleting field 'UserProfile.goals' + db.delete_column('auth_userprofile', 'goals') + + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'about': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'avatar_type': ('django.db.models.fields.CharField', [], {'default': "'n'", 'max_length': '1'}), + 'bronze': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'consecutive_days_visit_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'country': ('django_countries.fields.CountryField', [], {'max_length': '2', 'blank': 'True'}), + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'display_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'email_isvalid': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'email_key': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}), + 'email_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'gold': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'gravatar': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ignored_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'interesting_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'last_seen': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'location': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), + 'new_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'questions_per_page': ('django.db.models.fields.SmallIntegerField', [], {'default': '10'}), + 'real_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), + 'reputation': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}), + 'seen_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'show_country': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'silver': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'w'", 'max_length': '2'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}), + 'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'student.courseenrollment': { + 'Meta': {'unique_together': "(('user', 'course_id'),)", 'object_name': 'CourseEnrollment'}, + 'course_id': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + }, + 'student.pendingemailchange': { + 'Meta': {'object_name': 'PendingEmailChange'}, + 'activation_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32', 'db_index': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'new_email': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'}) + }, + 'student.pendingnamechange': { + 'Meta': {'object_name': 'PendingNameChange'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'new_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'rationale': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'}) + }, + 'student.registration': { + 'Meta': {'object_name': 'Registration', 'db_table': "'auth_registration'"}, + 'activation_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32', 'db_index': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + }, + 'student.userprofile': { + 'Meta': {'object_name': 'UserProfile', 'db_table': "'auth_userprofile'"}, + 'courseware': ('django.db.models.fields.CharField', [], {'default': "'course.xml'", 'max_length': '255', 'blank': 'True'}), + 'gender': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '6', 'null': 'True', 'blank': 'True'}), + 'goals': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}), + 'level_of_education': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '6', 'null': 'True', 'blank': 'True'}), + 'location': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}), + 'mailing_address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'meta': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'profile'", 'unique': 'True', 'to': "orm['auth.User']"}), + 'year_of_birth': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}) + }, + 'student.usertestgroup': { + 'Meta': {'object_name': 'UserTestGroup'}, + 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}), + 'users': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.User']", 'db_index': 'True', 'symmetrical': 'False'}) + } + } + + complete_apps = ['student'] \ No newline at end of file diff --git a/common/djangoapps/student/models.py b/common/djangoapps/student/models.py index f58b5ee754..bab39f2ad3 100644 --- a/common/djangoapps/student/models.py +++ b/common/djangoapps/student/models.py @@ -5,8 +5,8 @@ If you make changes to this model, be sure to create an appropriate migration file and check it in at the same time as your model changes. To do that, 1. Go to the mitx dir -2. ./manage.py schemamigration user --auto description_of_your_change -3. Add the migration file created in mitx/courseware/migrations/ +2. django-admin.py schemamigration student --auto --settings=lms.envs.dev --pythonpath=. description_of_your_change +3. Add the migration file created in mitx/common/djangoapps/student/migrations/ """ import uuid @@ -21,23 +21,41 @@ class UserProfile(models.Model): class Meta: db_table = "auth_userprofile" - GENDER_CHOICES = (('m', 'Male'), ('f', 'Female'), ('o', 'Other')) - ## CRITICAL TODO/SECURITY # Sanitize all fields. # This is not visible to other users, but could introduce holes later user = models.OneToOneField(User, unique=True, db_index=True, related_name='profile') name = models.CharField(blank=True, max_length=255, db_index=True) - language = models.CharField(blank=True, max_length=255, db_index=True) - location = models.CharField(blank=True, max_length=255, db_index=True) # TODO: What are we doing with this? + meta = models.TextField(blank=True) # JSON dictionary for future expansion courseware = models.CharField(blank=True, max_length=255, default='course.xml') - gender = models.CharField(blank=True, null=True, max_length=6, choices=GENDER_CHOICES) - date_of_birth = models.DateField(blank=True, null=True) + + # Location is no longer used, but is held here for backwards compatibility + # for users imported from our first class. + language = models.CharField(blank=True, max_length=255, db_index=True) + location = models.CharField(blank=True, max_length=255, db_index=True) + + # Optional demographic data we started capturing from Fall 2012 + year_of_birth = models.IntegerField(blank=True, null=True, db_index=True) + GENDER_CHOICES = (('m', 'Male'), ('f', 'Female'), ('o', 'Other')) + gender = models.CharField(blank=True, null=True, max_length=6, db_index=True, + choices=GENDER_CHOICES) + LEVEL_OF_EDUCATION_CHOICES = (('p_se', 'Doctorate in science or engineering'), + ('p_oth', 'Doctorate in another field'), + ('m', "Master's or professional degree"), + ('b', "Master's or professional degree"), + ('hs', "Secondary/high school"), + ('jhs', "Junior secondary/junior high/middle school"), + ('el', "Elementary/primary school"), + ('none', "None"), + ('other', "Other")) + level_of_education = models.CharField( + blank=True, null=True, max_length=6, db_index=True, + choices=LEVEL_OF_EDUCATION_CHOICES + ) mailing_address = models.TextField(blank=True, null=True) - country = CountryField(blank=True, null=True) - telephone_number = models.CharField(blank=True, null=True, max_length=25) - occupation = models.CharField(blank=True, null=True, max_length=255) + goals = models.TextField(blank=True, null=True) + def get_meta(self): js_str = self.meta diff --git a/common/djangoapps/student/views.py b/common/djangoapps/student/views.py index 9d2ea93049..8748dec062 100644 --- a/common/djangoapps/student/views.py +++ b/common/djangoapps/student/views.py @@ -243,17 +243,20 @@ def create_account(request, post_override=None): up = UserProfile(user=u) up.name = post_vars['name'] - up.country = post_vars['country'] + up.level_of_education = post_vars['level_of_education'] up.gender = post_vars['gender'] up.mailing_address = post_vars['mailing_address'] - - date_fields = ['date_of_birth__year', 'date_of_birth__month', 'date_of_birth__day'] - if all(len(post_vars[field]) > 0 for field in date_fields): - up.date_of_birth = date(int(post_vars['date_of_birth__year']), - int(post_vars['date_of_birth__month']), - int(post_vars['date_of_birth__day'])) - - up.save() + up.goals = post_vars['goals'] + + try: + up.year_of_birth = int(post_vars['year_of_birth']) + except ValueError: + up.year_of_birth = None # If they give us garbage, just ignore it instead + # of asking them to put an integer. + try: + up.save() + except Exception: + log.exception("UserProfile creation failed for user {0}.".format(u.id)) d = {'name': post_vars['name'], 'key': r.activation_key, diff --git a/lms/templates/signup_modal.html b/lms/templates/signup_modal.html index 7c14778adc..4e29b86138 100644 --- a/lms/templates/signup_modal.html +++ b/lms/templates/signup_modal.html @@ -27,18 +27,16 @@ - -
- +
- - %for country_code, country_name in COUNTRIES: - + %for code, ed_level in UserProfile.LEVEL_OF_EDUCATION_CHOICES: + %endfor
@@ -56,31 +54,18 @@
-
- +
+
- - - - - +
+ + + + + +