diff --git a/lms/djangoapps/badges/api/urls.py b/lms/djangoapps/badges/api/urls.py index 778c8557d1..95129fafcd 100644 --- a/lms/djangoapps/badges/api/urls.py +++ b/lms/djangoapps/badges/api/urls.py @@ -4,10 +4,11 @@ URLs for badges API from django.conf import settings -from django.conf.urls import url +from django.urls import re_path from .views import UserBadgeAssertions urlpatterns = [ - url('^assertions/user/' + settings.USERNAME_PATTERN + '/$', UserBadgeAssertions.as_view(), name='user_assertions'), + re_path('^assertions/user/' + settings.USERNAME_PATTERN + '/$', + UserBadgeAssertions.as_view(), name='user_assertions'), ] diff --git a/lms/djangoapps/badges/events/course_complete.py b/lms/djangoapps/badges/events/course_complete.py index 4f5804751e..ca34554763 100644 --- a/lms/djangoapps/badges/events/course_complete.py +++ b/lms/djangoapps/badges/events/course_complete.py @@ -8,7 +8,7 @@ import logging from django.urls import reverse from django.utils.text import slugify -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from lms.djangoapps.badges.models import BadgeAssertion, BadgeClass, CourseCompleteImageConfiguration from lms.djangoapps.badges.utils import requires_badges_enabled, site_prefix diff --git a/lms/djangoapps/badges/models.py b/lms/djangoapps/badges/models.py index a6f4978c26..92fff79883 100644 --- a/lms/djangoapps/badges/models.py +++ b/lms/djangoapps/badges/models.py @@ -10,7 +10,7 @@ from django.conf import settings from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user from django.core.exceptions import ValidationError from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from jsonfield import JSONField from lazy import lazy # lint-amnesty, pylint: disable=no-name-in-module from model_utils.models import TimeStampedModel diff --git a/lms/djangoapps/branding/api.py b/lms/djangoapps/branding/api.py index c10915defe..5f4f06d9d2 100644 --- a/lms/djangoapps/branding/api.py +++ b/lms/djangoapps/branding/api.py @@ -19,7 +19,7 @@ import six from django.conf import settings from django.contrib.staticfiles.storage import staticfiles_storage from django.urls import reverse -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from six.moves.urllib.parse import urljoin from common.djangoapps.edxmako.shortcuts import marketing_link diff --git a/lms/djangoapps/branding/api_urls.py b/lms/djangoapps/branding/api_urls.py index ff5cabf506..f9edae0488 100644 --- a/lms/djangoapps/branding/api_urls.py +++ b/lms/djangoapps/branding/api_urls.py @@ -3,10 +3,10 @@ Branding API endpoint urls. """ -from django.conf.urls import url +from django.urls import path from lms.djangoapps.branding.views import footer urlpatterns = [ - url(r"^footer$", footer, name="branding_footer"), + path('footer', footer, name="branding_footer"), ] diff --git a/lms/djangoapps/branding/views.py b/lms/djangoapps/branding/views.py index 7a2d4d827d..303dfde588 100644 --- a/lms/djangoapps/branding/views.py +++ b/lms/djangoapps/branding/views.py @@ -56,7 +56,7 @@ def index(request): ) return redirect(marketing_urls.get('ROOT')) - domain = request.META.get('HTTP_HOST') + domain = request.headers.get('Host') # keep specialized logic for Edge until we can migrate over Edge to fully use # configuration. @@ -257,7 +257,7 @@ def footer(request): raise Http404 # Use the content type to decide what representation to serve - accepts = request.META.get('HTTP_ACCEPT', '*/*') + accepts = request.headers.get('Accept', '*/*') # Show the OpenEdX logo in the footer show_openedx_logo = bool(request.GET.get('show-openedx-logo', False)) diff --git a/lms/djangoapps/bulk_email/tasks.py b/lms/djangoapps/bulk_email/tasks.py index b49eec13c2..8b31d31d57 100644 --- a/lms/djangoapps/bulk_email/tasks.py +++ b/lms/djangoapps/bulk_email/tasks.py @@ -34,7 +34,7 @@ from django.core.mail.message import forbid_multi_line_headers from django.urls import reverse from django.utils import timezone from django.utils.translation import override as override_language -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from edx_django_utils.monitoring import set_code_owner_attribute from markupsafe import escape diff --git a/lms/djangoapps/bulk_email/urls.py b/lms/djangoapps/bulk_email/urls.py index a62fe19752..4909507044 100644 --- a/lms/djangoapps/bulk_email/urls.py +++ b/lms/djangoapps/bulk_email/urls.py @@ -3,12 +3,12 @@ URLs for bulk_email app """ from django.conf import settings -from django.conf.urls import url +from django.urls import re_path from . import views urlpatterns = [ - url( + re_path( r'^email/optout/(?P[a-zA-Z0-9-_=]+)/{}/$'.format( settings.COURSE_ID_PATTERN, ), diff --git a/lms/djangoapps/bulk_enroll/urls.py b/lms/djangoapps/bulk_enroll/urls.py index f9f2ab1c73..326b0ad040 100644 --- a/lms/djangoapps/bulk_enroll/urls.py +++ b/lms/djangoapps/bulk_enroll/urls.py @@ -3,10 +3,10 @@ URLs for the Bulk Enrollment API """ -from django.conf.urls import url +from django.urls import path from .views import BulkEnrollView urlpatterns = [ - url(r'^bulk_enroll', BulkEnrollView.as_view(), name='bulk_enroll'), + path('bulk_enroll', BulkEnrollView.as_view(), name='bulk_enroll'), ] diff --git a/lms/djangoapps/bulk_user_retirement/urls.py b/lms/djangoapps/bulk_user_retirement/urls.py index 49098fb3b1..a2602362e6 100644 --- a/lms/djangoapps/bulk_user_retirement/urls.py +++ b/lms/djangoapps/bulk_user_retirement/urls.py @@ -2,14 +2,14 @@ Defines the URL route for this app. """ -from django.conf.urls import url +from django.urls import path from .views import BulkUsersRetirementView urlpatterns = [ - url( - r'v1/accounts/bulk_retire_users$', + path( + 'v1/accounts/bulk_retire_users', BulkUsersRetirementView.as_view(), name='bulk_retirement_api' ), diff --git a/lms/djangoapps/ccx/api/urls.py b/lms/djangoapps/ccx/api/urls.py index 365edab2e4..e0db57f93d 100644 --- a/lms/djangoapps/ccx/api/urls.py +++ b/lms/djangoapps/ccx/api/urls.py @@ -3,9 +3,9 @@ CCX API URLs. """ -from django.conf.urls import include, url +from django.urls import include, path app_name = 'ccx_api' urlpatterns = [ - url(r'^v0/', include('lms.djangoapps.ccx.api.v0.urls')), + path('v0/', include('lms.djangoapps.ccx.api.v0.urls')), ] diff --git a/lms/djangoapps/ccx/api/v0/urls.py b/lms/djangoapps/ccx/api/v0/urls.py index a89829fcec..7fd8ecbb8e 100644 --- a/lms/djangoapps/ccx/api/v0/urls.py +++ b/lms/djangoapps/ccx/api/v0/urls.py @@ -4,18 +4,18 @@ CCX API v0 URLs. from django.conf import settings -from django.conf.urls import include, url +from django.urls import include, path, re_path from lms.djangoapps.ccx.api.v0 import views CCX_COURSE_ID_PATTERN = settings.COURSE_ID_PATTERN.replace('course_id', 'ccx_course_id') CCX_URLS = ([ - url(r'^$', views.CCXListView.as_view(), name='list'), - url(fr'^{CCX_COURSE_ID_PATTERN}/?$', views.CCXDetailView.as_view(), name='detail'), + path('', views.CCXListView.as_view(), name='list'), + re_path(fr'^{CCX_COURSE_ID_PATTERN}/?$', views.CCXDetailView.as_view(), name='detail'), ], 'ccx') app_name = 'v0' urlpatterns = [ - url(r'^ccx/', include(CCX_URLS)), + path('ccx/', include(CCX_URLS)), ] diff --git a/lms/djangoapps/ccx/plugins.py b/lms/djangoapps/ccx/plugins.py index 3cf16d47b5..39e321bfee 100644 --- a/lms/djangoapps/ccx/plugins.py +++ b/lms/djangoapps/ccx/plugins.py @@ -4,7 +4,7 @@ Registers the CCX feature for the edX platform. from django.conf import settings -from django.utils.translation import ugettext_noop +from django.utils.translation import gettext_noop from common.djangoapps.student.roles import CourseCcxCoachRole from xmodule.tabs import CourseTab @@ -18,7 +18,7 @@ class CcxCourseTab(CourseTab): """ type = "ccx_coach" - title = ugettext_noop("CCX Coach") + title = gettext_noop("CCX Coach") view_name = "ccx_coach_dashboard" is_dynamic = True # The CCX view is dynamically added to the set of tabs when it is enabled diff --git a/lms/djangoapps/ccx/tests/test_views.py b/lms/djangoapps/ccx/tests/test_views.py index 1db7780932..73e37e1bf1 100644 --- a/lms/djangoapps/ccx/tests/test_views.py +++ b/lms/djangoapps/ccx/tests/test_views.py @@ -15,7 +15,7 @@ from django.conf import settings from django.test import RequestFactory from django.test.utils import override_settings from django.urls import resolve, reverse -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from edx_django_utils.cache import RequestCache from opaque_keys.edx.keys import CourseKey from pytz import UTC diff --git a/lms/djangoapps/ccx/urls.py b/lms/djangoapps/ccx/urls.py index c2e2041dc0..931e666c72 100644 --- a/lms/djangoapps/ccx/urls.py +++ b/lms/djangoapps/ccx/urls.py @@ -3,21 +3,21 @@ URLs for the CCX Feature. """ -from django.conf.urls import url +from django.urls import path, re_path from . import views urlpatterns = [ - url(r'^ccx_coach$', views.dashboard, name='ccx_coach_dashboard'), - url(r'^create_ccx$', views.create_ccx, name='create_ccx'), - url(r'^save_ccx$', views.save_ccx, name='save_ccx'), - url(r'^ccx_schedule$', views.ccx_schedule, name='ccx_schedule'), - url(r'^ccx-manage-students$', views.ccx_students_management, name='ccx-manage-students'), + path('ccx_coach', views.dashboard, name='ccx_coach_dashboard'), + path('create_ccx', views.create_ccx, name='create_ccx'), + path('save_ccx', views.save_ccx, name='save_ccx'), + path('ccx_schedule', views.ccx_schedule, name='ccx_schedule'), + path('ccx-manage-students', views.ccx_students_management, name='ccx-manage-students'), # Grade book - url(r'^ccx_gradebook$', views.ccx_gradebook, name='ccx_gradebook'), - url(r'^ccx_gradebook/(?P[0-9]+)$', views.ccx_gradebook, name='ccx_gradebook'), + path('ccx_gradebook', views.ccx_gradebook, name='ccx_gradebook'), + path('ccx_gradebook/', views.ccx_gradebook, name='ccx_gradebook'), - url(r'^ccx_grades.csv$', views.ccx_grades_csv, name='ccx_grades_csv'), - url(r'^ccx_set_grading_policy$', views.set_grading_policy, name='ccx_set_grading_policy'), + re_path(r'^ccx_grades.csv$', views.ccx_grades_csv, name='ccx_grades_csv'), + path('ccx_set_grading_policy', views.set_grading_policy, name='ccx_set_grading_policy'), ] diff --git a/lms/djangoapps/ccx/utils.py b/lms/djangoapps/ccx/utils.py index c6e088b3fb..9f7c0eff39 100644 --- a/lms/djangoapps/ccx/utils.py +++ b/lms/djangoapps/ccx/utils.py @@ -15,7 +15,7 @@ from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imp from django.core.exceptions import ValidationError from django.core.validators import validate_email from django.urls import reverse -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from common.djangoapps.student.models import CourseEnrollment, CourseEnrollmentException from common.djangoapps.student.roles import CourseCcxCoachRole, CourseInstructorRole, CourseStaffRole diff --git a/lms/djangoapps/ccx/views.py b/lms/djangoapps/ccx/views.py index c628b30062..a1f7f1ed82 100644 --- a/lms/djangoapps/ccx/views.py +++ b/lms/djangoapps/ccx/views.py @@ -20,7 +20,7 @@ from django.db import transaction from django.http import Http404, HttpResponse, HttpResponseForbidden from django.shortcuts import redirect from django.urls import reverse -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from django.views.decorators.cache import cache_control from django.views.decorators.csrf import ensure_csrf_cookie from opaque_keys.edx.keys import CourseKey diff --git a/lms/djangoapps/certificates/apis/urls.py b/lms/djangoapps/certificates/apis/urls.py index 41f418e614..5820a00ab5 100644 --- a/lms/djangoapps/certificates/apis/urls.py +++ b/lms/djangoapps/certificates/apis/urls.py @@ -3,9 +3,9 @@ Certificates API URLs. """ -from django.conf.urls import include, url +from django.urls import include, path app_name = 'certificates' urlpatterns = [ - url(r'^v0/', include('lms.djangoapps.certificates.apis.v0.urls')), + path('v0/', include('lms.djangoapps.certificates.apis.v0.urls')), ] diff --git a/lms/djangoapps/certificates/apis/v0/urls.py b/lms/djangoapps/certificates/apis/v0/urls.py index 5ddb35abff..5a10dedc3f 100644 --- a/lms/djangoapps/certificates/apis/v0/urls.py +++ b/lms/djangoapps/certificates/apis/v0/urls.py @@ -4,19 +4,19 @@ Certificates API v0 URLs. from django.conf import settings -from django.conf.urls import include, url +from django.urls import include, path, re_path from lms.djangoapps.certificates.apis.v0 import views CERTIFICATES_URLS = ([ - url( + re_path( r'^{username}/courses/{course_id}/$'.format( username=settings.USERNAME_PATTERN, course_id=settings.COURSE_ID_PATTERN ), views.CertificatesDetailView.as_view(), name='detail' ), - url( + re_path( r'^{username}/$'.format( username=settings.USERNAME_PATTERN ), @@ -26,5 +26,5 @@ CERTIFICATES_URLS = ([ app_name = 'v0' urlpatterns = [ - url(r'^certificates/', include(CERTIFICATES_URLS)), + path('certificates/', include(CERTIFICATES_URLS)), ] diff --git a/lms/djangoapps/certificates/migrations/0012_certificategenerationcoursesetting_include_hours_of_effort.py b/lms/djangoapps/certificates/migrations/0012_certificategenerationcoursesetting_include_hours_of_effort.py index 07203cc783..0761866ad2 100644 --- a/lms/djangoapps/certificates/migrations/0012_certificategenerationcoursesetting_include_hours_of_effort.py +++ b/lms/djangoapps/certificates/migrations/0012_certificategenerationcoursesetting_include_hours_of_effort.py @@ -11,6 +11,6 @@ class Migration(migrations.Migration): migrations.AddField( model_name='certificategenerationcoursesetting', name='include_hours_of_effort', - field=models.NullBooleanField(default=None, help_text="Display estimated time to complete the course, which is equal to the maximum hours of effort per week times the length of the course in weeks. This attribute will only be displayed in a certificate when the attributes 'Weeks to complete' and 'Max effort' have been provided for the course run and its certificate template includes Hours of Effort."), + field=models.BooleanField(default=None, help_text="Display estimated time to complete the course, which is equal to the maximum hours of effort per week times the length of the course in weeks. This attribute will only be displayed in a certificate when the attributes 'Weeks to complete' and 'Max effort' have been provided for the course run and its certificate template includes Hours of Effort.", null=True), ), ] diff --git a/lms/djangoapps/certificates/models.py b/lms/djangoapps/certificates/models.py index 633f8f7642..1a548ffcc4 100644 --- a/lms/djangoapps/certificates/models.py +++ b/lms/djangoapps/certificates/models.py @@ -17,7 +17,7 @@ from django.db import models, transaction from django.db.models import Count from django.dispatch import receiver -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from edx_name_affirmation.api import get_verified_name, should_use_verified_name_for_certs from model_utils import Choices from model_utils.models import TimeStampedModel @@ -974,15 +974,15 @@ class CertificateGenerationCourseSetting(TimeStampedModel): "certificate template." ) ) - include_hours_of_effort = models.NullBooleanField( + include_hours_of_effort = models.BooleanField( default=None, help_text=( "Display estimated time to complete the course, which is equal to the maximum hours of effort per week " "times the length of the course in weeks. This attribute will only be displayed in a certificate when the " "attributes 'Weeks to complete' and 'Max effort' have been provided for the course run and its " "certificate template includes Hours of Effort." - ) - ) + ), + null=True) class Meta: get_latest_by = 'created' diff --git a/lms/djangoapps/certificates/urls.py b/lms/djangoapps/certificates/urls.py index 6e0bd8836e..a7c07f24cb 100644 --- a/lms/djangoapps/certificates/urls.py +++ b/lms/djangoapps/certificates/urls.py @@ -4,27 +4,27 @@ URLs for the certificates app. from django.conf import settings -from django.conf.urls import url +from django.urls import path, re_path from lms.djangoapps.certificates import views app_name = 'certificates' urlpatterns = [ # Certificates HTML view end point to render web certs by user and course - url( + re_path( fr'^user/(?P[^/]*)/course/{settings.COURSE_ID_PATTERN}', views.unsupported_url, name='unsupported_url' ), - url( + re_path( fr'^course/{settings.COURSE_ID_PATTERN}', views.render_preview_certificate, name='preview_cert' ), # Certificates HTML view end point to render web certs by certificate_uuid - url( + re_path( r'^(?P[0-9a-f]{32})$', views.render_cert_by_uuid, name='render_cert_by_uuid' @@ -33,7 +33,7 @@ urlpatterns = [ # End-points used by student support # The views in the lms/djangoapps/support use these end-points # to retrieve certificate information and regenerate certificates. - url(r'^search', views.search_certificates, name="search"), - url(r'^regenerate', views.regenerate_certificate_for_user, name="regenerate_certificate_for_user"), - url(r'^generate', views.generate_certificate_for_user, name="generate_certificate_for_user"), + path('search', views.search_certificates, name="search"), + path('regenerate', views.regenerate_certificate_for_user, name="regenerate_certificate_for_user"), + path('generate', views.generate_certificate_for_user, name="generate_certificate_for_user"), ] diff --git a/lms/djangoapps/certificates/views/support.py b/lms/djangoapps/certificates/views/support.py index a2d934a1d0..67a75f3fa5 100644 --- a/lms/djangoapps/certificates/views/support.py +++ b/lms/djangoapps/certificates/views/support.py @@ -14,7 +14,7 @@ import bleach from django.db import transaction from django.db.models import Q from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden, HttpResponseServerError -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from django.views.decorators.http import require_GET, require_POST from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey diff --git a/lms/djangoapps/certificates/views/webview.py b/lms/djangoapps/certificates/views/webview.py index 7a537c8653..285a65caec 100644 --- a/lms/djangoapps/certificates/views/webview.py +++ b/lms/djangoapps/certificates/views/webview.py @@ -58,7 +58,7 @@ from openedx.core.lib.courses import get_course_by_id from xmodule.data import CertificatesDisplayBehaviors log = logging.getLogger(__name__) -_ = translation.ugettext +_ = translation.gettext INVALID_CERTIFICATE_TEMPLATE_PATH = 'certificates/invalid.html' diff --git a/lms/djangoapps/commerce/api/urls.py b/lms/djangoapps/commerce/api/urls.py index 1bf492b40f..d82e6e5651 100644 --- a/lms/djangoapps/commerce/api/urls.py +++ b/lms/djangoapps/commerce/api/urls.py @@ -3,10 +3,10 @@ API URLs. """ -from django.conf.urls import include, url +from django.urls import include, path app_name = 'commerce' urlpatterns = [ - url(r'^v0/', include('lms.djangoapps.commerce.api.v0.urls')), - url(r'^v1/', include('lms.djangoapps.commerce.api.v1.urls')), + path('v0/', include('lms.djangoapps.commerce.api.v0.urls')), + path('v1/', include('lms.djangoapps.commerce.api.v1.urls')), ] diff --git a/lms/djangoapps/commerce/api/v0/urls.py b/lms/djangoapps/commerce/api/v0/urls.py index 1bedf576ed..7591530b73 100644 --- a/lms/djangoapps/commerce/api/v0/urls.py +++ b/lms/djangoapps/commerce/api/v0/urls.py @@ -3,16 +3,16 @@ API v0 URLs. """ -from django.conf.urls import include, url +from django.urls import include, path, re_path from . import views BASKET_URLS = ([ - url(r'^$', views.BasketsView.as_view(), name='create'), - url(r'^(?P[\w]+)/order/$', views.BasketOrderView.as_view(), name='retrieve_order'), + path('', views.BasketsView.as_view(), name='create'), + re_path(r'^(?P[\w]+)/order/$', views.BasketOrderView.as_view(), name='retrieve_order'), ], 'baskets') app_name = 'v0' urlpatterns = [ - url(r'^baskets/', include(BASKET_URLS)), + path('baskets/', include(BASKET_URLS)), ] diff --git a/lms/djangoapps/commerce/api/v1/serializers.py b/lms/djangoapps/commerce/api/v1/serializers.py index 41e305ef24..5c8d4a5e48 100644 --- a/lms/djangoapps/commerce/api/v1/serializers.py +++ b/lms/djangoapps/commerce/api/v1/serializers.py @@ -4,7 +4,7 @@ from datetime import datetime import pytz -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey from rest_framework import serializers diff --git a/lms/djangoapps/commerce/api/v1/urls.py b/lms/djangoapps/commerce/api/v1/urls.py index 336a24f060..11450f4bac 100644 --- a/lms/djangoapps/commerce/api/v1/urls.py +++ b/lms/djangoapps/commerce/api/v1/urls.py @@ -4,21 +4,21 @@ Commerce URLs from django.conf import settings -from django.conf.urls import include, url +from django.urls import include, path, re_path from . import views COURSE_URLS = ([ - url(r'^$', views.CourseListView.as_view(), name='list'), - url(fr'^{settings.COURSE_ID_PATTERN}/$', views.CourseRetrieveUpdateView.as_view(), name='retrieve_update'), + path('', views.CourseListView.as_view(), name='list'), + re_path(fr'^{settings.COURSE_ID_PATTERN}/$', views.CourseRetrieveUpdateView.as_view(), name='retrieve_update'), ], 'courses') ORDER_URLS = ([ - url(r'^(?P[-\w]+)/$', views.OrderView.as_view(), name='detail'), + re_path(r'^(?P[-\w]+)/$', views.OrderView.as_view(), name='detail'), ], 'orders') app_name = 'v1' urlpatterns = [ - url(r'^courses/', include(COURSE_URLS)), - url(r'^orders/', include(ORDER_URLS)), + path('courses/', include(COURSE_URLS)), + path('orders/', include(ORDER_URLS)), ] diff --git a/lms/djangoapps/commerce/models.py b/lms/djangoapps/commerce/models.py index ca5f98656b..330d7b805f 100644 --- a/lms/djangoapps/commerce/models.py +++ b/lms/djangoapps/commerce/models.py @@ -6,7 +6,7 @@ Commerce-related models. from config_models.models import ConfigurationModel from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ class CommerceConfiguration(ConfigurationModel): diff --git a/lms/djangoapps/commerce/utils.py b/lms/djangoapps/commerce/utils.py index 056c3b3bc0..883a4ba5b2 100644 --- a/lms/djangoapps/commerce/utils.py +++ b/lms/djangoapps/commerce/utils.py @@ -10,7 +10,7 @@ import waffle # lint-amnesty, pylint: disable=invalid-django-waffle-import from django.conf import settings from django.contrib.auth import get_user_model from django.urls import reverse -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from opaque_keys.edx.keys import CourseKey from common.djangoapps.course_modes.models import CourseMode