internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: ocadotechnology/codeforlife-portal

Issue:
From django administration page, in Portal, can't access Teachers or Students
Trying to access a Student or Teacher from the administration page leads to an error:
Failed to load resource: the server responded with a status of 500 (OK)



Discussion:
@eddarmitage , can you share with Chris @PhydeauxLeChien  what you had been doing for this issue? We have a similar problem withas new model on staging. Thanks!

http://stackoverflow.com/questions/5848319/django-admin-hangs-until-timeout-error-for-a-specific-model-when-trying-to-edi

Resolving patch:
diff --git a/portal/admin.py b/portal/admin.py
--- a/portal/admin.py
+++ b/portal/admin.py
@@ -45,6 +45,7 @@
 class ClassAdmin(admin.ModelAdmin):
     search_fields = ['name', 'teacher__new_user__first_name', 'teacher__new_user__last_name']
     list_filter = ['teacher']
+    readonly_fields = ['teacher']
 
 
 class SchoolAdmin(admin.ModelAdmin):
@@ -55,17 +56,22 @@ class SchoolAdmin(admin.ModelAdmin):
 class StudentAdmin(admin.ModelAdmin):
     search_fields = ['new_user__first_name', 'new_user__last_name']
     list_filter = ['class_field', 'class_field__teacher']
+    readonly_fields = ['user', 'new_user']
+    raw_id_fields = ['class_field', 'pending_class_request']
 
 
 class TeacherAdmin(admin.ModelAdmin):
     search_fields = ['new_user__first_name', 'new_user__last_name']
     list_filter = ['school']
+    readonly_fields = ['user', 'new_user']
+    raw_id_fields = ['school', 'pending_join_request']
 
 
 class UserProfileAdmin(admin.ModelAdmin):
     search_fields = ['user__first_name', 'user__last_name', 'new_username', 'user__date_joined']
     list_filter = ['user__date_joined']
     list_display = ['user', 'joined_recently']
+    readonly_fields = ['user']
 
 
 class EmailVerificationAdmin(admin.ModelAdmin):


Test patch:
Repository: ocadotechnology/codeforlife-portal

Issue:
Teaching Resources UKS2 levels guide incorrectly labeled
Currently the resources landing page (https://www.codeforlife.education/teach/materials/#user-guide) and the UKS2 levels guide page (https://www.codeforlife.education/teach/materials/levels_guide_51-109) incorrectly label the guide as starting at level 50. It should state level 51.

![screen shot 2017-04-11 at 11 31 54](https://cloud.githubusercontent.com/assets/18662916/24905680/ae27bea8-1eac-11e7-9ee4-9481a238724e.png)

![screen shot 2017-04-11 at 11 35 18](https://cloud.githubusercontent.com/assets/18662916/24905704/bc77f28e-1eac-11e7-8fd7-099a8b95c80c.png)




Discussion:

Resolving patch:
diff --git a/portal/views/teacher/pdfs.py b/portal/views/teacher/pdfs.py
--- a/portal/views/teacher/pdfs.py
+++ b/portal/views/teacher/pdfs.py
@@ -70,7 +70,7 @@
     },
 
     "levels_guide_51-109": {
-        "title": "Levels Guide 50 - 109",
+        "title": "Levels Guide 51 - 109",
         "description": "Road maps for levels 51 to 109 of Rapid Router.",
         "links": ["levels_guide_1-50"],
         "url": "general_resources/UKS2-levels-guide.pdf",


Test patch:
Repository: ocadotechnology/codeforlife-portal

Issue:
Typo in introduction to coding teaching materials page
https://staging-dot-decent-digit-629.appspot.com/redesign/teach/materials/introduction_to_coding

"This document shows how the progrssion through rapid router levels cover each stage of the computing curriculum for key stages one and two."=> should be progression

PS: is there a typo in this issue?? [#muphryslaw](https://en.wikipedia.org/wiki/Muphry%27s_law)



Discussion:

Resolving patch:
diff --git a/portal/views/teacher/pdfs.py b/portal/views/teacher/pdfs.py
--- a/portal/views/teacher/pdfs.py
+++ b/portal/views/teacher/pdfs.py
@@ -39,7 +39,7 @@
     # .........User Guide........#
     "introduction_to_coding": {
         "title": "Introduction to Coding",
-        "description": "This document shows how the progrssion through rapid router levels cover each stage of the computing curriculum for key stages one and two.",
+        "description": "This document shows how the progression through rapid router levels cover each stage of the computing curriculum for key stages one and two.",
         "links": None,
         "url": "general_resources/introduction_to_coding.pdf",
         "page_origin": "#user-guide"


Test patch:
Repository: ocadotechnology/codeforlife-portal

Issue:
New run on local fails because of latest pillow version
Needs to be set to 2.9


Discussion:

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -53,7 +53,7 @@
         'django-online-status==0.1.0',
 
 
-        'Pillow>=2.9.0',
+        'Pillow==2.9.0',
         'django-reversion==1.9.3',
         'sqlparse',
         'libsass',


Test patch:
Repository: ocadotechnology/codeforlife-portal

Issue:
Redesign: when you create a new class, you stay on the create class form and don't know if it works
So accidentally you create another class by validating the form again :)
Maybe it could redirect to the class list??
cc @j4mesholland 


Discussion:
There are two issues here: 

1. When the user adds a new class, nothing appears to happen (but the class has been added to the section above).

2. One a new class has been added, the user should be redirected to the specific class page (they shouldn't need to press the 'Edit class' button) to get here. We will add an anchor below the subheading that will jump to the 'Add students section'. Updated wireframe for this page to follow shortly.
New wireframe for Edit class page: 

- The subheading has been edited to make it shorter
- A anchor button has been added below the subheading

![teacher dash class detail l desk](https://cloud.githubusercontent.com/assets/18662916/25667130/7e3fac76-301a-11e7-92d8-4a146b6e64ae.png)



Resolving patch:
diff --git a/portal/views/teacher/dashboard.py b/portal/views/teacher/dashboard.py
--- a/portal/views/teacher/dashboard.py
+++ b/portal/views/teacher/dashboard.py
@@ -100,7 +100,10 @@ def dashboard_teacher_view(request, is_admin):
         elif 'create_class' in request.POST:
             anchor = 'new-class'
             create_class_form = ClassCreationForm(request.POST)
-            process_create_class_form(request, teacher)
+            if create_class_form.is_valid():
+                created_class = create_class_new(create_class_form, teacher)
+                messages.success(request, "The class '{className}' has been created successfully.".format(className=created_class.name))
+                return HttpResponseRedirect(reverse_lazy('view_class', kwargs={'access_code': created_class.access_code}))
 
         else:
             anchor = 'account'
@@ -151,13 +154,6 @@ def process_update_school_form(request, school):
         messages.success(request, 'You have updated the details for your school or club successfully.')
 
 
-def process_create_class_form(request, teacher):
-    create_class_form = ClassCreationForm(request.POST)
-    if create_class_form.is_valid():
-        created_class = create_class_new(create_class_form, teacher)
-        messages.success(request, "The class '{className}' has been created successfully.".format(className=created_class.name))
-
-
 def create_class_new(form, teacher):
     classmate_progress = False
     if form.cleaned_data['classmate_progress'] == 'True':


Test patch:
Repository: ocadotechnology/codeforlife-portal

Issue:
2fa is broken
When users with 2fa enabled try to login, they get a 500:
Google Cloud console error:
`KeyError: 'password'
at teach (/base/data/home/apps/e~decent-digit-629/staging:snap-404.401035434925021697/lib/portal/views/home.py:104)
at wrapped (/base/data/home/apps/e~decent-digit-629/staging:snap-404.401035434925021697/lib/ratelimit/decorators.py:50)
at wrapped (/base/data/home/apps/e~decent-digit-629/staging:snap-404.401035434925021697/lib/ratelimit/decorators.py:50)
at get_response (/base/data/home/apps/e~decent-digit-629/staging:snap-404.401035434925021697/lib/django/core/handlers/base.py:132)`



Discussion:

Resolving patch:
diff --git a/portal/views/home.py b/portal/views/home.py
--- a/portal/views/home.py
+++ b/portal/views/home.py
@@ -101,7 +101,7 @@ def teach(request):
                     return render(request, 'portal/2FA_redirect.html', {
                         'form': AuthenticationForm(),
                         'username': request.user.username,
-                        'password': login_form.cleaned_data['password'],
+                        'password': login_form.cleaned_data['teacher_password'],
                     })
                 else:
                     link = reverse('two_factor:profile')
diff --git a/portal/views/home_new.py b/portal/views/home_new.py
--- a/portal/views/home_new.py
+++ b/portal/views/home_new.py
@@ -248,7 +248,7 @@ def process_login_form(request, login_form):
         return render(request, 'portal/2FA_redirect.html', {
             'form': AuthenticationForm(),
             'username': request.user.username,
-            'password': login_form.cleaned_data['password'],
+            'password': login_form.cleaned_data['teacher_password'],
         })
     else:
         link = reverse('two_factor:profile')


Test patch:
Repository: ocadotechnology/codeforlife-portal

Issue:
Prompt text required for the Add Students sections
Currently there is no prompt text in or near the input box for students names.

This section appears on the Onboarding and also Teacher Dashboard sections of the website.

See current page here:
![screen shot 2017-06-13 at 09 56 52](https://user-images.githubusercontent.com/18662916/27074484-286fa22c-501f-11e7-85dd-74f0b3fa70f5.png)

and original wireframe which has prompt text (please use this style, but note that text has changed below):
![teacher onboarding b - add students](https://user-images.githubusercontent.com/18662916/27074536-50c37992-501f-11e7-97a1-642878536b3f.png)
The text mentioned importing a .csv file, which isn't currently possible

_The prompt text should now read:_ 
**You may type students names or copy and paste them from a spreadsheet into this text box.** 

We will add the import .CSV file button option in a later phase.


Discussion:
@j4mesholland It looks like that now:

![add_students_form](https://user-images.githubusercontent.com/15927761/27077847-606b72b4-5029-11e7-8ff8-9ed90c3c2099.png)


Resolving patch:
diff --git a/portal/forms/teach.py b/portal/forms/teach.py
--- a/portal/forms/teach.py
+++ b/portal/forms/teach.py
@@ -474,7 +474,10 @@ def clean(self):
 
 
 class StudentCreationForm(forms.Form):
-    names = forms.CharField(label='names', widget=forms.Textarea)
+    names = forms.CharField(label='names', widget=forms.Textarea(
+        attrs={
+            'placeholder': 'You may type students names or copy and paste them from a spreadsheet into this text box.'
+        }))
 
     def __init__(self, klass, *args, **kwargs):
         self.klass = klass


Test patch:
Repository: ocadotechnology/codeforlife-portal

Issue:
'No 2FA enabled' message appears in onboarding
The message prompting the user to activate 2FA appears when a user registers/goes through the onboarding:
![crumbs](https://user-images.githubusercontent.com/15927761/27228311-fe7318c8-529e-11e7-9f12-528dc5b98f30.png)

Since the user doesn't have a complete account yet, the message shouldn't appear at all during the onboarding.


Discussion:

Resolving patch:
diff --git a/portal/views/home.py b/portal/views/home.py
--- a/portal/views/home.py
+++ b/portal/views/home.py
@@ -252,14 +252,6 @@ def process_login_form(request, login_form):
             'username': request.user.username,
             'password': login_form.cleaned_data['teacher_password'],
         })
-    else:
-        link = reverse('two_factor:profile')
-        messages.info(
-            request, ("You are not currently set up with two-factor authentication. " +
-                      "Use your phone or tablet to enhance your account's security. " +
-                      "Click <a href='" + link + "'>here</a> to find out more and " +
-                      "set it up or go to your account page at any time."),
-            extra_tags='safe')
 
     next_url = request.GET.get('next', None)
     if next_url:
@@ -267,7 +259,7 @@ def process_login_form(request, login_form):
 
     teacher = request.user.userprofile.teacher
 
-    return redirect_user_to_correct_page(teacher)
+    return redirect_user_to_correct_page(request, teacher)
 
 
 def process_student_login_form(request, school_login_form):
@@ -331,12 +323,19 @@ def is_logged_in_as_teacher(request):
     return logged_in_as_teacher
 
 
-def redirect_user_to_correct_page(teacher):
+def redirect_user_to_correct_page(request, teacher):
     if teacher.has_school():
         classes = teacher.class_teacher.all()
         if classes:
             classes_count = classes.count()
             if classes_count > 1 or classes[0].has_students():
+                link = reverse('two_factor:profile')
+                messages.info(
+                    request, ("You are not currently set up with two-factor authentication. " +
+                              "Use your phone or tablet to enhance your account's security.</br>" +
+                              "Click <a href='" + link + "'>here</a> to find out more and " +
+                              "set it up or go to your account page at any time."),
+                    extra_tags='safe')
                 return HttpResponseRedirect(reverse_lazy('dashboard'))
             else:
                 return HttpResponseRedirect(reverse_lazy('onboarding-class',


Test patch:
Repository: ocadotechnology/codeforlife-portal

Issue:
Code For Life logo for the reminders PDFs to update
Currently the student reminder pdf boasts the old logo... 
Should be updated!


Discussion:

Resolving patch:
diff --git a/portal/views/teacher/teach.py b/portal/views/teacher/teach.py
--- a/portal/views/teacher/teach.py
+++ b/portal/views/teacher/teach.py
@@ -687,6 +687,8 @@ def teacher_print_reminder_cards(request, access_code):
     CHARACTER_FILES = ["portal/img/dee.png", "portal/img/kirsty.png", "portal/img/wes.png", "portal/img/nigel.png", "portal/img/phil.png"]
     CHARACTERS = []
 
+    logo_image = ImageReader(staticfiles_storage.path("portal/img/logo_c4l_reminder_card.png"))
+
     for character_file in CHARACTER_FILES:
         character_image = ImageReader(staticfiles_storage.path(character_file))
         character_height = CARD_INNER_HEIGHT
@@ -760,10 +762,8 @@ def drawParagraph(text, position):
         p.setStrokeColor(black)
         p.roundRect(left, bottom, CARD_WIDTH, CARD_HEIGHT, CORNER_RADIUS)
 
-        # header text
-        p.setFillColor(white)
-        p.setFont('Helvetica', 18)
-        p.drawCentredString(inner_left + CARD_INNER_WIDTH / 2, header_bottom + HEADER_HEIGHT * 0.35, '[ code ] for { life }')
+        # header image
+        p.drawImage(logo_image, inner_left, header_bottom + 5, CARD_INNER_WIDTH, HEADER_HEIGHT * 0.6)
 
         # footer text
         p.setFont('Helvetica', 10)
@@ -786,10 +786,10 @@ def drawParagraph(text, position):
         p.drawImage(character['image'], inner_left + CARD_INNER_WIDTH - character['width'], inner_bottom, character['width'], character['height'], mask='auto')
 
         x = (x + 1) % NUM_X
-        compute_show_page(p, x, y, NUM_Y)
+        y = compute_show_page_character(p, x, y, NUM_Y)
         current_student_count += 1
 
-    compute_show_page(p, x, y, NUM_Y)
+    compute_show_page_end(p, x, y)
 
     p.save()
     return response
@@ -811,10 +811,14 @@ def get_student_data(request, klass, student_data):
     return student_data
 
 
-def compute_show_page(p, x, y, NUM_Y):
+def compute_show_page_character(p, x, y, NUM_Y):
     if x == 0:
         y = (y + 1) % NUM_Y
         if y == 0:
             p.showPage()
-    elif x != 0 or y != 0:
+    return y
+
+
+def compute_show_page_end(p, x, y):
+    if x != 0 or y != 0:
         p.showPage()


Test patch:
Repository: ocadotechnology/codeforlife-portal

Issue:
Contact form: email sent message is stuck on top (bad anchor?)
Once the contact form is submitted and the message is sent, the page doesn't reload at the top where the message 'Your message has been sent successfully' appears. Users can be confused as it is not obvious that the message has been sent.


Discussion:
Happens when the form is accessed via the footer link or the header link in the help and support banner. The issue is indeed linked to the anchor value in the url!

Resolving patch:
diff --git a/portal/views/home.py b/portal/views/home.py
--- a/portal/views/home.py
+++ b/portal/views/home.py
@@ -376,6 +376,7 @@ def contact(request):
         increment_count = True
 
         if contact_form.is_valid():
+            anchor = "top"
             email_message = emailMessages.contactEmail(
                 request, contact_form.cleaned_data['name'], contact_form.cleaned_data['telephone'],
                 contact_form.cleaned_data['email'], contact_form.cleaned_data['message'],
@@ -389,7 +390,7 @@ def contact(request):
                        confirmed_email_message['subject'], confirmed_email_message['message'])
 
             messages.success(request, 'Your message was sent successfully.')
-            return HttpResponseRedirect('.')
+            return render(request, 'portal/help-and-support.html', {'form': contact_form, 'anchor': anchor})
         else:
             contact_form = OutputContactForm(request.POST)
             anchor = "contact"


Test patch:
Repository: ocadotechnology/codeforlife-portal

Issue:
Allow blank field for pending request for teachers



Discussion:

Resolving patch:
diff --git a/portal/migrations/0054_pending_join_request_can_be_blank.py b/portal/migrations/0054_pending_join_request_can_be_blank.py
new file mode 100644
--- /dev/null
+++ b/portal/migrations/0054_pending_join_request_can_be_blank.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('portal', '0053_refactor_teacher_student_1'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='teacher',
+            name='pending_join_request',
+            field=models.ForeignKey(related_name='join_request', blank=True, to='portal.School', null=True),
+        ),
+    ]
diff --git a/portal/models.py b/portal/models.py
--- a/portal/models.py
+++ b/portal/models.py
@@ -114,7 +114,7 @@ class Teacher(models.Model):
     new_user = models.OneToOneField(User, related_name='new_teacher', null=True, blank=True)
     school = models.ForeignKey(School, related_name='teacher_school', null=True)
     is_admin = models.BooleanField(default=False)
-    pending_join_request = models.ForeignKey(School, related_name='join_request', null=True)
+    pending_join_request = models.ForeignKey(School, related_name='join_request', null=True, blank=True)
 
     objects = TeacherModelManager()
 


Test patch:
Repository: ocadotechnology/codeforlife-portal

Issue:
Incorrect Resources LK2
Issue flagged by a teacher:

- [x] LKS2 - Session 7 - video download unavailable
- [x] LKS2 - Session 8 - documents shown are for Session 7
Incorrect Resources LK2
Issue flagged by a teacher:

- [x] LKS2 - Session 7 - video download unavailable
- [x] LKS2 - Session 8 - documents shown are for Session 7


Discussion:

Resolving patch:
diff --git a/portal/views/teacher/pdfs.py b/portal/views/teacher/pdfs.py
--- a/portal/views/teacher/pdfs.py
+++ b/portal/views/teacher/pdfs.py
@@ -454,15 +454,15 @@
         "links": ["LKS2_S7_1", "LKS2_S7_2"],
         "url": "KS2/lesson_plans/s7.pdf",
         "video": "https://www.youtube.com/embed/vFGd0v3msRE",
-        "video_download_link": "videos/LKS2_7_Mahana_explains_repeat_functions.mp4",
+        "video_download_link": "videos/KS1_7_Mahana_explains_repeat_functions.mp4",
         "page_origin": "#lks2-sessions"
     },
 
     "lks2_session_8": {
         "title": "LKS2 - Session 8",
         "description": "Applying their programming knowledge to play and evaluate a game challenge.",
-        "links": ["LKS2_S7_1", "LKS2_S7_2"],
-        "url": "KS2/lesson_plans/s7.pdf",
+        "links": ["lks2_self_assessment_sheet"],
+        "url": "KS2/lesson_plans/s8.pdf",
         "page_origin": "#lks2-sessions"
     },
 
@@ -830,7 +830,7 @@
     "UKS2_S8_2": {
         "title": "UKS2 - Session 8 - Sheet 2",
         "description": "To be used with Session 8 lesson plan.",
-        "links": ["uks2_session_7"],
+        "links": ["uks2_session_8"],
         "url": "python/resource_sheets/UKS2-S8-2.pdf",
         "page_origin": "#uks2-resource-sheets"
     },


Test patch:
Repository: ocadotechnology/codeforlife-portal

Issue:
Add handle_turn video to the KS3 materials page



Discussion:

Resolving patch:
diff --git a/portal/views/teacher/pdfs.py b/portal/views/teacher/pdfs.py
--- a/portal/views/teacher/pdfs.py
+++ b/portal/views/teacher/pdfs.py
@@ -929,7 +929,19 @@
         "description": "To be used to understand the AI:MMO game.",
         "links": [],
         "url": "KS3/resource_sheets/KS3-HandleTurn.pdf",
+        "video": "https://www.youtube.com/embed/Mw8CaG47Wek",
+        "video_download_link": "videos/KS3_Understanding_Turn_Based_System.mp4",
         "page_origin": "#ks3-resource-sheets"
     },
 
+    # ...KS3 Assessments...#
+
+    "ks3_teacher_record_sheet": {
+        "title": "KS3 - Teacher Record Sheet",
+        "description": "Document for the teacher to record pupils progress.",
+        "url": "KS3/assessment/teacher_record_sheet.pdf",
+        "links": [],
+        "page_origin": "#ks3-assessments"
+    },
+
 }


Test patch:
Repository: ocadotechnology/codeforlife-portal

Issue:
CMS upgrade



Discussion:

Resolving patch:
diff --git a/portal/autoconfig.py b/portal/autoconfig.py
--- a/portal/autoconfig.py
+++ b/portal/autoconfig.py
@@ -74,7 +74,6 @@
     },
     'PIPELINE_CSS_COMPRESSOR': None,
     'INSTALLED_APPS': [
-        'cms',
         'game',
         'pipeline',
         'portal',
@@ -114,10 +113,6 @@
         'django.contrib.messages.middleware.MessageMiddleware',
         'django.middleware.clickjacking.XFrameOptionsMiddleware',
         'deploy.middleware.exceptionlogging.ExceptionLoggingMiddleware',
-        'cms.middleware.user.CurrentUserMiddleware',
-        'cms.middleware.page.CurrentPageMiddleware',
-        'cms.middleware.toolbar.ToolbarMiddleware',
-        'cms.middleware.language.LanguageCookieMiddleware',
         'portal.middleware.ratelimit_login_attempts.RateLimitLoginAttemptsMiddleware',
         'django_otp.middleware.OTPMiddleware',
     ],
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -29,28 +29,10 @@
         'urllib3==1.10.4',
         'requests==2.7.0',
 
-        'django-cms==3.1.2',
-
         'django-classy-tags==0.6.1',
         'django-treebeard==3.0',
         'django-sekizai==0.8.2',
-        'djangocms-admin-style==0.2.8',
 
-        'djangocms-text-ckeditor==2.6.0',
-        'djangocms-link==1.6.2',
-        'djangocms-snippet==1.5',
-        'djangocms-style==1.5',
-        'djangocms-column==1.5',
-        'djangocms-grid==1.2',
-        'djangocms-oembed==0.5',
-        'djangocms-table==1.2',
-        'djangocms-file==0.1',
-        'djangocms_flash==0.2.0',
-        'djangocms_googlemap==0.3',
-        'djangocms_inherit==0.1',
-        'djangocms_picture==0.1',
-        'djangocms_teaser==0.1',
-        'djangocms_video==0.1',
         'django-online-status==0.1.0',
 
 


Test patch: