From 1540f9ec7259da1c80b06681bbf116c7e7f1cde0 Mon Sep 17 00:00:00 2001 From: Tyler Hallada Date: Tue, 5 Jun 2018 16:03:57 -0400 Subject: [PATCH] Add on_delete kwarg to ForeignKey & OneToOneFields Django 2.0 will make this field required for `ForeignKey` and `OneToOneFields`. In previous versions the option defaulted to `models.CASCADE` when not specified. This change should make the deprecation warnings in the current Django version go away. The migrations where also modified, but the changes should not cause a change in the database schema since `models.CASCADE` was already the old default. --- .../migrations/0001_initial.py | 2 +- cms/djangoapps/course_creators/models.py | 2 +- .../xblock/tagging/migrations/0001_initial.py | 2 +- cms/lib/xblock/tagging/models.py | 2 +- .../0008_course_key_field_to_foreign_key.py | 2 +- common/djangoapps/course_modes/models.py | 1 + .../entitlements/migrations/0001_initial.py | 4 +- .../migrations/0002_auto_20171102_0719.py | 2 +- .../migrations/0003_auto_20171205_1431.py | 6 +-- .../0005_courseentitlementsupportdetail.py | 6 +-- .../migrations/0008_auto_20180328_1107.py | 2 +- common/djangoapps/entitlements/models.py | 14 ++--- .../migrations/0001_initial.py | 8 +-- .../migrations/0002_auto_20160202_0228.py | 2 +- .../microsite_configuration/models.py | 8 +-- .../status/migrations/0001_initial.py | 2 +- common/djangoapps/status/models.py | 2 +- .../student/migrations/0001_initial.py | 34 ++++++------ .../migrations/0003_auto_20160516_0938.py | 2 +- .../0011_course_key_field_to_foreign_key.py | 2 +- .../student/migrations/0012_sociallink.py | 2 +- .../0014_courseenrollmentallowed_user.py | 2 +- common/djangoapps/student/models.py | 43 ++++++++------- .../migrations/0001_initial.py | 2 +- .../migrations/0005_add_site_field.py | 12 +++-- common/djangoapps/third_party_auth/models.py | 4 +- .../badges/migrations/0001_initial.py | 4 +- lms/djangoapps/badges/models.py | 4 +- .../bulk_email/migrations/0001_initial.py | 4 +- .../migrations/0004_add_email_targets.py | 4 +- .../migrations/0006_course_mode_targets.py | 4 +- lms/djangoapps/bulk_email/models.py | 8 +-- lms/djangoapps/ccx/migrations/0001_initial.py | 4 +- lms/djangoapps/ccx/models.py | 4 +- .../certificates/migrations/0001_initial.py | 8 +-- .../0004_certificategenerationhistory.py | 4 +- .../0007_certificateinvalidation.py | 4 +- lms/djangoapps/certificates/models.py | 14 ++--- .../course_goals/migrations/0001_initial.py | 2 +- lms/djangoapps/course_goals/models.py | 2 +- .../courseware/migrations/0001_initial.py | 12 ++--- lms/djangoapps/courseware/models.py | 12 ++--- .../experiments/migrations/0001_initial.py | 2 +- lms/djangoapps/experiments/models.py | 2 +- .../grades/migrations/0001_initial.py | 2 +- lms/djangoapps/grades/models.py | 3 +- .../migrations/0001_initial.py | 2 +- lms/djangoapps/instructor_task/models.py | 2 +- .../lti_provider/migrations/0001_initial.py | 10 ++-- lms/djangoapps/lti_provider/models.py | 10 ++-- .../notes/migrations/0001_initial.py | 2 +- lms/djangoapps/notes/models.py | 2 +- .../shoppingcart/migrations/0001_initial.py | 54 +++++++++---------- lms/djangoapps/shoppingcart/models.py | 44 +++++++-------- .../survey/migrations/0001_initial.py | 4 +- lms/djangoapps/survey/models.py | 4 +- .../teams/migrations/0001_initial.py | 4 +- lms/djangoapps/teams/models.py | 4 +- .../verify_student/migrations/0001_initial.py | 14 ++--- lms/djangoapps/verify_student/models.py | 7 +-- .../api_admin/migrations/0001_initial.py | 2 +- .../migrations/0003_auto_20160404_1618.py | 2 +- .../migrations/0004_auto_20160412_1506.py | 2 +- .../migrations/0005_auto_20160414_1232.py | 2 +- openedx/core/djangoapps/api_admin/models.py | 4 +- .../bookmarks/migrations/0001_initial.py | 4 +- openedx/core/djangoapps/bookmarks/models.py | 4 +- .../migrations/0001_initial.py | 2 +- .../migrations/0006_courseoverviewimageset.py | 2 +- .../content/course_overviews/models.py | 5 +- .../course_groups/migrations/0001_initial.py | 8 +-- .../migrations/0003_auto_20170609_1455.py | 2 +- .../core/djangoapps/course_groups/models.py | 11 ++-- .../credit/migrations/0001_initial.py | 10 ++-- openedx/core/djangoapps/credit/models.py | 10 ++-- .../embargo/migrations/0001_initial.py | 4 +- openedx/core/djangoapps/embargo/models.py | 6 ++- .../external_auth/migrations/0001_initial.py | 2 +- .../core/djangoapps/external_auth/models.py | 2 +- .../oauth_dispatch/migrations/0001_initial.py | 2 +- .../core/djangoapps/oauth_dispatch/models.py | 2 +- .../schedules/migrations/0001_initial.py | 2 +- .../migrations/0003_scheduleconfig.py | 2 +- .../migrations/0006_scheduleexperience.py | 2 +- openedx/core/djangoapps/schedules/models.py | 6 +-- .../migrations/0001_initial.py | 4 +- .../djangoapps/site_configuration/models.py | 4 +- .../theming/migrations/0001_initial.py | 2 +- openedx/core/djangoapps/theming/models.py | 2 +- .../user_api/migrations/0001_initial.py | 6 +-- openedx/core/djangoapps/user_api/models.py | 14 ++--- 91 files changed, 293 insertions(+), 275 deletions(-) diff --git a/cms/djangoapps/course_creators/migrations/0001_initial.py b/cms/djangoapps/course_creators/migrations/0001_initial.py index db668d83a8..f515699d09 100644 --- a/cms/djangoapps/course_creators/migrations/0001_initial.py +++ b/cms/djangoapps/course_creators/migrations/0001_initial.py @@ -19,7 +19,7 @@ class Migration(migrations.Migration): ('state_changed', models.DateTimeField(help_text='The date when state was last updated', verbose_name=b'state last updated', auto_now_add=True)), ('state', models.CharField(default=b'unrequested', help_text='Current course creator state', max_length=24, choices=[(b'unrequested', 'unrequested'), (b'pending', 'pending'), (b'granted', 'granted'), (b'denied', 'denied')])), ('note', models.CharField(help_text='Optional notes about this user (for example, why course creation access was denied)', max_length=512, blank=True)), - ('user', models.OneToOneField(to=settings.AUTH_USER_MODEL, help_text='Studio user')), + ('user', models.OneToOneField(to=settings.AUTH_USER_MODEL, help_text='Studio user', on_delete=models.CASCADE)), ], ), ] diff --git a/cms/djangoapps/course_creators/models.py b/cms/djangoapps/course_creators/models.py index bec2da645e..92f7f60bca 100644 --- a/cms/djangoapps/course_creators/models.py +++ b/cms/djangoapps/course_creators/models.py @@ -35,7 +35,7 @@ class CourseCreator(models.Model): (DENIED, _(u'denied')), ) - user = models.OneToOneField(User, help_text=_("Studio user")) + user = models.OneToOneField(User, help_text=_("Studio user"), on_delete=models.CASCADE) state_changed = models.DateTimeField('state last updated', auto_now_add=True, help_text=_("The date when state was last updated")) state = models.CharField(max_length=24, blank=False, choices=STATES, default=UNREQUESTED, diff --git a/cms/lib/xblock/tagging/migrations/0001_initial.py b/cms/lib/xblock/tagging/migrations/0001_initial.py index a0d86d97ac..dc0d525ead 100644 --- a/cms/lib/xblock/tagging/migrations/0001_initial.py +++ b/cms/lib/xblock/tagging/migrations/0001_initial.py @@ -34,6 +34,6 @@ class Migration(migrations.Migration): migrations.AddField( model_name='tagavailablevalues', name='category', - field=models.ForeignKey(to='tagging.TagCategories'), + field=models.ForeignKey(to='tagging.TagCategories', on_delete=models.CASCADE), ), ] diff --git a/cms/lib/xblock/tagging/models.py b/cms/lib/xblock/tagging/models.py index e4a4a7d9b6..7406217903 100644 --- a/cms/lib/xblock/tagging/models.py +++ b/cms/lib/xblock/tagging/models.py @@ -31,7 +31,7 @@ class TagAvailableValues(models.Model): """ This model represents available values for tags. """ - category = models.ForeignKey(TagCategories, db_index=True) + category = models.ForeignKey(TagCategories, db_index=True, on_delete=models.CASCADE) value = models.CharField(max_length=255) class Meta(object): diff --git a/common/djangoapps/course_modes/migrations/0008_course_key_field_to_foreign_key.py b/common/djangoapps/course_modes/migrations/0008_course_key_field_to_foreign_key.py index 9b3ff686c4..75cb8ed0d7 100644 --- a/common/djangoapps/course_modes/migrations/0008_course_key_field_to_foreign_key.py +++ b/common/djangoapps/course_modes/migrations/0008_course_key_field_to_foreign_key.py @@ -45,7 +45,7 @@ class Migration(migrations.Migration): NoSqlAlterField( model_name='coursemode', name='course', - field=models.ForeignKey(related_name='modes', db_constraint=False, default=None, to='course_overviews.CourseOverview'), + field=models.ForeignKey(related_name='modes', db_constraint=False, default=None, to='course_overviews.CourseOverview', on_delete=models.CASCADE), preserve_default=False, ), # Change the Django unique-together constraint (this is Django-level only diff --git a/common/djangoapps/course_modes/models.py b/common/djangoapps/course_modes/models.py index 6d9b40e417..7a03b4c196 100644 --- a/common/djangoapps/course_modes/models.py +++ b/common/djangoapps/course_modes/models.py @@ -46,6 +46,7 @@ class CourseMode(models.Model): db_constraint=False, db_index=True, related_name='modes', + on_delete=models.CASCADE, ) # Django sets the `course_id` property in __init__ with the value from the database diff --git a/common/djangoapps/entitlements/migrations/0001_initial.py b/common/djangoapps/entitlements/migrations/0001_initial.py index af7d5b9407..0a85807671 100644 --- a/common/djangoapps/entitlements/migrations/0001_initial.py +++ b/common/djangoapps/entitlements/migrations/0001_initial.py @@ -27,8 +27,8 @@ class Migration(migrations.Migration): ('expired_at', models.DateTimeField(null=True)), ('mode', models.CharField(default=b'audit', max_length=100)), ('order_number', models.CharField(max_length=128, null=True)), - ('enrollment_course_run', models.ForeignKey(to='student.CourseEnrollment', null=True)), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('enrollment_course_run', models.ForeignKey(to='student.CourseEnrollment', null=True, on_delete=models.CASCADE)), + ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], options={ 'abstract': False, diff --git a/common/djangoapps/entitlements/migrations/0002_auto_20171102_0719.py b/common/djangoapps/entitlements/migrations/0002_auto_20171102_0719.py index 2ab05153fb..0e0408136a 100644 --- a/common/djangoapps/entitlements/migrations/0002_auto_20171102_0719.py +++ b/common/djangoapps/entitlements/migrations/0002_auto_20171102_0719.py @@ -22,7 +22,7 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='courseentitlement', name='enrollment_course_run', - field=models.ForeignKey(to='student.CourseEnrollment', help_text=b'The current Course enrollment for this entitlement. If NULL the Learner has not enrolled.', null=True), + field=models.ForeignKey(to='student.CourseEnrollment', help_text=b'The current Course enrollment for this entitlement. If NULL the Learner has not enrolled.', null=True, on_delete=models.CASCADE), ), migrations.AlterField( model_name='courseentitlement', diff --git a/common/djangoapps/entitlements/migrations/0003_auto_20171205_1431.py b/common/djangoapps/entitlements/migrations/0003_auto_20171205_1431.py index 6e9fe2dadf..908dca1e31 100644 --- a/common/djangoapps/entitlements/migrations/0003_auto_20171205_1431.py +++ b/common/djangoapps/entitlements/migrations/0003_auto_20171205_1431.py @@ -20,13 +20,13 @@ class Migration(migrations.Migration): ('expiration_period', models.DurationField(default=datetime.timedelta(450), help_text=b'Duration in days from when an entitlement is created until when it is expired.')), ('refund_period', models.DurationField(default=datetime.timedelta(60), help_text=b'Duration in days from when an entitlement is created until when it is no longer refundable')), ('regain_period', models.DurationField(default=datetime.timedelta(14), help_text=b'Duration in days from when an entitlement is redeemed for a course run until it is no longer able to be regained by a user.')), - ('site', models.ForeignKey(to='sites.Site')), + ('site', models.ForeignKey(to='sites.Site', on_delete=models.CASCADE)), ], ), migrations.AlterField( model_name='courseentitlement', name='enrollment_course_run', - field=models.ForeignKey(blank=True, to='student.CourseEnrollment', help_text=b'The current Course enrollment for this entitlement. If NULL the Learner has not enrolled.', null=True), + field=models.ForeignKey(blank=True, to='student.CourseEnrollment', help_text=b'The current Course enrollment for this entitlement. If NULL the Learner has not enrolled.', null=True, on_delete=models.CASCADE), ), migrations.AlterField( model_name='courseentitlement', @@ -36,6 +36,6 @@ class Migration(migrations.Migration): migrations.AddField( model_name='courseentitlement', name='_policy', - field=models.ForeignKey(blank=True, to='entitlements.CourseEntitlementPolicy', null=True), + field=models.ForeignKey(blank=True, to='entitlements.CourseEntitlementPolicy', null=True, on_delete=models.CASCADE), ), ] diff --git a/common/djangoapps/entitlements/migrations/0005_courseentitlementsupportdetail.py b/common/djangoapps/entitlements/migrations/0005_courseentitlementsupportdetail.py index 3dc823cfa0..d3d917eb2b 100644 --- a/common/djangoapps/entitlements/migrations/0005_courseentitlementsupportdetail.py +++ b/common/djangoapps/entitlements/migrations/0005_courseentitlementsupportdetail.py @@ -24,9 +24,9 @@ class Migration(migrations.Migration): ('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)), ('reason', models.CharField(max_length=15, choices=[(b'LEAVE', 'Learner requested leave session for expired entitlement'), (b'CHANGE', 'Learner requested session change for expired entitlement'), (b'LEARNER_NEW', 'Learner requested new entitlement'), (b'COURSE_TEAM_NEW', 'Course team requested entitlement for learnerg'), (b'OTHER', 'Other')])), ('comments', models.TextField(null=True)), - ('entitlement', models.ForeignKey(to='entitlements.CourseEntitlement')), - ('support_user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), - ('unenrolled_run', models.ForeignKey(db_constraint=False, blank=True, to='course_overviews.CourseOverview', null=True)), + ('entitlement', models.ForeignKey(to='entitlements.CourseEntitlement', on_delete=models.CASCADE)), + ('support_user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), + ('unenrolled_run', models.ForeignKey(db_constraint=False, blank=True, to='course_overviews.CourseOverview', null=True, on_delete=models.CASCADE)), ], options={ 'abstract': False, diff --git a/common/djangoapps/entitlements/migrations/0008_auto_20180328_1107.py b/common/djangoapps/entitlements/migrations/0008_auto_20180328_1107.py index 5e602194b1..f3186f4665 100644 --- a/common/djangoapps/entitlements/migrations/0008_auto_20180328_1107.py +++ b/common/djangoapps/entitlements/migrations/0008_auto_20180328_1107.py @@ -19,6 +19,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='courseentitlementpolicy', name='site', - field=models.ForeignKey(to='sites.Site', null=True), + field=models.ForeignKey(to='sites.Site', null=True, on_delete=models.CASCADE), ), ] diff --git a/common/djangoapps/entitlements/models.py b/common/djangoapps/entitlements/models.py index 9705b70153..bf2f3cd979 100644 --- a/common/djangoapps/entitlements/models.py +++ b/common/djangoapps/entitlements/models.py @@ -49,7 +49,7 @@ class CourseEntitlementPolicy(models.Model): "it is no longer able to be regained by a user."), null=False ) - site = models.ForeignKey(Site, null=True) + site = models.ForeignKey(Site, null=True, on_delete=models.CASCADE) mode = models.CharField(max_length=32, choices=MODES, null=True) def get_days_until_expiration(self, entitlement): @@ -146,7 +146,7 @@ class CourseEntitlement(TimeStampedModel): """ Represents a Student's Entitlement to a Course Run for a given Course. """ - user = models.ForeignKey(settings.AUTH_USER_MODEL) + user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) uuid = models.UUIDField(default=uuid_tools.uuid4, editable=False, unique=True) course_uuid = models.UUIDField(help_text='UUID for the Course, not the Course Run') expired_at = models.DateTimeField( @@ -159,11 +159,12 @@ class CourseEntitlement(TimeStampedModel): 'student.CourseEnrollment', null=True, help_text='The current Course enrollment for this entitlement. If NULL the Learner has not enrolled.', - blank=True + blank=True, + on_delete=models.CASCADE, ) order_number = models.CharField(max_length=128, null=True) refund_locked = models.BooleanField(default=False) - _policy = models.ForeignKey(CourseEntitlementPolicy, null=True, blank=True) + _policy = models.ForeignKey(CourseEntitlementPolicy, null=True, blank=True, on_delete=models.CASCADE) @property def expired_at_datetime(self): @@ -429,8 +430,8 @@ class CourseEntitlementSupportDetail(TimeStampedModel): (CREATE, 'Create new entitlement'), ) - entitlement = models.ForeignKey('entitlements.CourseEntitlement') - support_user = models.ForeignKey(settings.AUTH_USER_MODEL) + entitlement = models.ForeignKey('entitlements.CourseEntitlement', on_delete=models.CASCADE) + support_user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) #Deprecated: use action instead. reason = models.CharField(max_length=15, choices=ENTITLEMENT_SUPPORT_REASONS) @@ -443,6 +444,7 @@ class CourseEntitlementSupportDetail(TimeStampedModel): null=True, blank=True, db_constraint=False, + on_delete=models.CASCADE, ) def __unicode__(self): diff --git a/common/djangoapps/microsite_configuration/migrations/0001_initial.py b/common/djangoapps/microsite_configuration/migrations/0001_initial.py index 3e005e355d..2a12da189e 100644 --- a/common/djangoapps/microsite_configuration/migrations/0001_initial.py +++ b/common/djangoapps/microsite_configuration/migrations/0001_initial.py @@ -56,7 +56,7 @@ class Migration(migrations.Migration): ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('key', models.CharField(unique=True, max_length=63, db_index=True)), ('values', jsonfield.fields.JSONField(blank=True)), - ('site', models.OneToOneField(related_name='microsite', to='sites.Site')), + ('site', models.OneToOneField(related_name='microsite', to='sites.Site', on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -67,7 +67,7 @@ class Migration(migrations.Migration): ('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)), ('key', models.CharField(unique=True, max_length=63, db_index=True)), ('values', jsonfield.fields.JSONField(blank=True)), - ('site', models.OneToOneField(related_name='microsite_history', to='sites.Site')), + ('site', models.OneToOneField(related_name='microsite_history', to='sites.Site', on_delete=models.CASCADE)), ], options={ 'verbose_name_plural': 'Microsite histories', @@ -78,7 +78,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('organization', models.CharField(unique=True, max_length=63, db_index=True)), - ('microsite', models.ForeignKey(to='microsite_configuration.Microsite')), + ('microsite', models.ForeignKey(to='microsite_configuration.Microsite', on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -87,7 +87,7 @@ class Migration(migrations.Migration): ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('template_uri', models.CharField(max_length=255, db_index=True)), ('template', models.TextField()), - ('microsite', models.ForeignKey(to='microsite_configuration.Microsite')), + ('microsite', models.ForeignKey(to='microsite_configuration.Microsite', on_delete=models.CASCADE)), ], ), migrations.AddField( diff --git a/common/djangoapps/microsite_configuration/migrations/0002_auto_20160202_0228.py b/common/djangoapps/microsite_configuration/migrations/0002_auto_20160202_0228.py index 32cc30da01..e85078e583 100644 --- a/common/djangoapps/microsite_configuration/migrations/0002_auto_20160202_0228.py +++ b/common/djangoapps/microsite_configuration/migrations/0002_auto_20160202_0228.py @@ -19,6 +19,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='micrositehistory', name='site', - field=models.ForeignKey(related_name='microsite_history', to='sites.Site'), + field=models.ForeignKey(related_name='microsite_history', to='sites.Site', on_delete=models.CASCADE), ), ] diff --git a/common/djangoapps/microsite_configuration/models.py b/common/djangoapps/microsite_configuration/models.py index 01576b8d9b..bc2f7bbecb 100644 --- a/common/djangoapps/microsite_configuration/models.py +++ b/common/djangoapps/microsite_configuration/models.py @@ -29,7 +29,7 @@ class Microsite(models.Model): - The values field must be validated on save to prevent the platform from crashing badly in the case the string is not able to be loaded as json. """ - site = models.OneToOneField(Site, related_name='microsite') + site = models.OneToOneField(Site, related_name='microsite', on_delete=models.CASCADE) key = models.CharField(max_length=63, db_index=True, unique=True) values = JSONField(null=False, blank=True, load_kwargs={'object_pairs_hook': collections.OrderedDict}) @@ -61,7 +61,7 @@ class MicrositeHistory(TimeStampedModel): This is an archive table for Microsites model, so that we can maintain a history of changes. Note that the key field is no longer unique """ - site = models.ForeignKey(Site, related_name='microsite_history') + site = models.ForeignKey(Site, related_name='microsite_history', on_delete=models.CASCADE) key = models.CharField(max_length=63, db_index=True) values = JSONField(null=False, blank=True, load_kwargs={'object_pairs_hook': collections.OrderedDict}) @@ -112,7 +112,7 @@ class MicrositeOrganizationMapping(models.Model): """ organization = models.CharField(max_length=63, db_index=True, unique=True) - microsite = models.ForeignKey(Microsite, db_index=True) + microsite = models.ForeignKey(Microsite, db_index=True, on_delete=models.CASCADE) def __unicode__(self): """String conversion""" @@ -147,7 +147,7 @@ class MicrositeTemplate(models.Model): A HTML template that a microsite can use """ - microsite = models.ForeignKey(Microsite, db_index=True) + microsite = models.ForeignKey(Microsite, db_index=True, on_delete=models.CASCADE) template_uri = models.CharField(max_length=255, db_index=True) template = models.TextField() diff --git a/common/djangoapps/status/migrations/0001_initial.py b/common/djangoapps/status/migrations/0001_initial.py index 75468dce8f..94d4c77b7a 100644 --- a/common/djangoapps/status/migrations/0001_initial.py +++ b/common/djangoapps/status/migrations/0001_initial.py @@ -40,6 +40,6 @@ class Migration(migrations.Migration): migrations.AddField( model_name='coursemessage', name='global_message', - field=models.ForeignKey(to='status.GlobalStatusMessage'), + field=models.ForeignKey(to='status.GlobalStatusMessage', on_delete=models.CASCADE), ), ] diff --git a/common/djangoapps/status/models.py b/common/djangoapps/status/models.py index 94dfe2fb36..42bb3117d5 100644 --- a/common/djangoapps/status/models.py +++ b/common/djangoapps/status/models.py @@ -55,7 +55,7 @@ class CourseMessage(models.Model): 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) + global_message = models.ForeignKey(GlobalStatusMessage, on_delete=models.CASCADE) course_key = CourseKeyField(max_length=255, blank=True, db_index=True) message = models.TextField(blank=True, null=True) diff --git a/common/djangoapps/student/migrations/0001_initial.py b/common/djangoapps/student/migrations/0001_initial.py index 0054d38b1c..2d4f1af201 100644 --- a/common/djangoapps/student/migrations/0001_initial.py +++ b/common/djangoapps/student/migrations/0001_initial.py @@ -22,7 +22,7 @@ class Migration(migrations.Migration): ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('anonymous_user_id', models.CharField(unique=True, max_length=32)), ('course_id', CourseKeyField(db_index=True, max_length=255, blank=True)), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -32,7 +32,7 @@ class Migration(migrations.Migration): ('org', models.CharField(db_index=True, max_length=64, blank=True)), ('course_id', CourseKeyField(db_index=True, max_length=255, blank=True)), ('role', models.CharField(max_length=64, db_index=True)), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -43,7 +43,7 @@ class Migration(migrations.Migration): ('created', models.DateTimeField(db_index=True, auto_now_add=True, null=True)), ('is_active', models.BooleanField(default=True)), ('mode', models.CharField(default=b'honor', max_length=100)), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], options={ 'ordering': ('user', 'course_id'), @@ -66,7 +66,7 @@ class Migration(migrations.Migration): ('namespace', models.CharField(help_text='Namespace of enrollment attribute', max_length=255)), ('name', models.CharField(help_text='Name of the enrollment attribute', max_length=255)), ('value', models.CharField(help_text='Value of the enrollment attribute', max_length=255)), - ('enrollment', models.ForeignKey(related_name='attributes', to='student.CourseEnrollment')), + ('enrollment', models.ForeignKey(related_name='attributes', to='student.CourseEnrollment', on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -105,7 +105,7 @@ class Migration(migrations.Migration): ('created', models.DateTimeField(db_index=True, auto_now_add=True, null=True)), ('updated', models.DateTimeField(auto_now=True, db_index=True)), ('skip_entrance_exam', models.BooleanField(default=True)), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -157,7 +157,7 @@ class Migration(migrations.Migration): ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('failure_count', models.IntegerField(default=0)), ('lockout_until', models.DateTimeField(null=True)), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -168,8 +168,8 @@ class Migration(migrations.Migration): ('time_stamp', models.DateTimeField(auto_now_add=True, null=True)), ('state_transition', models.CharField(max_length=255, choices=[(b'from unenrolled to allowed to enroll', b'from unenrolled to allowed to enroll'), (b'from allowed to enroll to enrolled', b'from allowed to enroll to enrolled'), (b'from enrolled to enrolled', b'from enrolled to enrolled'), (b'from enrolled to unenrolled', b'from enrolled to unenrolled'), (b'from unenrolled to enrolled', b'from unenrolled to enrolled'), (b'from allowed to enroll to enrolled', b'from allowed to enroll to enrolled'), (b'from unenrolled to unenrolled', b'from unenrolled to unenrolled'), (b'N/A', b'N/A')])), ('reason', models.TextField(null=True)), - ('enrolled_by', models.ForeignKey(to=settings.AUTH_USER_MODEL, null=True)), - ('enrollment', models.ForeignKey(to='student.CourseEnrollment', null=True)), + ('enrolled_by', models.ForeignKey(to=settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE)), + ('enrollment', models.ForeignKey(to='student.CourseEnrollment', null=True, on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -178,7 +178,7 @@ class Migration(migrations.Migration): ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('password', models.CharField(max_length=128)), ('time_set', models.DateTimeField(default=django.utils.timezone.now)), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -187,7 +187,7 @@ class Migration(migrations.Migration): ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('new_email', models.CharField(db_index=True, max_length=255, blank=True)), ('activation_key', models.CharField(unique=True, max_length=32, verbose_name=b'activation key', db_index=True)), - ('user', models.OneToOneField(to=settings.AUTH_USER_MODEL)), + ('user', models.OneToOneField(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -196,7 +196,7 @@ class Migration(migrations.Migration): ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('new_name', models.CharField(max_length=255, blank=True)), ('rationale', models.CharField(max_length=1024, blank=True)), - ('user', models.OneToOneField(to=settings.AUTH_USER_MODEL)), + ('user', models.OneToOneField(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -204,7 +204,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('activation_key', models.CharField(unique=True, max_length=32, verbose_name=b'activation key', db_index=True)), - ('user', models.OneToOneField(to=settings.AUTH_USER_MODEL)), + ('user', models.OneToOneField(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], options={ 'db_table': 'auth_registration', @@ -229,7 +229,7 @@ class Migration(migrations.Migration): ('allow_certificate', models.BooleanField(default=1)), ('bio', models.CharField(max_length=3000, null=True, blank=True)), ('profile_image_uploaded_at', models.DateTimeField(null=True)), - ('user', models.OneToOneField(related_name='profile', to=settings.AUTH_USER_MODEL)), + ('user', models.OneToOneField(related_name='profile', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], options={ 'db_table': 'auth_userprofile', @@ -240,7 +240,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('site', models.CharField(max_length=255, db_index=True)), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -249,8 +249,8 @@ class Migration(migrations.Migration): ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('account_status', models.CharField(blank=True, max_length=31, choices=[(b'disabled', 'Account Disabled'), (b'enabled', 'Account Enabled')])), ('standing_last_changed_at', models.DateTimeField(auto_now=True)), - ('changed_by', models.ForeignKey(to=settings.AUTH_USER_MODEL, blank=True)), - ('user', models.OneToOneField(related_name='standing', to=settings.AUTH_USER_MODEL)), + ('changed_by', models.ForeignKey(to=settings.AUTH_USER_MODEL, blank=True, on_delete=models.CASCADE)), + ('user', models.OneToOneField(related_name='standing', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -265,7 +265,7 @@ class Migration(migrations.Migration): migrations.AddField( model_name='languageproficiency', name='user_profile', - field=models.ForeignKey(related_name='language_proficiencies', to='student.UserProfile'), + field=models.ForeignKey(related_name='language_proficiencies', to='student.UserProfile', on_delete=models.CASCADE), ), migrations.AlterUniqueTogether( name='courseenrollmentallowed', diff --git a/common/djangoapps/student/migrations/0003_auto_20160516_0938.py b/common/djangoapps/student/migrations/0003_auto_20160516_0938.py index a15c1b7960..9d041fc6cb 100644 --- a/common/djangoapps/student/migrations/0003_auto_20160516_0938.py +++ b/common/djangoapps/student/migrations/0003_auto_20160516_0938.py @@ -23,7 +23,7 @@ class Migration(migrations.Migration): ('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)), ('name', models.CharField(help_text='Name of this user attribute.', max_length=255)), ('value', models.CharField(help_text='Value of this user attribute.', max_length=255)), - ('user', models.ForeignKey(related_name='attributes', to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(related_name='attributes', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.AlterUniqueTogether( diff --git a/common/djangoapps/student/migrations/0011_course_key_field_to_foreign_key.py b/common/djangoapps/student/migrations/0011_course_key_field_to_foreign_key.py index ec4d0b8ad5..0724f0d7ae 100644 --- a/common/djangoapps/student/migrations/0011_course_key_field_to_foreign_key.py +++ b/common/djangoapps/student/migrations/0011_course_key_field_to_foreign_key.py @@ -54,7 +54,7 @@ class Migration(migrations.Migration): NoSqlAlterField( model_name='courseenrollment', name='course', - field=models.ForeignKey(db_constraint=False, to='course_overviews.CourseOverview'), + field=models.ForeignKey(db_constraint=False, to='course_overviews.CourseOverview', on_delete=models.CASCADE), preserve_default=True, ), NoSqlAlterField( diff --git a/common/djangoapps/student/migrations/0012_sociallink.py b/common/djangoapps/student/migrations/0012_sociallink.py index 9e98824b63..b81df8ddc9 100644 --- a/common/djangoapps/student/migrations/0012_sociallink.py +++ b/common/djangoapps/student/migrations/0012_sociallink.py @@ -17,7 +17,7 @@ class Migration(migrations.Migration): ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('platform', models.CharField(max_length=30)), ('social_link', models.CharField(max_length=100, blank=True)), - ('user_profile', models.ForeignKey(related_name='social_links', to='student.UserProfile')), + ('user_profile', models.ForeignKey(related_name='social_links', to='student.UserProfile', on_delete=models.CASCADE)), ], ), ] diff --git a/common/djangoapps/student/migrations/0014_courseenrollmentallowed_user.py b/common/djangoapps/student/migrations/0014_courseenrollmentallowed_user.py index 72557ddf20..8db32abbbd 100644 --- a/common/djangoapps/student/migrations/0014_courseenrollmentallowed_user.py +++ b/common/djangoapps/student/migrations/0014_courseenrollmentallowed_user.py @@ -16,6 +16,6 @@ class Migration(migrations.Migration): migrations.AddField( model_name='courseenrollmentallowed', name='user', - field=models.ForeignKey(blank=True, to=settings.AUTH_USER_MODEL, help_text="First user which enrolled in the specified course through the specified e-mail. Once set, it won't change.", null=True), + field=models.ForeignKey(blank=True, to=settings.AUTH_USER_MODEL, help_text="First user which enrolled in the specified course through the specified e-mail. Once set, it won't change.", null=True, on_delete=models.CASCADE), ), ] diff --git a/common/djangoapps/student/models.py b/common/djangoapps/student/models.py index d4acf521d0..0ae99df0fc 100644 --- a/common/djangoapps/student/models.py +++ b/common/djangoapps/student/models.py @@ -129,7 +129,7 @@ class AnonymousUserId(models.Model): objects = NoneToEmptyManager() - user = models.ForeignKey(User, db_index=True) + user = models.ForeignKey(User, db_index=True, on_delete=models.CASCADE) anonymous_user_id = models.CharField(unique=True, max_length=32) course_id = CourseKeyField(db_index=True, max_length=255, blank=True) @@ -328,11 +328,11 @@ class UserStanding(models.Model): (ACCOUNT_ENABLED, u"Account Enabled"), ) - user = models.OneToOneField(User, db_index=True, related_name='standing') + user = models.OneToOneField(User, db_index=True, related_name='standing', on_delete=models.CASCADE) account_status = models.CharField( blank=True, max_length=31, choices=USER_STANDING_CHOICES ) - changed_by = models.ForeignKey(User, blank=True) + changed_by = models.ForeignKey(User, blank=True, on_delete=models.CASCADE) standing_last_changed_at = models.DateTimeField(auto_now=True) @@ -364,7 +364,7 @@ class UserProfile(models.Model): # 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') + user = models.OneToOneField(User, unique=True, db_index=True, related_name='profile', on_delete=models.CASCADE) name = models.CharField(blank=True, max_length=255, db_index=True) meta = models.TextField(blank=True) # JSON dictionary for future expansion @@ -640,7 +640,7 @@ class UserSignupSource(models.Model): This table contains information about users registering via Micro-Sites """ - user = models.ForeignKey(User, db_index=True) + user = models.ForeignKey(User, db_index=True, on_delete=models.CASCADE) site = models.CharField(max_length=255, db_index=True) @@ -674,7 +674,7 @@ class Registration(models.Model): class Meta(object): db_table = "auth_registration" - user = models.OneToOneField(User) + user = models.OneToOneField(User, on_delete=models.CASCADE) activation_key = models.CharField(('activation key'), max_length=32, unique=True, db_index=True) def register(self, user): @@ -711,7 +711,7 @@ class Registration(models.Model): class PendingNameChange(DeletableByUserValue, models.Model): - user = models.OneToOneField(User, unique=True, db_index=True) + user = models.OneToOneField(User, unique=True, db_index=True, on_delete=models.CASCADE) new_name = models.CharField(blank=True, max_length=255) rationale = models.CharField(blank=True, max_length=1024) @@ -720,7 +720,7 @@ class PendingEmailChange(DeletableByUserValue, models.Model): """ This model keeps track of pending requested changes to a user's email address. """ - user = models.OneToOneField(User, unique=True, db_index=True) + user = models.OneToOneField(User, unique=True, db_index=True, on_delete=models.CASCADE) new_email = models.CharField(blank=True, max_length=255, db_index=True) activation_key = models.CharField(('activation key'), max_length=32, unique=True, db_index=True) @@ -752,7 +752,7 @@ class PasswordHistory(models.Model): This model will keep track of past passwords that a user has used as well as providing contraints (e.g. can't reuse passwords) """ - user = models.ForeignKey(User) + user = models.ForeignKey(User, on_delete=models.CASCADE) password = models.CharField(max_length=128) time_set = models.DateTimeField(default=timezone.now) @@ -952,7 +952,7 @@ class LoginFailures(models.Model): """ This model will keep track of failed login attempts """ - user = models.ForeignKey(User) + user = models.ForeignKey(User, on_delete=models.CASCADE) failure_count = models.IntegerField(default=0) lockout_until = models.DateTimeField(null=True) @@ -1157,11 +1157,12 @@ class CourseEnrollment(models.Model): """ MODEL_TAGS = ['course', 'is_active', 'mode'] - user = models.ForeignKey(User) + user = models.ForeignKey(User, on_delete=models.CASCADE) course = models.ForeignKey( CourseOverview, db_constraint=False, + on_delete=models.CASCADE, ) @property @@ -2093,8 +2094,8 @@ class ManualEnrollmentAudit(models.Model): """ Table for tracking which enrollments were performed through manual enrollment. """ - enrollment = models.ForeignKey(CourseEnrollment, null=True) - enrolled_by = models.ForeignKey(User, null=True) + enrollment = models.ForeignKey(CourseEnrollment, null=True, on_delete=models.CASCADE) + enrolled_by = models.ForeignKey(User, null=True, on_delete=models.CASCADE) enrolled_email = models.CharField(max_length=255, db_index=True) time_stamp = models.DateTimeField(auto_now_add=True, null=True) state_transition = models.CharField(max_length=255, choices=TRANSITION_STATES) @@ -2162,7 +2163,8 @@ class CourseEnrollmentAllowed(DeletableByUserValue, models.Model): null=True, blank=True, help_text="First user which enrolled in the specified course through the specified e-mail. " - "Once set, it won't change." + "Once set, it won't change.", + on_delete=models.CASCADE, ) created = models.DateTimeField(auto_now_add=True, null=True, db_index=True) @@ -2212,7 +2214,7 @@ class CourseAccessRole(models.Model): objects = NoneToEmptyManager() - user = models.ForeignKey(User) + user = models.ForeignKey(User, on_delete=models.CASCADE) # blank org is for global group based roles such as course creator (may be deprecated) org = models.CharField(max_length=64, db_index=True, blank=True) # blank course_id implies org wide role @@ -2575,7 +2577,7 @@ class EntranceExamConfiguration(models.Model): Represents a Student's entrance exam specific data for a single Course """ - user = models.ForeignKey(User, db_index=True) + user = models.ForeignKey(User, db_index=True, on_delete=models.CASCADE) course_id = CourseKeyField(max_length=255, db_index=True) created = models.DateTimeField(auto_now_add=True, null=True, db_index=True) updated = models.DateTimeField(auto_now=True, db_index=True) @@ -2644,7 +2646,8 @@ class LanguageProficiency(models.Model): class Meta(object): unique_together = (('code', 'user_profile'),) - user_profile = models.ForeignKey(UserProfile, db_index=True, related_name='language_proficiencies') + user_profile = models.ForeignKey(UserProfile, db_index=True, related_name='language_proficiencies', + on_delete=models.CASCADE) code = models.CharField( max_length=16, blank=False, @@ -2663,7 +2666,7 @@ class SocialLink(models.Model): # pylint: disable=model-missing-unicode The stored social_link value must adhere to the form 'https://www.[url_stub][username]'. """ - user_profile = models.ForeignKey(UserProfile, db_index=True, related_name='social_links') + user_profile = models.ForeignKey(UserProfile, db_index=True, related_name='social_links', on_delete=models.CASCADE) platform = models.CharField(max_length=30) social_link = models.CharField(max_length=100, blank=True) @@ -2672,7 +2675,7 @@ class CourseEnrollmentAttribute(models.Model): """ Provide additional information about the user's enrollment. """ - enrollment = models.ForeignKey(CourseEnrollment, related_name="attributes") + enrollment = models.ForeignKey(CourseEnrollment, related_name="attributes", on_delete=models.CASCADE) namespace = models.CharField( max_length=255, help_text=_("Namespace of enrollment attribute") @@ -2801,7 +2804,7 @@ class UserAttribute(TimeStampedModel): # Ensure that at most one value exists for a given user/name. unique_together = (('user', 'name',), ) - user = models.ForeignKey(User, related_name='attributes') + user = models.ForeignKey(User, related_name='attributes', on_delete=models.CASCADE) name = models.CharField(max_length=255, help_text=_("Name of this user attribute."), db_index=True) value = models.CharField(max_length=255, help_text=_("Value of this user attribute.")) diff --git a/common/djangoapps/third_party_auth/migrations/0001_initial.py b/common/djangoapps/third_party_auth/migrations/0001_initial.py index a476ab75a5..1cad33a686 100644 --- a/common/djangoapps/third_party_auth/migrations/0001_initial.py +++ b/common/djangoapps/third_party_auth/migrations/0001_initial.py @@ -64,7 +64,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('provider_id', models.CharField(help_text=b'Uniquely identify a provider. This is different from backend_name.', max_length=255)), - ('client', models.ForeignKey(to='oauth2.Client')), + ('client', models.ForeignKey(to='oauth2.Client', on_delete=models.CASCADE)), ], options={ 'verbose_name': 'Provider API Permission', diff --git a/common/djangoapps/third_party_auth/migrations/0005_add_site_field.py b/common/djangoapps/third_party_auth/migrations/0005_add_site_field.py index b02d39568f..75cdbcec25 100644 --- a/common/djangoapps/third_party_auth/migrations/0005_add_site_field.py +++ b/common/djangoapps/third_party_auth/migrations/0005_add_site_field.py @@ -41,7 +41,8 @@ class Migration(migrations.Migration): related_name='ltiproviderconfigs', default=settings.SITE_ID, to='sites.Site', - help_text='The Site that this provider configuration belongs to.' + help_text='The Site that this provider configuration belongs to.', + on_delete=models.CASCADE, ), ), migrations.AddField( @@ -51,7 +52,8 @@ class Migration(migrations.Migration): related_name='oauth2providerconfigs', default=settings.SITE_ID, to='sites.Site', - help_text='The Site that this provider configuration belongs to.' + help_text='The Site that this provider configuration belongs to.', + on_delete=models.CASCADE, ), ), migrations.AddField( @@ -61,7 +63,8 @@ class Migration(migrations.Migration): related_name='samlproviderconfigs', default=settings.SITE_ID, to='sites.Site', - help_text='The Site that this provider configuration belongs to.' + help_text='The Site that this provider configuration belongs to.', + on_delete=models.CASCADE, ), ), migrations.AddField( @@ -71,7 +74,8 @@ class Migration(migrations.Migration): related_name='samlconfigurations', default=settings.SITE_ID, to='sites.Site', - help_text='The Site that this SAML configuration belongs to.' + help_text='The Site that this SAML configuration belongs to.', + on_delete=models.CASCADE, ), ), ] diff --git a/common/djangoapps/third_party_auth/models.py b/common/djangoapps/third_party_auth/models.py index c25d6fbf19..920eab66e6 100644 --- a/common/djangoapps/third_party_auth/models.py +++ b/common/djangoapps/third_party_auth/models.py @@ -131,6 +131,7 @@ class ProviderConfig(ConfigurationModel): help_text=_( 'The Site that this provider configuration belongs to.' ), + on_delete=models.CASCADE, ) skip_hinted_login_dialog = models.BooleanField( default=False, @@ -390,6 +391,7 @@ class SAMLConfiguration(ConfigurationModel): help_text=_( 'The Site that this SAML configuration belongs to.' ), + on_delete=models.CASCADE, ) slug = models.SlugField( max_length=30, @@ -812,7 +814,7 @@ class ProviderApiPermissions(models.Model): It gives permission for a OAuth2 client to access the information under certain IdPs. """ - client = models.ForeignKey(Client) + client = models.ForeignKey(Client, on_delete=models.CASCADE) provider_id = models.CharField( max_length=255, help_text=( diff --git a/lms/djangoapps/badges/migrations/0001_initial.py b/lms/djangoapps/badges/migrations/0001_initial.py index 7e3a9e29f7..d66191b57f 100644 --- a/lms/djangoapps/badges/migrations/0001_initial.py +++ b/lms/djangoapps/badges/migrations/0001_initial.py @@ -59,11 +59,11 @@ class Migration(migrations.Migration): migrations.AddField( model_name='badgeassertion', name='badge_class', - field=models.ForeignKey(to='badges.BadgeClass'), + field=models.ForeignKey(to='badges.BadgeClass', on_delete=models.CASCADE), ), migrations.AddField( model_name='badgeassertion', name='user', - field=models.ForeignKey(to=settings.AUTH_USER_MODEL), + field=models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE), ), ] diff --git a/lms/djangoapps/badges/models.py b/lms/djangoapps/badges/models.py index c2637e69ab..79709e4df5 100644 --- a/lms/djangoapps/badges/models.py +++ b/lms/djangoapps/badges/models.py @@ -141,8 +141,8 @@ class BadgeAssertion(TimeStampedModel): """ Tracks badges on our side of the badge baking transaction """ - user = models.ForeignKey(User) - badge_class = models.ForeignKey(BadgeClass) + user = models.ForeignKey(User, on_delete=models.CASCADE) + badge_class = models.ForeignKey(BadgeClass, on_delete=models.CASCADE) data = JSONField() backend = models.CharField(max_length=50) image_url = models.URLField() diff --git a/lms/djangoapps/bulk_email/migrations/0001_initial.py b/lms/djangoapps/bulk_email/migrations/0001_initial.py index 01402855c0..fdb7c68c54 100644 --- a/lms/djangoapps/bulk_email/migrations/0001_initial.py +++ b/lms/djangoapps/bulk_email/migrations/0001_initial.py @@ -35,7 +35,7 @@ class Migration(migrations.Migration): ('to_option', models.CharField(default=b'myself', max_length=64, choices=[(b'myself', b'Myself'), (b'staff', b'Staff and instructors'), (b'all', b'All')])), ('template_name', models.CharField(max_length=255, null=True)), ('from_addr', models.CharField(max_length=255, null=True)), - ('sender', models.ForeignKey(default=1, blank=True, to=settings.AUTH_USER_MODEL, null=True)), + ('sender', models.ForeignKey(default=1, blank=True, to=settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -52,7 +52,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('course_id', CourseKeyField(max_length=255, db_index=True)), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, null=True)), + ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE)), ], ), migrations.AlterUniqueTogether( diff --git a/lms/djangoapps/bulk_email/migrations/0004_add_email_targets.py b/lms/djangoapps/bulk_email/migrations/0004_add_email_targets.py index e50d3733a1..4acc63d9d3 100644 --- a/lms/djangoapps/bulk_email/migrations/0004_add_email_targets.py +++ b/lms/djangoapps/bulk_email/migrations/0004_add_email_targets.py @@ -27,8 +27,8 @@ class Migration(migrations.Migration): migrations.CreateModel( name='CohortTarget', fields=[ - ('target_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='bulk_email.Target')), - ('cohort', models.ForeignKey(to='course_groups.CourseUserGroup')), + ('target_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='bulk_email.Target', on_delete=models.CASCADE)), + ('cohort', models.ForeignKey(to='course_groups.CourseUserGroup', on_delete=models.CASCADE)), ], bases=('bulk_email.target',), ), diff --git a/lms/djangoapps/bulk_email/migrations/0006_course_mode_targets.py b/lms/djangoapps/bulk_email/migrations/0006_course_mode_targets.py index ec294d95c3..98cf5a3310 100644 --- a/lms/djangoapps/bulk_email/migrations/0006_course_mode_targets.py +++ b/lms/djangoapps/bulk_email/migrations/0006_course_mode_targets.py @@ -15,8 +15,8 @@ class Migration(migrations.Migration): migrations.CreateModel( name='CourseModeTarget', fields=[ - ('target_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='bulk_email.Target')), - ('track', models.ForeignKey(to='course_modes.CourseMode')), + ('target_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='bulk_email.Target', on_delete=models.CASCADE)), + ('track', models.ForeignKey(to='course_modes.CourseMode', on_delete=models.CASCADE)), ], bases=('bulk_email.target',), ), diff --git a/lms/djangoapps/bulk_email/models.py b/lms/djangoapps/bulk_email/models.py index dab9d07bf6..03f194547b 100644 --- a/lms/djangoapps/bulk_email/models.py +++ b/lms/djangoapps/bulk_email/models.py @@ -28,7 +28,7 @@ class Email(models.Model): """ Abstract base class for common information for an email. """ - sender = models.ForeignKey(User, default=1, blank=True, null=True) + sender = models.ForeignKey(User, default=1, blank=True, null=True, on_delete=models.CASCADE) slug = models.CharField(max_length=128, db_index=True) subject = models.CharField(max_length=128, blank=True) html_message = models.TextField(null=True, blank=True) @@ -139,7 +139,7 @@ class CohortTarget(Target): """ Subclass of Target, specifically referring to a cohort. """ - cohort = models.ForeignKey('course_groups.CourseUserGroup') + cohort = models.ForeignKey('course_groups.CourseUserGroup', on_delete=models.CASCADE) class Meta: app_label = "bulk_email" @@ -182,7 +182,7 @@ class CourseModeTarget(Target): """ Subclass of Target, specifically for course modes. """ - track = models.ForeignKey('course_modes.CourseMode') + track = models.ForeignKey('course_modes.CourseMode', on_delete=models.CASCADE) class Meta: app_label = "bulk_email" @@ -306,7 +306,7 @@ class Optout(models.Model): # 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) + user = models.ForeignKey(User, db_index=True, null=True, on_delete=models.CASCADE) course_id = CourseKeyField(max_length=255, db_index=True) class Meta(object): diff --git a/lms/djangoapps/ccx/migrations/0001_initial.py b/lms/djangoapps/ccx/migrations/0001_initial.py index e632b29016..e3d54d7a3d 100644 --- a/lms/djangoapps/ccx/migrations/0001_initial.py +++ b/lms/djangoapps/ccx/migrations/0001_initial.py @@ -28,13 +28,13 @@ class Migration(migrations.Migration): ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('course_id', CourseKeyField(max_length=255, db_index=True)), ('display_name', models.CharField(max_length=255)), - ('coach', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('coach', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.AddField( model_name='ccxfieldoverride', name='ccx', - field=models.ForeignKey(to='ccx.CustomCourseForEdX'), + field=models.ForeignKey(to='ccx.CustomCourseForEdX', on_delete=models.CASCADE), ), migrations.AlterUniqueTogether( name='ccxfieldoverride', diff --git a/lms/djangoapps/ccx/models.py b/lms/djangoapps/ccx/models.py index 66cc3b34f5..e47e918431 100644 --- a/lms/djangoapps/ccx/models.py +++ b/lms/djangoapps/ccx/models.py @@ -26,7 +26,7 @@ class CustomCourseForEdX(models.Model): """ course_id = CourseKeyField(max_length=255, db_index=True) display_name = models.CharField(max_length=255) - coach = models.ForeignKey(User, db_index=True) + coach = models.ForeignKey(User, db_index=True, on_delete=models.CASCADE) # if not empty, this field contains a json serialized list of # the master course modules structure_json = models.TextField(verbose_name='Structure JSON', blank=True, null=True) @@ -107,7 +107,7 @@ class CcxFieldOverride(models.Model): """ Field overrides for custom courses. """ - ccx = models.ForeignKey(CustomCourseForEdX, db_index=True) + ccx = models.ForeignKey(CustomCourseForEdX, db_index=True, on_delete=models.CASCADE) location = UsageKeyField(max_length=255, db_index=True) field = models.CharField(max_length=255) diff --git a/lms/djangoapps/certificates/migrations/0001_initial.py b/lms/djangoapps/certificates/migrations/0001_initial.py index 95a5cc5f9c..596fb2ca9e 100644 --- a/lms/djangoapps/certificates/migrations/0001_initial.py +++ b/lms/djangoapps/certificates/migrations/0001_initial.py @@ -26,7 +26,7 @@ class Migration(migrations.Migration): ('course_id', CourseKeyField(default=None, max_length=255, blank=True)), ('mode', models.CharField(max_length=100)), ('data', jsonfield.fields.JSONField()), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -117,7 +117,7 @@ class Migration(migrations.Migration): ('whitelist', models.BooleanField(default=0)), ('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)), ('notes', models.TextField(default=None, null=True)), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -165,13 +165,13 @@ class Migration(migrations.Migration): ('created_date', models.DateTimeField(auto_now_add=True)), ('modified_date', models.DateTimeField(auto_now=True)), ('error_reason', models.CharField(default=b'', max_length=512, blank=True)), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.AddField( model_name='examplecertificate', name='example_cert_set', - field=models.ForeignKey(to='certificates.ExampleCertificateSet'), + field=models.ForeignKey(to='certificates.ExampleCertificateSet', on_delete=models.CASCADE), ), migrations.AlterUniqueTogether( name='certificatetemplate', diff --git a/lms/djangoapps/certificates/migrations/0004_certificategenerationhistory.py b/lms/djangoapps/certificates/migrations/0004_certificategenerationhistory.py index 69c4a1e459..3f8861a9a4 100644 --- a/lms/djangoapps/certificates/migrations/0004_certificategenerationhistory.py +++ b/lms/djangoapps/certificates/migrations/0004_certificategenerationhistory.py @@ -25,8 +25,8 @@ class Migration(migrations.Migration): ('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)), ('course_id', CourseKeyField(max_length=255)), ('is_regeneration', models.BooleanField(default=False)), - ('generated_by', models.ForeignKey(to=settings.AUTH_USER_MODEL)), - ('instructor_task', models.ForeignKey(to='instructor_task.InstructorTask')), + ('generated_by', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), + ('instructor_task', models.ForeignKey(to='instructor_task.InstructorTask', on_delete=models.CASCADE)), ], ), ] diff --git a/lms/djangoapps/certificates/migrations/0007_certificateinvalidation.py b/lms/djangoapps/certificates/migrations/0007_certificateinvalidation.py index 1dd5a49bba..f25fe3d709 100644 --- a/lms/djangoapps/certificates/migrations/0007_certificateinvalidation.py +++ b/lms/djangoapps/certificates/migrations/0007_certificateinvalidation.py @@ -23,8 +23,8 @@ class Migration(migrations.Migration): ('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)), ('notes', models.TextField(default=None, null=True)), ('active', models.BooleanField(default=True)), - ('generated_certificate', models.ForeignKey(to='certificates.GeneratedCertificate')), - ('invalidated_by', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('generated_certificate', models.ForeignKey(to='certificates.GeneratedCertificate', on_delete=models.CASCADE)), + ('invalidated_by', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), ] diff --git a/lms/djangoapps/certificates/models.py b/lms/djangoapps/certificates/models.py index 0ac76b0d20..2657869ccc 100644 --- a/lms/djangoapps/certificates/models.py +++ b/lms/djangoapps/certificates/models.py @@ -136,7 +136,7 @@ class CertificateWhitelist(models.Model): objects = NoneToEmptyManager() - user = models.ForeignKey(User) + user = models.ForeignKey(User, on_delete=models.CASCADE) course_id = CourseKeyField(max_length=255, blank=True, default=None) whitelist = models.BooleanField(default=0) created = AutoCreatedField(_('created')) @@ -231,7 +231,7 @@ class GeneratedCertificate(models.Model): VERIFIED_CERTS_MODES = [CourseMode.VERIFIED, CourseMode.CREDIT_MODE] - user = models.ForeignKey(User) + user = models.ForeignKey(User, on_delete=models.CASCADE) course_id = CourseKeyField(max_length=255, blank=True, default=None) verify_uuid = models.CharField(max_length=32, blank=True, default='', db_index=True) download_uuid = models.CharField(max_length=32, blank=True, default='') @@ -358,8 +358,8 @@ class CertificateGenerationHistory(TimeStampedModel): """ course_id = CourseKeyField(max_length=255) - generated_by = models.ForeignKey(User) - instructor_task = models.ForeignKey(InstructorTask) + generated_by = models.ForeignKey(User, on_delete=models.CASCADE) + instructor_task = models.ForeignKey(InstructorTask, on_delete=models.CASCADE) is_regeneration = models.BooleanField(default=False) def get_task_name(self): @@ -418,8 +418,8 @@ class CertificateInvalidation(TimeStampedModel): """ Model for storing Certificate Invalidation. """ - generated_certificate = models.ForeignKey(GeneratedCertificate) - invalidated_by = models.ForeignKey(User) + generated_certificate = models.ForeignKey(GeneratedCertificate, on_delete=models.CASCADE) + invalidated_by = models.ForeignKey(User, on_delete=models.CASCADE) notes = models.TextField(default=None, null=True) active = models.BooleanField(default=True) @@ -710,7 +710,7 @@ class ExampleCertificate(TimeStampedModel): # Dummy full name for the generated certificate EXAMPLE_FULL_NAME = u'John Doë' - example_cert_set = models.ForeignKey(ExampleCertificateSet) + example_cert_set = models.ForeignKey(ExampleCertificateSet, on_delete=models.CASCADE) description = models.CharField( max_length=255, diff --git a/lms/djangoapps/course_goals/migrations/0001_initial.py b/lms/djangoapps/course_goals/migrations/0001_initial.py index 834a8eb8f6..f976442a39 100644 --- a/lms/djangoapps/course_goals/migrations/0001_initial.py +++ b/lms/djangoapps/course_goals/migrations/0001_initial.py @@ -19,7 +19,7 @@ class Migration(migrations.Migration): ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('course_key', CourseKeyField(max_length=255, db_index=True)), ('goal_key', models.CharField(default=b'unsure', max_length=100, choices=[(b'certify', 'Earn a certificate.'), (b'complete', 'Complete the course.'), (b'explore', 'Explore the course.'), (b'unsure', 'Not sure yet.')])), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.AlterUniqueTogether( diff --git a/lms/djangoapps/course_goals/models.py b/lms/djangoapps/course_goals/models.py index d76912a0a4..b0bc820864 100644 --- a/lms/djangoapps/course_goals/models.py +++ b/lms/djangoapps/course_goals/models.py @@ -26,7 +26,7 @@ class CourseGoal(models.Model): """ Represents a course goal set by a user on the course home page. """ - user = models.ForeignKey(User, blank=False) + user = models.ForeignKey(User, blank=False, on_delete=models.CASCADE) 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) diff --git a/lms/djangoapps/courseware/migrations/0001_initial.py b/lms/djangoapps/courseware/migrations/0001_initial.py index 2e54b8049a..b00a76c9e1 100644 --- a/lms/djangoapps/courseware/migrations/0001_initial.py +++ b/lms/djangoapps/courseware/migrations/0001_initial.py @@ -25,7 +25,7 @@ class Migration(migrations.Migration): ('created', models.DateTimeField(db_index=True, auto_now_add=True, null=True)), ('updated', models.DateTimeField(auto_now=True, db_index=True)), ('gradeset', models.TextField(null=True, blank=True)), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -52,7 +52,7 @@ class Migration(migrations.Migration): ('location', UsageKeyField(max_length=255, db_index=True)), ('field', models.CharField(max_length=255)), ('value', models.TextField(default=b'null')), - ('student', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('student', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -68,7 +68,7 @@ class Migration(migrations.Migration): ('done', models.CharField(default=b'na', max_length=8, db_index=True, choices=[(b'na', b'NOT_APPLICABLE'), (b'f', b'FINISHED'), (b'i', b'INCOMPLETE')])), ('created', models.DateTimeField(auto_now_add=True, db_index=True)), ('modified', models.DateTimeField(auto_now=True, db_index=True)), - ('student', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('student', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -80,7 +80,7 @@ class Migration(migrations.Migration): ('state', models.TextField(null=True, blank=True)), ('grade', models.FloatField(null=True, blank=True)), ('max_grade', models.FloatField(null=True, blank=True)), - ('student_module', models.ForeignKey(to='courseware.StudentModule')), + ('student_module', models.ForeignKey(to='courseware.StudentModule', on_delete=models.CASCADE)), ], options={ 'get_latest_by': 'created', @@ -94,7 +94,7 @@ class Migration(migrations.Migration): ('value', models.TextField(default=b'null')), ('created', models.DateTimeField(auto_now_add=True, db_index=True)), ('modified', models.DateTimeField(auto_now=True, db_index=True)), - ('student', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('student', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -106,7 +106,7 @@ class Migration(migrations.Migration): ('created', models.DateTimeField(auto_now_add=True, db_index=True)), ('modified', models.DateTimeField(auto_now=True, db_index=True)), ('module_type', BlockTypeKeyField(max_length=64, db_index=True)), - ('student', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('student', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.CreateModel( diff --git a/lms/djangoapps/courseware/models.py b/lms/djangoapps/courseware/models.py index 23c0c8210b..141ef654fa 100644 --- a/lms/djangoapps/courseware/models.py +++ b/lms/djangoapps/courseware/models.py @@ -92,7 +92,7 @@ class StudentModule(models.Model): # Key used to share state. This is the XBlock usage_id module_state_key = UsageKeyField(max_length=255, db_column='module_id') - student = models.ForeignKey(User, db_index=True) + student = models.ForeignKey(User, db_index=True, on_delete=models.CASCADE) course_id = CourseKeyField(max_length=255, db_index=True) @@ -223,7 +223,7 @@ class StudentModuleHistory(BaseStudentModuleHistory): app_label = "courseware" get_latest_by = "created" - student_module = models.ForeignKey(StudentModule, db_index=True) + student_module = models.ForeignKey(StudentModule, db_index=True, on_delete=models.CASCADE) def __unicode__(self): return unicode(repr(self)) @@ -300,7 +300,7 @@ class XModuleStudentPrefsField(XBlockFieldBase): # The type of the module for these preferences module_type = BlockTypeKeyField(max_length=64, db_index=True) - student = models.ForeignKey(User, db_index=True) + student = models.ForeignKey(User, db_index=True, on_delete=models.CASCADE) class XModuleStudentInfoField(XBlockFieldBase): @@ -312,14 +312,14 @@ class XModuleStudentInfoField(XBlockFieldBase): app_label = "courseware" unique_together = (('student', 'field_name'),) - student = models.ForeignKey(User, db_index=True) + student = models.ForeignKey(User, db_index=True, on_delete=models.CASCADE) class OfflineComputedGrade(models.Model): """ Table of grades computed offline for a given user and course. """ - user = models.ForeignKey(User, db_index=True) + user = models.ForeignKey(User, db_index=True, on_delete=models.CASCADE) course_id = CourseKeyField(max_length=255, db_index=True) created = models.DateTimeField(auto_now_add=True, null=True, db_index=True) @@ -363,7 +363,7 @@ class StudentFieldOverride(TimeStampedModel): """ course_id = CourseKeyField(max_length=255, db_index=True) location = UsageKeyField(max_length=255, db_index=True) - student = models.ForeignKey(User, db_index=True) + student = models.ForeignKey(User, db_index=True, on_delete=models.CASCADE) class Meta(object): app_label = "courseware" diff --git a/lms/djangoapps/experiments/migrations/0001_initial.py b/lms/djangoapps/experiments/migrations/0001_initial.py index 79701e693e..ff7d94e399 100644 --- a/lms/djangoapps/experiments/migrations/0001_initial.py +++ b/lms/djangoapps/experiments/migrations/0001_initial.py @@ -23,7 +23,7 @@ class Migration(migrations.Migration): ('experiment_id', models.PositiveSmallIntegerField(verbose_name=b'Experiment ID', db_index=True)), ('key', models.CharField(max_length=255)), ('value', models.TextField()), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], options={ 'verbose_name': 'Experiment Data', diff --git a/lms/djangoapps/experiments/models.py b/lms/djangoapps/experiments/models.py index 168c839c41..226c8ab71e 100644 --- a/lms/djangoapps/experiments/models.py +++ b/lms/djangoapps/experiments/models.py @@ -4,7 +4,7 @@ from model_utils.models import TimeStampedModel class ExperimentData(TimeStampedModel): - user = models.ForeignKey(settings.AUTH_USER_MODEL) + user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) experiment_id = models.PositiveSmallIntegerField( null=False, blank=False, db_index=True, verbose_name='Experiment ID' ) diff --git a/lms/djangoapps/grades/migrations/0001_initial.py b/lms/djangoapps/grades/migrations/0001_initial.py index 8361693f5c..a940bd1304 100644 --- a/lms/djangoapps/grades/migrations/0001_initial.py +++ b/lms/djangoapps/grades/migrations/0001_initial.py @@ -42,7 +42,7 @@ class Migration(migrations.Migration): migrations.AddField( model_name='persistentsubsectiongrade', name='visible_blocks', - field=models.ForeignKey(to='grades.VisibleBlocks', db_column=b'visible_blocks_hash', to_field=b'hashed'), + field=models.ForeignKey(to='grades.VisibleBlocks', db_column=b'visible_blocks_hash', to_field=b'hashed', on_delete=models.CASCADE), ), migrations.AlterUniqueTogether( name='persistentsubsectiongrade', diff --git a/lms/djangoapps/grades/models.py b/lms/djangoapps/grades/models.py index 37244550b2..b19301dff4 100644 --- a/lms/djangoapps/grades/models.py +++ b/lms/djangoapps/grades/models.py @@ -306,7 +306,8 @@ class PersistentSubsectionGrade(TimeStampedModel): first_attempted = models.DateTimeField(null=True, blank=True) # track which blocks were visible at the time of grade calculation - visible_blocks = models.ForeignKey(VisibleBlocks, db_column='visible_blocks_hash', to_field='hashed') + visible_blocks = models.ForeignKey(VisibleBlocks, db_column='visible_blocks_hash', to_field='hashed', + on_delete=models.CASCADE) @property def full_usage_key(self): diff --git a/lms/djangoapps/instructor_task/migrations/0001_initial.py b/lms/djangoapps/instructor_task/migrations/0001_initial.py index 496d9d901d..14970627f1 100644 --- a/lms/djangoapps/instructor_task/migrations/0001_initial.py +++ b/lms/djangoapps/instructor_task/migrations/0001_initial.py @@ -27,7 +27,7 @@ class Migration(migrations.Migration): ('created', models.DateTimeField(auto_now_add=True, null=True)), ('updated', models.DateTimeField(auto_now=True)), ('subtasks', models.TextField(blank=True)), - ('requester', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('requester', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), ] diff --git a/lms/djangoapps/instructor_task/models.py b/lms/djangoapps/instructor_task/models.py index 6fe50a39a1..a01495e3eb 100644 --- a/lms/djangoapps/instructor_task/models.py +++ b/lms/djangoapps/instructor_task/models.py @@ -69,7 +69,7 @@ class InstructorTask(models.Model): task_id = models.CharField(max_length=255, db_index=True) # max_length from celery_taskmeta task_state = models.CharField(max_length=50, null=True, db_index=True) # max_length from celery_taskmeta task_output = models.CharField(max_length=1024, null=True) - requester = models.ForeignKey(User, db_index=True) + requester = models.ForeignKey(User, db_index=True, on_delete=models.CASCADE) created = models.DateTimeField(auto_now_add=True, null=True) updated = models.DateTimeField(auto_now=True) subtasks = models.TextField(blank=True) # JSON dictionary diff --git a/lms/djangoapps/lti_provider/migrations/0001_initial.py b/lms/djangoapps/lti_provider/migrations/0001_initial.py index cb39ab96d1..5fbbf3b015 100644 --- a/lms/djangoapps/lti_provider/migrations/0001_initial.py +++ b/lms/djangoapps/lti_provider/migrations/0001_initial.py @@ -39,8 +39,8 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('lti_user_id', models.CharField(max_length=255)), - ('edx_user', models.OneToOneField(to=settings.AUTH_USER_MODEL)), - ('lti_consumer', models.ForeignKey(to='lti_provider.LtiConsumer')), + ('edx_user', models.OneToOneField(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), + ('lti_consumer', models.ForeignKey(to='lti_provider.LtiConsumer', on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -48,18 +48,18 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('lis_outcome_service_url', models.CharField(unique=True, max_length=255)), - ('lti_consumer', models.ForeignKey(to='lti_provider.LtiConsumer')), + ('lti_consumer', models.ForeignKey(to='lti_provider.LtiConsumer', on_delete=models.CASCADE)), ], ), migrations.AddField( model_name='gradedassignment', name='outcome_service', - field=models.ForeignKey(to='lti_provider.OutcomeService'), + field=models.ForeignKey(to='lti_provider.OutcomeService', on_delete=models.CASCADE), ), migrations.AddField( model_name='gradedassignment', name='user', - field=models.ForeignKey(to=settings.AUTH_USER_MODEL), + field=models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE), ), migrations.AlterUniqueTogether( name='ltiuser', diff --git a/lms/djangoapps/lti_provider/models.py b/lms/djangoapps/lti_provider/models.py index ad338e069d..12498aed6f 100644 --- a/lms/djangoapps/lti_provider/models.py +++ b/lms/djangoapps/lti_provider/models.py @@ -93,7 +93,7 @@ class OutcomeService(models.Model): properties """ lis_outcome_service_url = models.CharField(max_length=255, unique=True) - lti_consumer = models.ForeignKey(LtiConsumer) + lti_consumer = models.ForeignKey(LtiConsumer, on_delete=models.CASCADE) class GradedAssignment(models.Model): @@ -110,10 +110,10 @@ class GradedAssignment(models.Model): Learning Information Services standard from which LTI inherits some properties """ - user = models.ForeignKey(User, db_index=True) + user = models.ForeignKey(User, db_index=True, on_delete=models.CASCADE) course_key = CourseKeyField(max_length=255, db_index=True) usage_key = UsageKeyField(max_length=255, db_index=True) - outcome_service = models.ForeignKey(OutcomeService) + outcome_service = models.ForeignKey(OutcomeService, on_delete=models.CASCADE) lis_result_sourcedid = models.CharField(max_length=255, db_index=True) version_number = models.IntegerField(default=0) @@ -128,9 +128,9 @@ class LtiUser(models.Model): to the LTI spec), so we guarantee a unique mapping from LTI to edX account by using the lti_consumer/lti_user_id tuple. """ - lti_consumer = models.ForeignKey(LtiConsumer) + lti_consumer = models.ForeignKey(LtiConsumer, on_delete=models.CASCADE) lti_user_id = models.CharField(max_length=255) - edx_user = models.OneToOneField(User) + edx_user = models.OneToOneField(User, on_delete=models.CASCADE) class Meta(object): unique_together = ('lti_consumer', 'lti_user_id') diff --git a/lms/djangoapps/notes/migrations/0001_initial.py b/lms/djangoapps/notes/migrations/0001_initial.py index 8087621b71..0fd2629616 100644 --- a/lms/djangoapps/notes/migrations/0001_initial.py +++ b/lms/djangoapps/notes/migrations/0001_initial.py @@ -28,7 +28,7 @@ class Migration(migrations.Migration): ('tags', models.TextField(default=b'')), ('created', models.DateTimeField(db_index=True, auto_now_add=True, null=True)), ('updated', models.DateTimeField(auto_now=True, db_index=True)), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), ] diff --git a/lms/djangoapps/notes/models.py b/lms/djangoapps/notes/models.py index 60776d7b63..f7bc90208f 100644 --- a/lms/djangoapps/notes/models.py +++ b/lms/djangoapps/notes/models.py @@ -10,7 +10,7 @@ from six import text_type class Note(models.Model): - user = models.ForeignKey(User, db_index=True) + user = models.ForeignKey(User, db_index=True, on_delete=models.CASCADE) course_id = CourseKeyField(max_length=255, db_index=True) uri = models.CharField(max_length=255, db_index=True) text = models.TextField(default="") diff --git a/lms/djangoapps/shoppingcart/migrations/0001_initial.py b/lms/djangoapps/shoppingcart/migrations/0001_initial.py index d45aca8ce8..5209a2c6a6 100644 --- a/lms/djangoapps/shoppingcart/migrations/0001_initial.py +++ b/lms/djangoapps/shoppingcart/migrations/0001_initial.py @@ -28,14 +28,14 @@ class Migration(migrations.Migration): ('created_at', models.DateTimeField(auto_now_add=True)), ('is_active', models.BooleanField(default=True)), ('expiration_date', models.DateTimeField(null=True, blank=True)), - ('created_by', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('created_by', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.CreateModel( name='CouponRedemption', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('coupon', models.ForeignKey(to='shoppingcart.Coupon')), + ('coupon', models.ForeignKey(to='shoppingcart.Coupon', on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -55,7 +55,7 @@ class Migration(migrations.Migration): ('created_at', models.DateTimeField(auto_now_add=True)), ('mode_slug', models.CharField(max_length=100, null=True)), ('is_valid', models.BooleanField(default=True)), - ('created_by', models.ForeignKey(related_name='created_by_user', to=settings.AUTH_USER_MODEL)), + ('created_by', models.ForeignKey(related_name='created_by_user', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -102,7 +102,7 @@ class Migration(migrations.Migration): ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('timestamp', models.DateTimeField(auto_now_add=True, db_index=True)), ('snapshot', models.TextField(blank=True)), - ('invoice', models.ForeignKey(to='shoppingcart.Invoice')), + ('invoice', models.ForeignKey(to='shoppingcart.Invoice', on_delete=models.CASCADE)), ], options={ 'get_latest_by': 'timestamp', @@ -129,9 +129,9 @@ class Migration(migrations.Migration): ('currency', models.CharField(default=b'usd', help_text='Lower-case ISO currency codes', max_length=8)), ('comments', models.TextField(help_text='Optional: provide additional information for this transaction', null=True, blank=True)), ('status', models.CharField(default=b'started', help_text="The status of the payment or refund. 'started' means that payment is expected, but money has not yet been transferred. 'completed' means that the payment or refund was received. 'cancelled' means that payment or refund was expected, but was cancelled before money was transferred. ", max_length=32, choices=[(b'started', b'started'), (b'completed', b'completed'), (b'cancelled', b'cancelled')])), - ('created_by', models.ForeignKey(to=settings.AUTH_USER_MODEL)), - ('invoice', models.ForeignKey(to='shoppingcart.Invoice')), - ('last_modified_by', models.ForeignKey(related_name='last_modified_by_user', to=settings.AUTH_USER_MODEL)), + ('created_by', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), + ('invoice', models.ForeignKey(to='shoppingcart.Invoice', on_delete=models.CASCADE)), + ('last_modified_by', models.ForeignKey(related_name='last_modified_by_user', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -160,7 +160,7 @@ class Migration(migrations.Migration): ('recipient_email', models.CharField(max_length=255, null=True, blank=True)), ('customer_reference_number', models.CharField(max_length=63, null=True, blank=True)), ('order_type', models.CharField(default=b'personal', max_length=32, choices=[(b'personal', b'personal'), (b'business', b'business')])), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -194,26 +194,26 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('redeemed_at', models.DateTimeField(auto_now_add=True, null=True)), - ('course_enrollment', models.ForeignKey(to='student.CourseEnrollment', null=True)), - ('order', models.ForeignKey(to='shoppingcart.Order', null=True)), - ('redeemed_by', models.ForeignKey(to=settings.AUTH_USER_MODEL)), - ('registration_code', models.ForeignKey(to='shoppingcart.CourseRegistrationCode')), + ('course_enrollment', models.ForeignKey(to='student.CourseEnrollment', null=True, on_delete=models.CASCADE)), + ('order', models.ForeignKey(to='shoppingcart.Order', null=True, on_delete=models.CASCADE)), + ('redeemed_by', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), + ('registration_code', models.ForeignKey(to='shoppingcart.CourseRegistrationCode', on_delete=models.CASCADE)), ], ), migrations.CreateModel( name='CertificateItem', fields=[ - ('orderitem_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='shoppingcart.OrderItem')), + ('orderitem_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='shoppingcart.OrderItem', on_delete=models.CASCADE)), ('course_id', CourseKeyField(max_length=128, db_index=True)), ('mode', models.SlugField()), - ('course_enrollment', models.ForeignKey(to='student.CourseEnrollment')), + ('course_enrollment', models.ForeignKey(to='student.CourseEnrollment', on_delete=models.CASCADE)), ], bases=('shoppingcart.orderitem',), ), migrations.CreateModel( name='CourseRegCodeItem', fields=[ - ('orderitem_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='shoppingcart.OrderItem')), + ('orderitem_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='shoppingcart.OrderItem', on_delete=models.CASCADE)), ('course_id', CourseKeyField(max_length=128, db_index=True)), ('mode', models.SlugField(default=b'honor')), ], @@ -222,7 +222,7 @@ class Migration(migrations.Migration): migrations.CreateModel( name='CourseRegistrationCodeInvoiceItem', fields=[ - ('invoiceitem_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='shoppingcart.InvoiceItem')), + ('invoiceitem_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='shoppingcart.InvoiceItem', on_delete=models.CASCADE)), ('course_id', CourseKeyField(max_length=128, db_index=True)), ], bases=('shoppingcart.invoiceitem',), @@ -230,7 +230,7 @@ class Migration(migrations.Migration): migrations.CreateModel( name='Donation', fields=[ - ('orderitem_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='shoppingcart.OrderItem')), + ('orderitem_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='shoppingcart.OrderItem', on_delete=models.CASCADE)), ('donation_type', models.CharField(default=b'general', max_length=32, choices=[(b'general', b'A general donation'), (b'course', b'A donation to a particular course')])), ('course_id', CourseKeyField(max_length=255, db_index=True)), ], @@ -239,51 +239,51 @@ class Migration(migrations.Migration): migrations.CreateModel( name='PaidCourseRegistration', fields=[ - ('orderitem_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='shoppingcart.OrderItem')), + ('orderitem_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='shoppingcart.OrderItem', on_delete=models.CASCADE)), ('course_id', CourseKeyField(max_length=128, db_index=True)), ('mode', models.SlugField(default=b'honor')), - ('course_enrollment', models.ForeignKey(to='student.CourseEnrollment', null=True)), + ('course_enrollment', models.ForeignKey(to='student.CourseEnrollment', null=True, on_delete=models.CASCADE)), ], bases=('shoppingcart.orderitem',), ), migrations.AddField( model_name='orderitem', name='order', - field=models.ForeignKey(to='shoppingcart.Order'), + field=models.ForeignKey(to='shoppingcart.Order', on_delete=models.CASCADE), ), migrations.AddField( model_name='orderitem', name='user', - field=models.ForeignKey(to=settings.AUTH_USER_MODEL), + field=models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE), ), migrations.AddField( model_name='invoiceitem', name='invoice', - field=models.ForeignKey(to='shoppingcart.Invoice'), + field=models.ForeignKey(to='shoppingcart.Invoice', on_delete=models.CASCADE), ), migrations.AddField( model_name='courseregistrationcode', name='invoice', - field=models.ForeignKey(to='shoppingcart.Invoice', null=True), + field=models.ForeignKey(to='shoppingcart.Invoice', null=True, on_delete=models.CASCADE), ), migrations.AddField( model_name='courseregistrationcode', name='order', - field=models.ForeignKey(related_name='purchase_order', to='shoppingcart.Order', null=True), + field=models.ForeignKey(related_name='purchase_order', to='shoppingcart.Order', null=True, on_delete=models.CASCADE), ), migrations.AddField( model_name='couponredemption', name='order', - field=models.ForeignKey(to='shoppingcart.Order'), + field=models.ForeignKey(to='shoppingcart.Order', on_delete=models.CASCADE), ), migrations.AddField( model_name='couponredemption', name='user', - field=models.ForeignKey(to=settings.AUTH_USER_MODEL), + field=models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE), ), migrations.AddField( model_name='courseregistrationcode', name='invoice_item', - field=models.ForeignKey(to='shoppingcart.CourseRegistrationCodeInvoiceItem', null=True), + field=models.ForeignKey(to='shoppingcart.CourseRegistrationCodeInvoiceItem', null=True, on_delete=models.CASCADE), ), ] diff --git a/lms/djangoapps/shoppingcart/models.py b/lms/djangoapps/shoppingcart/models.py index 54edf2df70..646db2b44b 100644 --- a/lms/djangoapps/shoppingcart/models.py +++ b/lms/djangoapps/shoppingcart/models.py @@ -113,7 +113,7 @@ class Order(models.Model): class Meta(object): app_label = "shoppingcart" - user = models.ForeignKey(User, db_index=True) + user = models.ForeignKey(User, db_index=True, on_delete=models.CASCADE) currency = models.CharField(default="usd", max_length=8) # lower case ISO currency codes status = models.CharField(max_length=32, default='cart', choices=ORDER_STATUSES) purchase_time = models.DateTimeField(null=True, blank=True) @@ -648,9 +648,9 @@ class OrderItem(TimeStampedModel): base_manager_name = 'objects' objects = InheritanceManager() - order = models.ForeignKey(Order, db_index=True) + order = models.ForeignKey(Order, db_index=True, on_delete=models.CASCADE) # this is denormalized, but convenient for SQL queries for reports, etc. user should always be = order.user - user = models.ForeignKey(User, db_index=True) + user = models.ForeignKey(User, db_index=True, on_delete=models.CASCADE) # this is denormalized, but convenient for SQL queries for reports, etc. status should always be = order.status status = models.CharField(max_length=32, default='cart', choices=ORDER_STATUSES, db_index=True) qty = models.IntegerField(default=1) @@ -1003,7 +1003,7 @@ class InvoiceTransaction(TimeStampedModel): class Meta(object): app_label = "shoppingcart" - invoice = models.ForeignKey(Invoice) + invoice = models.ForeignKey(Invoice, on_delete=models.CASCADE) amount = models.DecimalField( default=0.0, decimal_places=2, max_digits=30, help_text=ugettext_lazy( @@ -1032,8 +1032,8 @@ class InvoiceTransaction(TimeStampedModel): "'cancelled' means that payment or refund was expected, but was cancelled before money was transferred. " ) ) - created_by = models.ForeignKey(User) - last_modified_by = models.ForeignKey(User, related_name='last_modified_by_user') + created_by = models.ForeignKey(User, on_delete=models.CASCADE) + last_modified_by = models.ForeignKey(User, related_name='last_modified_by_user', on_delete=models.CASCADE) @classmethod def get_invoice_transaction(cls, invoice_id): @@ -1095,7 +1095,7 @@ class InvoiceItem(TimeStampedModel): base_manager_name = 'objects' objects = InheritanceManager() - invoice = models.ForeignKey(Invoice, db_index=True) + invoice = models.ForeignKey(Invoice, db_index=True, on_delete=models.CASCADE) qty = models.IntegerField( default=1, help_text=ugettext_lazy("The number of items sold.") @@ -1171,7 +1171,7 @@ class InvoiceHistory(models.Model): """ timestamp = models.DateTimeField(auto_now_add=True, db_index=True) - invoice = models.ForeignKey(Invoice) + invoice = models.ForeignKey(Invoice, on_delete=models.CASCADE) # JSON-serialized representation of the current state # of the invoice, including its line items and @@ -1234,17 +1234,17 @@ class CourseRegistrationCode(models.Model): code = models.CharField(max_length=32, db_index=True, unique=True) course_id = CourseKeyField(max_length=255, db_index=True) - created_by = models.ForeignKey(User, related_name='created_by_user') + created_by = models.ForeignKey(User, related_name='created_by_user', on_delete=models.CASCADE) created_at = models.DateTimeField(auto_now_add=True) - order = models.ForeignKey(Order, db_index=True, null=True, related_name="purchase_order") + order = models.ForeignKey(Order, db_index=True, null=True, related_name="purchase_order", on_delete=models.CASCADE) mode_slug = models.CharField(max_length=100, null=True) is_valid = models.BooleanField(default=True) # For backwards compatibility, we maintain the FK to "invoice" # In the future, we will remove this in favor of the FK # to "invoice_item" (which can be used to look up the invoice). - invoice = models.ForeignKey(Invoice, null=True) - invoice_item = models.ForeignKey(CourseRegistrationCodeInvoiceItem, null=True) + invoice = models.ForeignKey(Invoice, null=True, on_delete=models.CASCADE) + invoice_item = models.ForeignKey(CourseRegistrationCodeInvoiceItem, null=True, on_delete=models.CASCADE) @classmethod def order_generated_registration_codes(cls, course_id): @@ -1270,11 +1270,11 @@ class RegistrationCodeRedemption(models.Model): class Meta(object): app_label = "shoppingcart" - order = models.ForeignKey(Order, db_index=True, null=True) - registration_code = models.ForeignKey(CourseRegistrationCode, db_index=True) - redeemed_by = models.ForeignKey(User, db_index=True) + order = models.ForeignKey(Order, db_index=True, null=True, on_delete=models.CASCADE) + registration_code = models.ForeignKey(CourseRegistrationCode, db_index=True, on_delete=models.CASCADE) + redeemed_by = models.ForeignKey(User, db_index=True, on_delete=models.CASCADE) redeemed_at = models.DateTimeField(auto_now_add=True, null=True) - course_enrollment = models.ForeignKey(CourseEnrollment, null=True) + course_enrollment = models.ForeignKey(CourseEnrollment, null=True, on_delete=models.CASCADE) @classmethod def registration_code_used_for_enrollment(cls, course_enrollment): @@ -1334,7 +1334,7 @@ class Coupon(models.Model): description = models.CharField(max_length=255, null=True, blank=True) course_id = CourseKeyField(max_length=255) percentage_discount = models.IntegerField(default=0) - created_by = models.ForeignKey(User) + created_by = models.ForeignKey(User, on_delete=models.CASCADE) created_at = models.DateTimeField(auto_now_add=True) is_active = models.BooleanField(default=True) expiration_date = models.DateTimeField(null=True, blank=True) @@ -1357,9 +1357,9 @@ class CouponRedemption(models.Model): class Meta(object): app_label = "shoppingcart" - order = models.ForeignKey(Order, db_index=True) - user = models.ForeignKey(User, db_index=True) - coupon = models.ForeignKey(Coupon, db_index=True) + order = models.ForeignKey(Order, db_index=True, on_delete=models.CASCADE) + user = models.ForeignKey(User, db_index=True, on_delete=models.CASCADE) + coupon = models.ForeignKey(Coupon, db_index=True, on_delete=models.CASCADE) @classmethod def remove_code_redemption_from_item(cls, item, user): @@ -1475,7 +1475,7 @@ class PaidCourseRegistration(OrderItem): course_id = CourseKeyField(max_length=128, db_index=True) mode = models.SlugField(default=CourseMode.DEFAULT_SHOPPINGCART_MODE_SLUG) - course_enrollment = models.ForeignKey(CourseEnrollment, null=True) + course_enrollment = models.ForeignKey(CourseEnrollment, null=True, on_delete=models.CASCADE) @classmethod def get_self_purchased_seat_count(cls, course_key, status='purchased'): @@ -1868,7 +1868,7 @@ class CertificateItem(OrderItem): app_label = "shoppingcart" course_id = CourseKeyField(max_length=128, db_index=True) - course_enrollment = models.ForeignKey(CourseEnrollment) + course_enrollment = models.ForeignKey(CourseEnrollment, on_delete=models.CASCADE) mode = models.SlugField() @receiver(UNENROLL_DONE) diff --git a/lms/djangoapps/survey/migrations/0001_initial.py b/lms/djangoapps/survey/migrations/0001_initial.py index 8eec89a911..7f33ce5445 100644 --- a/lms/djangoapps/survey/migrations/0001_initial.py +++ b/lms/djangoapps/survey/migrations/0001_initial.py @@ -45,11 +45,11 @@ class Migration(migrations.Migration): migrations.AddField( model_name='surveyanswer', name='form', - field=models.ForeignKey(to='survey.SurveyForm'), + field=models.ForeignKey(to='survey.SurveyForm', on_delete=models.CASCADE), ), migrations.AddField( model_name='surveyanswer', name='user', - field=models.ForeignKey(to=settings.AUTH_USER_MODEL), + field=models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE), ), ] diff --git a/lms/djangoapps/survey/models.py b/lms/djangoapps/survey/models.py index d38b616560..a8fa845bdd 100644 --- a/lms/djangoapps/survey/models.py +++ b/lms/djangoapps/survey/models.py @@ -164,8 +164,8 @@ class SurveyAnswer(TimeStampedModel): """ Model for the answers that a user gives for a particular form in a course """ - user = models.ForeignKey(User, db_index=True) - form = models.ForeignKey(SurveyForm, db_index=True) + user = models.ForeignKey(User, db_index=True, on_delete=models.CASCADE) + form = models.ForeignKey(SurveyForm, db_index=True, on_delete=models.CASCADE) field_name = models.CharField(max_length=255, db_index=True) field_value = models.CharField(max_length=1024) diff --git a/lms/djangoapps/teams/migrations/0001_initial.py b/lms/djangoapps/teams/migrations/0001_initial.py index f62bc09043..9abab5178e 100644 --- a/lms/djangoapps/teams/migrations/0001_initial.py +++ b/lms/djangoapps/teams/migrations/0001_initial.py @@ -38,8 +38,8 @@ class Migration(migrations.Migration): ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('date_joined', models.DateTimeField(auto_now_add=True)), ('last_activity_at', models.DateTimeField()), - ('team', models.ForeignKey(related_name='membership', to='teams.CourseTeam')), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('team', models.ForeignKey(related_name='membership', to='teams.CourseTeam', on_delete=models.CASCADE)), + ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.AddField( diff --git a/lms/djangoapps/teams/models.py b/lms/djangoapps/teams/models.py index 657e7dd18f..d91225d193 100644 --- a/lms/djangoapps/teams/models.py +++ b/lms/djangoapps/teams/models.py @@ -171,8 +171,8 @@ class CourseTeamMembership(models.Model): app_label = "teams" unique_together = (('user', 'team'),) - user = models.ForeignKey(User) - team = models.ForeignKey(CourseTeam, related_name='membership') + user = models.ForeignKey(User, on_delete=models.CASCADE) + team = models.ForeignKey(CourseTeam, related_name='membership', on_delete=models.CASCADE) date_joined = models.DateTimeField(auto_now_add=True) last_activity_at = models.DateTimeField() diff --git a/lms/djangoapps/verify_student/migrations/0001_initial.py b/lms/djangoapps/verify_student/migrations/0001_initial.py index b7507a19d2..1a2ecd6308 100644 --- a/lms/djangoapps/verify_student/migrations/0001_initial.py +++ b/lms/djangoapps/verify_student/migrations/0001_initial.py @@ -88,9 +88,9 @@ class Migration(migrations.Migration): ('error_msg', models.TextField(blank=True)), ('error_code', models.CharField(max_length=50, blank=True)), ('photo_id_key', models.TextField(max_length=1024)), - ('copy_id_photo_from', models.ForeignKey(blank=True, to='verify_student.SoftwareSecurePhotoVerification', null=True)), - ('reviewing_user', models.ForeignKey(related_name='photo_verifications_reviewed', default=None, to=settings.AUTH_USER_MODEL, null=True)), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('copy_id_photo_from', models.ForeignKey(blank=True, to='verify_student.SoftwareSecurePhotoVerification', null=True, on_delete=models.CASCADE)), + ('reviewing_user', models.ForeignKey(related_name='photo_verifications_reviewed', default=None, to=settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE)), + ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], options={ 'ordering': ['-created_at'], @@ -127,8 +127,8 @@ class Migration(migrations.Migration): ('timestamp', models.DateTimeField(auto_now_add=True)), ('response', models.TextField(null=True, blank=True)), ('error', models.TextField(null=True, blank=True)), - ('checkpoint', models.ForeignKey(related_name='checkpoint_status', to='verify_student.VerificationCheckpoint')), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('checkpoint', models.ForeignKey(related_name='checkpoint_status', to='verify_student.VerificationCheckpoint', on_delete=models.CASCADE)), + ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], options={ 'get_latest_by': 'timestamp', @@ -139,12 +139,12 @@ class Migration(migrations.Migration): migrations.AddField( model_name='skippedreverification', name='checkpoint', - field=models.ForeignKey(related_name='skipped_checkpoint', to='verify_student.VerificationCheckpoint'), + field=models.ForeignKey(related_name='skipped_checkpoint', to='verify_student.VerificationCheckpoint', on_delete=models.CASCADE), ), migrations.AddField( model_name='skippedreverification', name='user', - field=models.ForeignKey(to=settings.AUTH_USER_MODEL), + field=models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE), ), migrations.AlterUniqueTogether( name='verificationcheckpoint', diff --git a/lms/djangoapps/verify_student/models.py b/lms/djangoapps/verify_student/models.py index 6502e68006..441c4ca802 100644 --- a/lms/djangoapps/verify_student/models.py +++ b/lms/djangoapps/verify_student/models.py @@ -98,7 +98,7 @@ class IDVerificationAttempt(StatusModel): including PhotoVerification and SSOVerification. """ STATUS = Choices('created', 'ready', 'submitted', 'must_retry', 'approved', 'denied') - user = models.ForeignKey(User, db_index=True) + user = models.ForeignKey(User, db_index=True, on_delete=models.CASCADE) # They can change their name later on, so we want to copy the value here so # we always preserve what it was at the time they requested. We only copy @@ -259,7 +259,8 @@ class PhotoVerification(IDVerificationAttempt): db_index=True, default=None, null=True, - related_name="photo_verifications_reviewed" + related_name="photo_verifications_reviewed", + on_delete=models.CASCADE, ) # Mark the name of the service used to evaluate this attempt (e.g @@ -506,7 +507,7 @@ class SoftwareSecurePhotoVerification(PhotoVerification): photo_id_key = models.TextField(max_length=1024) IMAGE_LINK_DURATION = 5 * 60 * 60 * 24 # 5 days in seconds - copy_id_photo_from = models.ForeignKey("self", null=True, blank=True) + copy_id_photo_from = models.ForeignKey("self", null=True, blank=True, on_delete=models.CASCADE) @classmethod def get_initial_verification(cls, user, earliest_allowed_date=None): diff --git a/openedx/core/djangoapps/api_admin/migrations/0001_initial.py b/openedx/core/djangoapps/api_admin/migrations/0001_initial.py index 4493c5db02..9a45a2c714 100644 --- a/openedx/core/djangoapps/api_admin/migrations/0001_initial.py +++ b/openedx/core/djangoapps/api_admin/migrations/0001_initial.py @@ -24,7 +24,7 @@ class Migration(migrations.Migration): ('status', models.CharField(default=b'pending', help_text='Status of this API access request', max_length=255, db_index=True, choices=[(b'pending', 'Pending'), (b'denied', 'Denied'), (b'approved', 'Approved')])), ('website', models.URLField(help_text='The URL of the website associated with this API user.')), ('reason', models.TextField(help_text='The reason this user wants to access the API.')), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], options={ 'ordering': ('-modified', '-created'), diff --git a/openedx/core/djangoapps/api_admin/migrations/0003_auto_20160404_1618.py b/openedx/core/djangoapps/api_admin/migrations/0003_auto_20160404_1618.py index 916a0c622e..3bb347f7a4 100644 --- a/openedx/core/djangoapps/api_admin/migrations/0003_auto_20160404_1618.py +++ b/openedx/core/djangoapps/api_admin/migrations/0003_auto_20160404_1618.py @@ -50,6 +50,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='apiaccessrequest', name='user', - field=models.OneToOneField(to=settings.AUTH_USER_MODEL), + field=models.OneToOneField(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE), ), ] diff --git a/openedx/core/djangoapps/api_admin/migrations/0004_auto_20160412_1506.py b/openedx/core/djangoapps/api_admin/migrations/0004_auto_20160412_1506.py index 6a9365fa48..4cfdac9755 100644 --- a/openedx/core/djangoapps/api_admin/migrations/0004_auto_20160412_1506.py +++ b/openedx/core/djangoapps/api_admin/migrations/0004_auto_20160412_1506.py @@ -21,7 +21,7 @@ class Migration(migrations.Migration): migrations.AddField( model_name='apiaccessrequest', name='site', - field=models.ForeignKey(default=1, to='sites.Site'), + field=models.ForeignKey(default=1, to='sites.Site', on_delete=models.CASCADE), preserve_default=False, ), migrations.AddField( diff --git a/openedx/core/djangoapps/api_admin/migrations/0005_auto_20160414_1232.py b/openedx/core/djangoapps/api_admin/migrations/0005_auto_20160414_1232.py index 5e1c094cea..cb1658593c 100644 --- a/openedx/core/djangoapps/api_admin/migrations/0005_auto_20160414_1232.py +++ b/openedx/core/djangoapps/api_admin/migrations/0005_auto_20160414_1232.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='apiaccessrequest', name='user', - field=models.OneToOneField(related_name='api_access_request', to=settings.AUTH_USER_MODEL), + field=models.OneToOneField(related_name='api_access_request', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE), ), ] diff --git a/openedx/core/djangoapps/api_admin/models.py b/openedx/core/djangoapps/api_admin/models.py index 94666e345d..4410b09e01 100644 --- a/openedx/core/djangoapps/api_admin/models.py +++ b/openedx/core/djangoapps/api_admin/models.py @@ -32,7 +32,7 @@ class ApiAccessRequest(TimeStampedModel): (DENIED, _('Denied')), (APPROVED, _('Approved')), ) - user = models.OneToOneField(User, related_name='api_access_request') + user = models.OneToOneField(User, related_name='api_access_request', on_delete=models.CASCADE) status = models.CharField( max_length=255, choices=STATUS_CHOICES, @@ -44,7 +44,7 @@ class ApiAccessRequest(TimeStampedModel): reason = models.TextField(help_text=_('The reason this user wants to access the API.')) company_name = models.CharField(max_length=255, default='') company_address = models.CharField(max_length=255, default='') - site = models.ForeignKey(Site) + site = models.ForeignKey(Site, on_delete=models.CASCADE) contacted = models.BooleanField(default=False) class Meta: diff --git a/openedx/core/djangoapps/bookmarks/migrations/0001_initial.py b/openedx/core/djangoapps/bookmarks/migrations/0001_initial.py index b98e7fd926..979a297aca 100644 --- a/openedx/core/djangoapps/bookmarks/migrations/0001_initial.py +++ b/openedx/core/djangoapps/bookmarks/migrations/0001_initial.py @@ -25,7 +25,7 @@ class Migration(migrations.Migration): ('course_key', CourseKeyField(max_length=255, db_index=True)), ('usage_key', UsageKeyField(max_length=255, db_index=True)), ('_path', jsonfield.fields.JSONField(help_text=b'Path in course tree to the block', db_column=b'path')), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -46,7 +46,7 @@ class Migration(migrations.Migration): migrations.AddField( model_name='bookmark', name='xblock_cache', - field=models.ForeignKey(to='bookmarks.XBlockCache'), + field=models.ForeignKey(to='bookmarks.XBlockCache', on_delete=models.CASCADE), ), migrations.AlterUniqueTogether( name='bookmark', diff --git a/openedx/core/djangoapps/bookmarks/models.py b/openedx/core/djangoapps/bookmarks/models.py index 9058e70c56..f46f8f6bf6 100644 --- a/openedx/core/djangoapps/bookmarks/models.py +++ b/openedx/core/djangoapps/bookmarks/models.py @@ -42,12 +42,12 @@ class Bookmark(TimeStampedModel): """ Bookmarks model. """ - user = models.ForeignKey(User, db_index=True) + user = models.ForeignKey(User, db_index=True, on_delete=models.CASCADE) course_key = CourseKeyField(max_length=255, db_index=True) usage_key = UsageKeyField(max_length=255, db_index=True) _path = JSONField(db_column='path', help_text='Path in course tree to the block') - xblock_cache = models.ForeignKey('bookmarks.XBlockCache') + xblock_cache = models.ForeignKey('bookmarks.XBlockCache', on_delete=models.CASCADE) class Meta(object): """ diff --git a/openedx/core/djangoapps/content/course_overviews/migrations/0001_initial.py b/openedx/core/djangoapps/content/course_overviews/migrations/0001_initial.py index 82313d9ab9..f0a5fb0ecd 100644 --- a/openedx/core/djangoapps/content/course_overviews/migrations/0001_initial.py +++ b/openedx/core/djangoapps/content/course_overviews/migrations/0001_initial.py @@ -54,7 +54,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('tab_id', models.CharField(max_length=50)), - ('course_overview', models.ForeignKey(related_name='tabs', to='course_overviews.CourseOverview')), + ('course_overview', models.ForeignKey(related_name='tabs', to='course_overviews.CourseOverview', on_delete=models.CASCADE)), ], ), ] diff --git a/openedx/core/djangoapps/content/course_overviews/migrations/0006_courseoverviewimageset.py b/openedx/core/djangoapps/content/course_overviews/migrations/0006_courseoverviewimageset.py index 609950bbbb..23fb6e598a 100644 --- a/openedx/core/djangoapps/content/course_overviews/migrations/0006_courseoverviewimageset.py +++ b/openedx/core/djangoapps/content/course_overviews/migrations/0006_courseoverviewimageset.py @@ -21,7 +21,7 @@ class Migration(migrations.Migration): ('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)), ('small_url', models.TextField(default=b'', blank=True)), ('large_url', models.TextField(default=b'', blank=True)), - ('course_overview', models.OneToOneField(related_name='image_set', to='course_overviews.CourseOverview')), + ('course_overview', models.OneToOneField(related_name='image_set', to='course_overviews.CourseOverview', on_delete=models.CASCADE)), ], options={ 'abstract': False, diff --git a/openedx/core/djangoapps/content/course_overviews/models.py b/openedx/core/djangoapps/content/course_overviews/models.py index 25eae9cdd9..0c6285ed97 100644 --- a/openedx/core/djangoapps/content/course_overviews/models.py +++ b/openedx/core/djangoapps/content/course_overviews/models.py @@ -708,7 +708,7 @@ class CourseOverviewTab(models.Model): Model for storing and caching tabs information of a course. """ tab_id = models.CharField(max_length=50) - course_overview = models.ForeignKey(CourseOverview, db_index=True, related_name="tabs") + course_overview = models.ForeignKey(CourseOverview, db_index=True, related_name="tabs", on_delete=models.CASCADE) class CourseOverviewImageSet(TimeStampedModel): @@ -779,7 +779,8 @@ class CourseOverviewImageSet(TimeStampedModel): interested in extending this functionality. """ - course_overview = models.OneToOneField(CourseOverview, db_index=True, related_name="image_set") + course_overview = models.OneToOneField(CourseOverview, db_index=True, related_name="image_set", + on_delete=models.CASCADE) small_url = models.TextField(blank=True, default="") large_url = models.TextField(blank=True, default="") diff --git a/openedx/core/djangoapps/course_groups/migrations/0001_initial.py b/openedx/core/djangoapps/course_groups/migrations/0001_initial.py index dc94761e9f..c610dac6ab 100644 --- a/openedx/core/djangoapps/course_groups/migrations/0001_initial.py +++ b/openedx/core/djangoapps/course_groups/migrations/0001_initial.py @@ -55,23 +55,23 @@ class Migration(migrations.Migration): ('group_id', models.IntegerField(help_text=b'contains the id of a specific group within the cohorted partition')), ('created_at', models.DateTimeField(auto_now_add=True)), ('updated_at', models.DateTimeField(auto_now=True)), - ('course_user_group', models.OneToOneField(to='course_groups.CourseUserGroup')), + ('course_user_group', models.OneToOneField(to='course_groups.CourseUserGroup', on_delete=models.CASCADE)), ], ), migrations.AddField( model_name='coursecohort', name='course_user_group', - field=models.OneToOneField(related_name='cohort', to='course_groups.CourseUserGroup'), + field=models.OneToOneField(related_name='cohort', to='course_groups.CourseUserGroup', on_delete=models.CASCADE), ), migrations.AddField( model_name='cohortmembership', name='course_user_group', - field=models.ForeignKey(to='course_groups.CourseUserGroup'), + field=models.ForeignKey(to='course_groups.CourseUserGroup', on_delete=models.CASCADE), ), migrations.AddField( model_name='cohortmembership', name='user', - field=models.ForeignKey(to=settings.AUTH_USER_MODEL), + field=models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE), ), migrations.AlterUniqueTogether( name='courseusergroup', diff --git a/openedx/core/djangoapps/course_groups/migrations/0003_auto_20170609_1455.py b/openedx/core/djangoapps/course_groups/migrations/0003_auto_20170609_1455.py index 01293299f3..01cd8b47d3 100644 --- a/openedx/core/djangoapps/course_groups/migrations/0003_auto_20170609_1455.py +++ b/openedx/core/djangoapps/course_groups/migrations/0003_auto_20170609_1455.py @@ -18,7 +18,7 @@ class Migration(migrations.Migration): ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('email', models.CharField(db_index=True, max_length=255, blank=True)), ('course_id', CourseKeyField(max_length=255)), - ('course_user_group', models.ForeignKey(to='course_groups.CourseUserGroup')), + ('course_user_group', models.ForeignKey(to='course_groups.CourseUserGroup', on_delete=models.CASCADE)), ], ), migrations.AlterUniqueTogether( diff --git a/openedx/core/djangoapps/course_groups/models.py b/openedx/core/djangoapps/course_groups/models.py index e3d40a8ba3..c17adea74d 100644 --- a/openedx/core/djangoapps/course_groups/models.py +++ b/openedx/core/djangoapps/course_groups/models.py @@ -70,8 +70,8 @@ class CourseUserGroup(models.Model): class CohortMembership(models.Model): """Used internally to enforce our particular definition of uniqueness""" - course_user_group = models.ForeignKey(CourseUserGroup) - user = models.ForeignKey(User) + course_user_group = models.ForeignKey(CourseUserGroup, on_delete=models.CASCADE) + user = models.ForeignKey(User, on_delete=models.CASCADE) course_id = CourseKeyField(max_length=255) previous_cohort = None @@ -155,7 +155,7 @@ class CourseUserGroupPartitionGroup(models.Model): """ Create User Partition Info. """ - course_user_group = models.OneToOneField(CourseUserGroup) + course_user_group = models.OneToOneField(CourseUserGroup, on_delete=models.CASCADE) partition_id = models.IntegerField( help_text="contains the id of a cohorted partition in this course" ) @@ -209,7 +209,8 @@ class CourseCohort(models.Model): """ This model represents cohort related info. """ - course_user_group = models.OneToOneField(CourseUserGroup, unique=True, related_name='cohort') + course_user_group = models.OneToOneField(CourseUserGroup, unique=True, related_name='cohort', + on_delete=models.CASCADE) RANDOM = 'random' MANUAL = 'manual' @@ -246,6 +247,6 @@ class UnregisteredLearnerCohortAssignments(DeletableByUserValue, models.Model): class Meta(object): unique_together = (('course_id', 'email'), ) - course_user_group = models.ForeignKey(CourseUserGroup) + course_user_group = models.ForeignKey(CourseUserGroup, on_delete=models.CASCADE) email = models.CharField(blank=True, max_length=255, db_index=True) course_id = CourseKeyField(max_length=255) diff --git a/openedx/core/djangoapps/credit/migrations/0001_initial.py b/openedx/core/djangoapps/credit/migrations/0001_initial.py index bdb4c1d112..3ad57bfe01 100644 --- a/openedx/core/djangoapps/credit/migrations/0001_initial.py +++ b/openedx/core/djangoapps/credit/migrations/0001_initial.py @@ -35,7 +35,7 @@ class Migration(migrations.Migration): ('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)), ('username', models.CharField(max_length=255, db_index=True)), ('deadline', models.DateTimeField(default=openedx.core.djangoapps.credit.models.default_deadline_for_credit_eligibility, help_text='Deadline for purchasing and requesting credit.')), - ('course', models.ForeignKey(related_name='eligibilities', to='credit.CreditCourse')), + ('course', models.ForeignKey(related_name='eligibilities', to='credit.CreditCourse', on_delete=models.CASCADE)), ], options={ 'verbose_name_plural': 'Credit eligibilities', @@ -73,8 +73,8 @@ class Migration(migrations.Migration): ('username', models.CharField(max_length=255, db_index=True)), ('parameters', jsonfield.fields.JSONField()), ('status', models.CharField(default=b'pending', max_length=255, choices=[(b'pending', b'Pending'), (b'approved', b'Approved'), (b'rejected', b'Rejected')])), - ('course', models.ForeignKey(related_name='credit_requests', to='credit.CreditCourse')), - ('provider', models.ForeignKey(related_name='credit_requests', to='credit.CreditProvider')), + ('course', models.ForeignKey(related_name='credit_requests', to='credit.CreditCourse', on_delete=models.CASCADE)), + ('provider', models.ForeignKey(related_name='credit_requests', to='credit.CreditProvider', on_delete=models.CASCADE)), ], options={ 'get_latest_by': 'created', @@ -92,7 +92,7 @@ class Migration(migrations.Migration): ('order', models.PositiveIntegerField(default=0)), ('criteria', jsonfield.fields.JSONField()), ('active', models.BooleanField(default=True)), - ('course', models.ForeignKey(related_name='credit_requirements', to='credit.CreditCourse')), + ('course', models.ForeignKey(related_name='credit_requirements', to='credit.CreditCourse', on_delete=models.CASCADE)), ], options={ 'ordering': ['order'], @@ -107,7 +107,7 @@ class Migration(migrations.Migration): ('username', models.CharField(max_length=255, db_index=True)), ('status', models.CharField(max_length=32, choices=[(b'satisfied', b'satisfied'), (b'failed', b'failed'), (b'declined', b'declined')])), ('reason', jsonfield.fields.JSONField(default={})), - ('requirement', models.ForeignKey(related_name='statuses', to='credit.CreditRequirement')), + ('requirement', models.ForeignKey(related_name='statuses', to='credit.CreditRequirement', on_delete=models.CASCADE)), ], ), migrations.CreateModel( diff --git a/openedx/core/djangoapps/credit/models.py b/openedx/core/djangoapps/credit/models.py index 571b286ee8..ec956eb285 100644 --- a/openedx/core/djangoapps/credit/models.py +++ b/openedx/core/djangoapps/credit/models.py @@ -284,7 +284,7 @@ class CreditRequirement(TimeStampedModel): may need to determine whether a user has satisfied the requirement. """ - course = models.ForeignKey(CreditCourse, related_name="credit_requirements") + course = models.ForeignKey(CreditCourse, related_name="credit_requirements", on_delete=models.CASCADE) namespace = models.CharField(max_length=255) name = models.CharField(max_length=255) display_name = models.CharField(max_length=255, default="") @@ -427,7 +427,7 @@ class CreditRequirementStatus(TimeStampedModel): ) username = models.CharField(max_length=255, db_index=True) - requirement = models.ForeignKey(CreditRequirement, related_name="statuses") + requirement = models.ForeignKey(CreditRequirement, related_name="statuses", on_delete=models.CASCADE) status = models.CharField(max_length=32, choices=REQUIREMENT_STATUS_CHOICES) # Include additional information about why the user satisfied or failed @@ -543,7 +543,7 @@ def default_deadline_for_credit_eligibility(): # pylint: disable=invalid-name class CreditEligibility(TimeStampedModel): """ A record of a user's eligibility for credit for a specific course. """ username = models.CharField(max_length=255, db_index=True) - course = models.ForeignKey(CreditCourse, related_name="eligibilities") + course = models.ForeignKey(CreditCourse, related_name="eligibilities", on_delete=models.CASCADE) # Deadline for when credit eligibility will expire. # Once eligibility expires, users will no longer be able to purchase @@ -656,8 +656,8 @@ class CreditRequest(TimeStampedModel): uuid = models.CharField(max_length=32, unique=True, db_index=True) username = models.CharField(max_length=255, db_index=True) - course = models.ForeignKey(CreditCourse, related_name="credit_requests") - provider = models.ForeignKey(CreditProvider, related_name="credit_requests") + course = models.ForeignKey(CreditCourse, related_name="credit_requests", on_delete=models.CASCADE) + provider = models.ForeignKey(CreditProvider, related_name="credit_requests", on_delete=models.CASCADE) parameters = JSONField() REQUEST_STATUS_PENDING = "pending" diff --git a/openedx/core/djangoapps/embargo/migrations/0001_initial.py b/openedx/core/djangoapps/embargo/migrations/0001_initial.py index 9e3c5c0c7c..045aa06fb7 100644 --- a/openedx/core/djangoapps/embargo/migrations/0001_initial.py +++ b/openedx/core/djangoapps/embargo/migrations/0001_initial.py @@ -30,7 +30,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('rule_type', models.CharField(default=b'blacklist', help_text='Whether to include or exclude the given course. If whitelist countries are specified, then ONLY users from whitelisted countries will be able to access the course. If blacklist countries are specified, then users from blacklisted countries will NOT be able to access the course.', max_length=255, choices=[(b'whitelist', b'Whitelist (allow only these countries)'), (b'blacklist', b'Blacklist (block these countries)')])), - ('country', models.ForeignKey(help_text='The country to which this rule applies.', to='embargo.Country')), + ('country', models.ForeignKey(help_text='The country to which this rule applies.', to='embargo.Country', on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -95,7 +95,7 @@ class Migration(migrations.Migration): migrations.AddField( model_name='countryaccessrule', name='restricted_course', - field=models.ForeignKey(help_text='The course to which this rule applies.', to='embargo.RestrictedCourse'), + field=models.ForeignKey(help_text='The course to which this rule applies.', to='embargo.RestrictedCourse', on_delete=models.CASCADE), ), migrations.AlterUniqueTogether( name='countryaccessrule', diff --git a/openedx/core/djangoapps/embargo/models.py b/openedx/core/djangoapps/embargo/models.py index 54f9eead64..0febdf9644 100644 --- a/openedx/core/djangoapps/embargo/models.py +++ b/openedx/core/djangoapps/embargo/models.py @@ -428,12 +428,14 @@ class CountryAccessRule(models.Model): restricted_course = models.ForeignKey( "RestrictedCourse", - help_text=ugettext_lazy(u"The course to which this rule applies.") + help_text=ugettext_lazy(u"The course to which this rule applies."), + on_delete=models.CASCADE, ) country = models.ForeignKey( "Country", - help_text=ugettext_lazy(u"The country to which this rule applies.") + help_text=ugettext_lazy(u"The country to which this rule applies."), + on_delete=models.CASCADE, ) CACHE_KEY = u"embargo.allowed_countries.{course_key}" diff --git a/openedx/core/djangoapps/external_auth/migrations/0001_initial.py b/openedx/core/djangoapps/external_auth/migrations/0001_initial.py index f68b8f0e88..46bac1ce3b 100644 --- a/openedx/core/djangoapps/external_auth/migrations/0001_initial.py +++ b/openedx/core/djangoapps/external_auth/migrations/0001_initial.py @@ -24,7 +24,7 @@ class Migration(migrations.Migration): ('internal_password', models.CharField(max_length=31, blank=True)), ('dtcreated', models.DateTimeField(auto_now_add=True, verbose_name=b'creation date')), ('dtsignup', models.DateTimeField(null=True, verbose_name=b'signup date')), - ('user', models.OneToOneField(null=True, to=settings.AUTH_USER_MODEL)), + ('user', models.OneToOneField(null=True, to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.AlterUniqueTogether( diff --git a/openedx/core/djangoapps/external_auth/models.py b/openedx/core/djangoapps/external_auth/models.py index fddbaeb3cd..c25529240c 100644 --- a/openedx/core/djangoapps/external_auth/models.py +++ b/openedx/core/djangoapps/external_auth/models.py @@ -26,7 +26,7 @@ class ExternalAuthMap(models.Model): external_credentials = models.TextField(blank=True) # JSON dictionary external_email = models.CharField(max_length=255, db_index=True) external_name = models.CharField(blank=True, max_length=255, db_index=True) - user = models.OneToOneField(User, unique=True, db_index=True, null=True) + user = models.OneToOneField(User, unique=True, db_index=True, null=True, on_delete=models.CASCADE) internal_password = models.CharField(blank=True, max_length=31) # randomly generated dtcreated = models.DateTimeField('creation date', auto_now_add=True) dtsignup = models.DateTimeField('signup date', null=True) # set after signup diff --git a/openedx/core/djangoapps/oauth_dispatch/migrations/0001_initial.py b/openedx/core/djangoapps/oauth_dispatch/migrations/0001_initial.py index 39ea4aaa18..67ac35c2a3 100644 --- a/openedx/core/djangoapps/oauth_dispatch/migrations/0001_initial.py +++ b/openedx/core/djangoapps/oauth_dispatch/migrations/0001_initial.py @@ -16,7 +16,7 @@ class Migration(migrations.Migration): name='RestrictedApplication', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('application', models.ForeignKey(to=settings.OAUTH2_PROVIDER_APPLICATION_MODEL)), + ('application', models.ForeignKey(to=settings.OAUTH2_PROVIDER_APPLICATION_MODEL, on_delete=models.CASCADE)), ], ), ] diff --git a/openedx/core/djangoapps/oauth_dispatch/models.py b/openedx/core/djangoapps/oauth_dispatch/models.py index 406b69fcc6..6c661e3647 100644 --- a/openedx/core/djangoapps/oauth_dispatch/models.py +++ b/openedx/core/djangoapps/oauth_dispatch/models.py @@ -18,7 +18,7 @@ class RestrictedApplication(models.Model): so that they cannot be used to call into APIs. """ - application = models.ForeignKey(oauth2_settings.APPLICATION_MODEL, null=False) + application = models.ForeignKey(oauth2_settings.APPLICATION_MODEL, null=False, on_delete=models.CASCADE) def __unicode__(self): """ diff --git a/openedx/core/djangoapps/schedules/migrations/0001_initial.py b/openedx/core/djangoapps/schedules/migrations/0001_initial.py index 61cae97754..9dd8cc2705 100644 --- a/openedx/core/djangoapps/schedules/migrations/0001_initial.py +++ b/openedx/core/djangoapps/schedules/migrations/0001_initial.py @@ -22,7 +22,7 @@ class Migration(migrations.Migration): ('active', models.BooleanField(default=True, help_text='Indicates if this schedule is actively used')), ('start', models.DateTimeField(help_text='Date this schedule went into effect')), ('upgrade_deadline', models.DateTimeField(help_text='Deadline by which the learner must upgrade to a verified seat', null=True, blank=True)), - ('enrollment', models.OneToOneField(to='student.CourseEnrollment')), + ('enrollment', models.OneToOneField(to='student.CourseEnrollment', on_delete=models.CASCADE)), ], options={ 'verbose_name': 'Schedule', diff --git a/openedx/core/djangoapps/schedules/migrations/0003_scheduleconfig.py b/openedx/core/djangoapps/schedules/migrations/0003_scheduleconfig.py index 67e4e4e493..0bd24a3413 100644 --- a/openedx/core/djangoapps/schedules/migrations/0003_scheduleconfig.py +++ b/openedx/core/djangoapps/schedules/migrations/0003_scheduleconfig.py @@ -25,7 +25,7 @@ class Migration(migrations.Migration): ('enqueue_recurring_nudge', models.BooleanField(default=False)), ('deliver_recurring_nudge', models.BooleanField(default=False)), ('changed_by', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, editable=False, to=settings.AUTH_USER_MODEL, null=True, verbose_name='Changed by')), - ('site', models.ForeignKey(to='sites.Site')), + ('site', models.ForeignKey(to='sites.Site', on_delete=models.CASCADE)), ], options={ 'ordering': ('-change_date',), diff --git a/openedx/core/djangoapps/schedules/migrations/0006_scheduleexperience.py b/openedx/core/djangoapps/schedules/migrations/0006_scheduleexperience.py index df0b41412b..468ad1388b 100644 --- a/openedx/core/djangoapps/schedules/migrations/0006_scheduleexperience.py +++ b/openedx/core/djangoapps/schedules/migrations/0006_scheduleexperience.py @@ -16,7 +16,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('experience_type', models.PositiveSmallIntegerField(default=0, choices=[(0, b'Recurring Nudge and Upgrade Reminder'), (1, b'Course Updates')])), - ('schedule', models.OneToOneField(related_name='experience', to='schedules.Schedule')), + ('schedule', models.OneToOneField(related_name='experience', to='schedules.Schedule', on_delete=models.CASCADE)), ], ), ] diff --git a/openedx/core/djangoapps/schedules/models.py b/openedx/core/djangoapps/schedules/models.py index 2ca8c5f422..1659ab1464 100644 --- a/openedx/core/djangoapps/schedules/models.py +++ b/openedx/core/djangoapps/schedules/models.py @@ -8,7 +8,7 @@ from config_models.models import ConfigurationModel class Schedule(TimeStampedModel): - enrollment = models.OneToOneField('student.CourseEnrollment', null=False) + enrollment = models.OneToOneField('student.CourseEnrollment', null=False, on_delete=models.CASCADE) active = models.BooleanField( default=True, help_text=_('Indicates if this schedule is actively used') @@ -38,7 +38,7 @@ class Schedule(TimeStampedModel): class ScheduleConfig(ConfigurationModel): KEY_FIELDS = ('site',) - site = models.ForeignKey(Site) + site = models.ForeignKey(Site, on_delete=models.CASCADE) create_schedules = models.BooleanField(default=False) enqueue_recurring_nudge = models.BooleanField(default=False) deliver_recurring_nudge = models.BooleanField(default=False) @@ -55,5 +55,5 @@ class ScheduleExperience(models.Model): (1, 'course_updates', 'Course Updates') ) - schedule = models.OneToOneField(Schedule, related_name='experience') + schedule = models.OneToOneField(Schedule, related_name='experience', on_delete=models.CASCADE) experience_type = models.PositiveSmallIntegerField(choices=EXPERIENCES, default=EXPERIENCES.default) diff --git a/openedx/core/djangoapps/site_configuration/migrations/0001_initial.py b/openedx/core/djangoapps/site_configuration/migrations/0001_initial.py index e33f79249b..e6a792b552 100644 --- a/openedx/core/djangoapps/site_configuration/migrations/0001_initial.py +++ b/openedx/core/djangoapps/site_configuration/migrations/0001_initial.py @@ -19,7 +19,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('values', jsonfield.fields.JSONField(blank=True)), - ('site', models.OneToOneField(related_name='configuration', to='sites.Site')), + ('site', models.OneToOneField(related_name='configuration', to='sites.Site', on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -29,7 +29,7 @@ class Migration(migrations.Migration): ('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)), ('values', jsonfield.fields.JSONField(blank=True)), - ('site', models.ForeignKey(related_name='configuration_histories', to='sites.Site')), + ('site', models.ForeignKey(related_name='configuration_histories', to='sites.Site', on_delete=models.CASCADE)), ], options={ 'ordering': ('-modified', '-created'), diff --git a/openedx/core/djangoapps/site_configuration/models.py b/openedx/core/djangoapps/site_configuration/models.py index 2de6d8073d..fcbf032ba9 100644 --- a/openedx/core/djangoapps/site_configuration/models.py +++ b/openedx/core/djangoapps/site_configuration/models.py @@ -23,7 +23,7 @@ class SiteConfiguration(models.Model): site (OneToOneField): one to one field relating each configuration to a single site values (JSONField): json field to store configurations for a site """ - site = models.OneToOneField(Site, related_name='configuration') + site = models.OneToOneField(Site, related_name='configuration', on_delete=models.CASCADE) enabled = models.BooleanField(default=False, verbose_name="Enabled") values = JSONField( null=False, @@ -122,7 +122,7 @@ class SiteConfigurationHistory(TimeStampedModel): site (ForeignKey): foreign-key to django Site values (JSONField): json field to store configurations for a site """ - site = models.ForeignKey(Site, related_name='configuration_histories') + site = models.ForeignKey(Site, related_name='configuration_histories', on_delete=models.CASCADE) enabled = models.BooleanField(default=False, verbose_name="Enabled") values = JSONField( null=False, diff --git a/openedx/core/djangoapps/theming/migrations/0001_initial.py b/openedx/core/djangoapps/theming/migrations/0001_initial.py index ebf80f9d3e..78c906f1c9 100644 --- a/openedx/core/djangoapps/theming/migrations/0001_initial.py +++ b/openedx/core/djangoapps/theming/migrations/0001_initial.py @@ -16,7 +16,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('theme_dir_name', models.CharField(max_length=255)), - ('site', models.ForeignKey(related_name='themes', to='sites.Site')), + ('site', models.ForeignKey(related_name='themes', to='sites.Site', on_delete=models.CASCADE)), ], ), ] diff --git a/openedx/core/djangoapps/theming/models.py b/openedx/core/djangoapps/theming/models.py index da771dcbcd..d06b9312b2 100644 --- a/openedx/core/djangoapps/theming/models.py +++ b/openedx/core/djangoapps/theming/models.py @@ -12,7 +12,7 @@ class SiteTheme(models.Model): `site` field is foreignkey to django Site model `theme_dir_name` contains directory name having Site's theme """ - site = models.ForeignKey(Site, related_name='themes') + site = models.ForeignKey(Site, related_name='themes', on_delete=models.CASCADE) theme_dir_name = models.CharField(max_length=255) def __unicode__(self): diff --git a/openedx/core/djangoapps/user_api/migrations/0001_initial.py b/openedx/core/djangoapps/user_api/migrations/0001_initial.py index 26f4c199e6..79b4e14337 100644 --- a/openedx/core/djangoapps/user_api/migrations/0001_initial.py +++ b/openedx/core/djangoapps/user_api/migrations/0001_initial.py @@ -23,7 +23,7 @@ class Migration(migrations.Migration): ('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)), + ('user', models.ForeignKey(related_name='+', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -35,7 +35,7 @@ class Migration(migrations.Migration): ('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)), + ('user', models.ForeignKey(related_name='+', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -44,7 +44,7 @@ class Migration(migrations.Migration): ('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)), + ('user', models.ForeignKey(related_name='preferences', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], ), migrations.AlterUniqueTogether( diff --git a/openedx/core/djangoapps/user_api/models.py b/openedx/core/djangoapps/user_api/models.py index 8fce760f89..41fa72bcb0 100644 --- a/openedx/core/djangoapps/user_api/models.py +++ b/openedx/core/djangoapps/user_api/models.py @@ -35,7 +35,7 @@ class RetirementStateError(Exception): class UserPreference(models.Model): """A user's preference, stored as generic text to be processed by client""" KEY_REGEX = r"[-_a-zA-Z0-9]+" - user = models.ForeignKey(User, db_index=True, related_name="preferences") + user = models.ForeignKey(User, db_index=True, related_name="preferences", on_delete=models.CASCADE) key = models.CharField(max_length=255, db_index=True, validators=[RegexValidator(KEY_REGEX)]) value = models.TextField() @@ -113,7 +113,7 @@ 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="+") + user = models.ForeignKey(User, db_index=True, related_name="+", on_delete=models.CASCADE) key = models.CharField(max_length=255, db_index=True) course_id = CourseKeyField(max_length=255, db_index=True) value = models.TextField() @@ -129,7 +129,7 @@ class UserOrgTag(TimeStampedModel, DeletableByUserValue): # pylint: disable=mod Allows settings to be configured at an organization level. """ - user = models.ForeignKey(User, db_index=True, related_name="+") + user = models.ForeignKey(User, db_index=True, related_name="+", on_delete=models.CASCADE) key = models.CharField(max_length=255, db_index=True) org = models.CharField(max_length=255, db_index=True) value = models.TextField() @@ -173,7 +173,7 @@ class UserRetirementRequest(TimeStampedModel): Users that have requested to cancel their retirement before retirement begins can be removed. All other retired users persist in this table forever. """ - user = models.OneToOneField(User) + user = models.OneToOneField(User, on_delete=models.CASCADE) class Meta(object): verbose_name = 'User Retirement Request' @@ -203,14 +203,14 @@ class UserRetirementStatus(TimeStampedModel): """ Tracks the progress of a user's retirement request """ - user = models.OneToOneField(User) + user = models.OneToOneField(User, on_delete=models.CASCADE) original_username = models.CharField(max_length=150, db_index=True) original_email = models.EmailField(db_index=True) original_name = models.CharField(max_length=255, blank=True, db_index=True) retired_username = models.CharField(max_length=150, db_index=True) retired_email = models.EmailField(db_index=True) - current_state = models.ForeignKey(RetirementState, related_name='current_state') - last_state = models.ForeignKey(RetirementState, blank=True, related_name='last_state') + current_state = models.ForeignKey(RetirementState, related_name='current_state', on_delete=models.CASCADE) + last_state = models.ForeignKey(RetirementState, blank=True, related_name='last_state', on_delete=models.CASCADE) responses = models.TextField() class Meta(object):