Repository: uclapi/uclapi

Issue:
Django 2.0 Compatibility
We need to test and assess our code for Django 2.0 compatibility, including checking whether our database code works with the 2.0 breaking changes.


Discussion:
This looks helpful: https://eldarion.com/blog/2017/12/26/10-tips-upgrading-django-20/

Resolving patch:
diff --git a/backend/uclapi/dashboard/models.py b/backend/uclapi/dashboard/models.py
--- a/backend/uclapi/dashboard/models.py
+++ b/backend/uclapi/dashboard/models.py
@@ -39,7 +39,11 @@ class App(models.Model):
         primary_key=True,
         default=generate_app_id
     )
-    user = models.ForeignKey(User, related_name='user')
+    user = models.ForeignKey(
+        User,
+        related_name='user',
+        on_delete=models.CASCADE
+    )
     name = models.CharField(max_length=1000)
     api_token = models.CharField(
         max_length=1000,
@@ -72,8 +76,9 @@ def create_scope():
 
     scope = models.ForeignKey(
         OAuthScope,
-        on_delete=models.CASCADE,
-        default=create_scope)
+        default=create_scope,
+        on_delete=models.CASCADE
+    )
 
     def regenerate_token(self):
         new_token = generate_api_token()
@@ -86,8 +91,16 @@ class Meta:
 
 class APICall(models.Model):
     ts = models.DateTimeField(auto_now_add=True)
-    app = models.ForeignKey(App, related_name='api_call')
-    user = models.ForeignKey(User, related_name='api_call')
+    app = models.ForeignKey(
+        App,
+        on_delete=models.CASCADE,
+        related_name='api_call'
+    )
+    user = models.ForeignKey(
+        User,
+        on_delete=models.CASCADE,
+        related_name='api_call'
+    )
     raw_request = models.TextField(max_length=10000000)
 
     class Meta:
@@ -95,7 +108,7 @@ class Meta:
 
 
 class Webhook(models.Model):
-    app = models.OneToOneField(App)
+    app = models.OneToOneField(App, on_delete=models.CASCADE)
     url = models.URLField(max_length=1000, blank=True)
 
     siteid = models.CharField(max_length=40, blank=True)
@@ -117,7 +130,10 @@ class Meta:
 
 
 class WebhookTriggerHistory(models.Model):
-    webhook = models.ForeignKey(Webhook)
+    webhook = models.ForeignKey(
+        Webhook,
+        on_delete=models.CASCADE
+    )
     payload = models.CharField(max_length=10000000)
 
     timestamp = models.DateTimeField(auto_now_add=True, editable=False)
diff --git a/backend/uclapi/timetable/models.py b/backend/uclapi/timetable/models.py
--- a/backend/uclapi/timetable/models.py
+++ b/backend/uclapi/timetable/models.py
@@ -256,7 +256,7 @@ class Module(models.Model):
     name = models.TextField(max_length=120)
     category = models.TextField(max_length=10, null=True)
     classif = models.TextField(max_length=10)
-    linkcode = models.TextField(primary_key=True, max_length=20)
+    linkcode = models.TextField(max_length=20)
     csize = models.BigIntegerField(null=True, blank=True)
     minsize = models.BigIntegerField(null=True, blank=True)
     maxsize = models.BigIntegerField(null=True, blank=True)
@@ -272,6 +272,7 @@ class Meta:
         managed = False
         db_table = '"CMIS_OWNER"."MODULE"'
         _DATABASE = 'roombookings'
+        unique_together = (("linkcode", "moduleid"),)
 
 
 class ModuleA(models.Model):
@@ -758,6 +759,7 @@ class CrsavailmodulesB(models.Model):
     class Meta:
         _DATABASE = 'gencache'
 
+
 class Timetable(models.Model):
     slotid = models.BigIntegerField(primary_key=True)
     slotentry = models.BigIntegerField(null=True, blank=True)
@@ -1291,10 +1293,10 @@ class Meta:
 
 
 class Modulegroups(models.Model):
-    setid = models.TextField(max_length=10, primary_key=True)
-    moduleid = models.TextField(max_length=12, primary_key=True)
+    setid = models.TextField(max_length=10)
+    moduleid = models.TextField(max_length=12)
     owner = models.TextField(max_length=10)
-    grpcode = models.TextField(max_length=10, primary_key=True)
+    grpcode = models.TextField(max_length=10)
     name = models.TextField(max_length=30, null=True, blank=True)
     csize = models.IntegerField(null=True, blank=True)
     minsize = models.IntegerField(null=True, blank=True)
@@ -1312,6 +1314,7 @@ class Meta:
         managed = False
         db_table = '"CMIS_OWNER"."MODULEGROUPS"'
         _DATABASE = 'roombookings'
+        unique_together = (("setid", "moduleid", "grpcode"),)
 
 
 class ModulegroupsA(models.Model):
diff --git a/backend/uclapi/uclapi/urls.py b/backend/uclapi/uclapi/urls.py
--- a/backend/uclapi/uclapi/urls.py
+++ b/backend/uclapi/uclapi/urls.py
@@ -18,6 +18,9 @@
 from dashboard.views import documentation, home, about
 from marketplace.views import marketplace
 
+
+app_name = "uclapi"
+
 urlpatterns = [
     url(r'^admin/', admin.site.urls),
     url(r'^dashboard/', include('dashboard.urls')),


Test patch: