diff --git a/cms/envs/common.py b/cms/envs/common.py index 63ae7caaa023..98a003ff20f1 100644 --- a/cms/envs/common.py +++ b/cms/envs/common.py @@ -815,6 +815,7 @@ # other apps that are. Django 1.8 wants to have imported models supported # by installed apps. 'lms.djangoapps.verify_student', + ) diff --git a/common/test/db_cache/bok_choy_data.json b/common/test/db_cache/bok_choy_data.json index 2070ba49bca9..4f77ddc7d1c2 100644 --- a/common/test/db_cache/bok_choy_data.json +++ b/common/test/db_cache/bok_choy_data.json @@ -1 +1 @@ -[{"fields": {"model": "permission", "app_label": "auth"}, "model": "contenttypes.contenttype", "pk": 1}, {"fields": {"model": "group", "app_label": "auth"}, "model": "contenttypes.contenttype", "pk": 2}, {"fields": {"model": "user", "app_label": "auth"}, "model": "contenttypes.contenttype", "pk": 3}, {"fields": {"model": "contenttype", "app_label": "contenttypes"}, "model": "contenttypes.contenttype", "pk": 4}, {"fields": {"model": "session", "app_label": "sessions"}, "model": "contenttypes.contenttype", "pk": 5}, {"fields": {"model": "site", "app_label": "sites"}, "model": "contenttypes.contenttype", "pk": 6}, {"fields": {"model": "taskmeta", "app_label": "djcelery"}, "model": "contenttypes.contenttype", "pk": 7}, {"fields": {"model": "tasksetmeta", "app_label": "djcelery"}, "model": "contenttypes.contenttype", "pk": 8}, {"fields": {"model": "intervalschedule", "app_label": "djcelery"}, "model": "contenttypes.contenttype", "pk": 9}, {"fields": {"model": "crontabschedule", "app_label": "djcelery"}, "model": "contenttypes.contenttype", "pk": 10}, {"fields": {"model": "periodictasks", "app_label": "djcelery"}, "model": "contenttypes.contenttype", "pk": 11}, {"fields": {"model": "periodictask", "app_label": "djcelery"}, "model": "contenttypes.contenttype", "pk": 12}, {"fields": {"model": "workerstate", "app_label": "djcelery"}, "model": "contenttypes.contenttype", "pk": 13}, {"fields": {"model": "taskstate", "app_label": "djcelery"}, "model": "contenttypes.contenttype", "pk": 14}, {"fields": {"model": "globalstatusmessage", "app_label": "status"}, "model": "contenttypes.contenttype", "pk": 15}, {"fields": {"model": "coursemessage", "app_label": "status"}, "model": "contenttypes.contenttype", "pk": 16}, {"fields": {"model": "studentmodule", "app_label": "courseware"}, "model": "contenttypes.contenttype", "pk": 17}, {"fields": {"model": "studentmodulehistory", "app_label": "courseware"}, "model": "contenttypes.contenttype", "pk": 18}, {"fields": {"model": "xmoduleuserstatesummaryfield", "app_label": "courseware"}, "model": "contenttypes.contenttype", "pk": 19}, {"fields": {"model": "xmodulestudentprefsfield", "app_label": "courseware"}, "model": "contenttypes.contenttype", "pk": 20}, {"fields": {"model": "xmodulestudentinfofield", "app_label": "courseware"}, "model": "contenttypes.contenttype", "pk": 21}, {"fields": {"model": "offlinecomputedgrade", "app_label": "courseware"}, "model": "contenttypes.contenttype", "pk": 22}, {"fields": {"model": "offlinecomputedgradelog", "app_label": "courseware"}, "model": "contenttypes.contenttype", "pk": 23}, {"fields": {"model": "studentfieldoverride", "app_label": "courseware"}, "model": "contenttypes.contenttype", "pk": 24}, {"fields": {"model": "anonymoususerid", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 25}, {"fields": {"model": "userstanding", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 26}, {"fields": {"model": "userprofile", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 27}, {"fields": {"model": "usersignupsource", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 28}, {"fields": {"model": "usertestgroup", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 29}, {"fields": {"model": "registration", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 30}, {"fields": {"model": "pendingnamechange", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 31}, {"fields": {"model": "pendingemailchange", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 32}, {"fields": {"model": "passwordhistory", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 33}, {"fields": {"model": "loginfailures", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 34}, {"fields": {"model": "historicalcourseenrollment", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 35}, {"fields": {"model": "courseenrollment", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 36}, {"fields": {"model": "manualenrollmentaudit", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 37}, {"fields": {"model": "courseenrollmentallowed", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 38}, {"fields": {"model": "courseaccessrole", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 39}, {"fields": {"model": "dashboardconfiguration", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 40}, {"fields": {"model": "linkedinaddtoprofileconfiguration", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 41}, {"fields": {"model": "entranceexamconfiguration", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 42}, {"fields": {"model": "languageproficiency", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 43}, {"fields": {"model": "courseenrollmentattribute", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 44}, {"fields": {"model": "enrollmentrefundconfiguration", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 45}, {"fields": {"model": "trackinglog", "app_label": "track"}, "model": "contenttypes.contenttype", "pk": 46}, {"fields": {"model": "ratelimitconfiguration", "app_label": "util"}, "model": "contenttypes.contenttype", "pk": 47}, {"fields": {"model": "certificatewhitelist", "app_label": "certificates"}, "model": "contenttypes.contenttype", "pk": 48}, {"fields": {"model": "generatedcertificate", "app_label": "certificates"}, "model": "contenttypes.contenttype", "pk": 49}, {"fields": {"model": "examplecertificateset", "app_label": "certificates"}, "model": "contenttypes.contenttype", "pk": 50}, {"fields": {"model": "examplecertificate", "app_label": "certificates"}, "model": "contenttypes.contenttype", "pk": 51}, {"fields": {"model": "certificategenerationcoursesetting", "app_label": "certificates"}, "model": "contenttypes.contenttype", "pk": 52}, {"fields": {"model": "certificategenerationconfiguration", "app_label": "certificates"}, "model": "contenttypes.contenttype", "pk": 53}, {"fields": {"model": "certificatehtmlviewconfiguration", "app_label": "certificates"}, "model": "contenttypes.contenttype", "pk": 54}, {"fields": {"model": "badgeassertion", "app_label": "certificates"}, "model": "contenttypes.contenttype", "pk": 55}, {"fields": {"model": "badgeimageconfiguration", "app_label": "certificates"}, "model": "contenttypes.contenttype", "pk": 56}, {"fields": {"model": "certificatetemplate", "app_label": "certificates"}, "model": "contenttypes.contenttype", "pk": 57}, {"fields": {"model": "certificatetemplateasset", "app_label": "certificates"}, "model": "contenttypes.contenttype", "pk": 58}, {"fields": {"model": "instructortask", "app_label": "instructor_task"}, "model": "contenttypes.contenttype", "pk": 59}, {"fields": {"model": "psychometricdata", "app_label": "psychometrics"}, "model": "contenttypes.contenttype", "pk": 60}, {"fields": {"model": "coursesoftware", "app_label": "licenses"}, "model": "contenttypes.contenttype", "pk": 61}, {"fields": {"model": "userlicense", "app_label": "licenses"}, "model": "contenttypes.contenttype", "pk": 62}, {"fields": {"model": "courseusergroup", "app_label": "course_groups"}, "model": "contenttypes.contenttype", "pk": 63}, {"fields": {"model": "cohortmembership", "app_label": "course_groups"}, "model": "contenttypes.contenttype", "pk": 64}, {"fields": {"model": "courseusergrouppartitiongroup", "app_label": "course_groups"}, "model": "contenttypes.contenttype", "pk": 65}, {"fields": {"model": "coursecohortssettings", "app_label": "course_groups"}, "model": "contenttypes.contenttype", "pk": 66}, {"fields": {"model": "coursecohort", "app_label": "course_groups"}, "model": "contenttypes.contenttype", "pk": 67}, {"fields": {"model": "courseemail", "app_label": "bulk_email"}, "model": "contenttypes.contenttype", "pk": 68}, {"fields": {"model": "optout", "app_label": "bulk_email"}, "model": "contenttypes.contenttype", "pk": 69}, {"fields": {"model": "courseemailtemplate", "app_label": "bulk_email"}, "model": "contenttypes.contenttype", "pk": 70}, {"fields": {"model": "courseauthorization", "app_label": "bulk_email"}, "model": "contenttypes.contenttype", "pk": 71}, {"fields": {"model": "brandinginfoconfig", "app_label": "branding"}, "model": "contenttypes.contenttype", "pk": 72}, {"fields": {"model": "brandingapiconfig", "app_label": "branding"}, "model": "contenttypes.contenttype", "pk": 73}, {"fields": {"model": "externalauthmap", "app_label": "external_auth"}, "model": "contenttypes.contenttype", "pk": 74}, {"fields": {"model": "nonce", "app_label": "django_openid_auth"}, "model": "contenttypes.contenttype", "pk": 75}, {"fields": {"model": "association", "app_label": "django_openid_auth"}, "model": "contenttypes.contenttype", "pk": 76}, {"fields": {"model": "useropenid", "app_label": "django_openid_auth"}, "model": "contenttypes.contenttype", "pk": 77}, {"fields": {"model": "client", "app_label": "oauth2"}, "model": "contenttypes.contenttype", "pk": 78}, {"fields": {"model": "grant", "app_label": "oauth2"}, "model": "contenttypes.contenttype", "pk": 79}, {"fields": {"model": "accesstoken", "app_label": "oauth2"}, "model": "contenttypes.contenttype", "pk": 80}, {"fields": {"model": "refreshtoken", "app_label": "oauth2"}, "model": "contenttypes.contenttype", "pk": 81}, {"fields": {"model": "trustedclient", "app_label": "oauth2_provider"}, "model": "contenttypes.contenttype", "pk": 82}, {"fields": {"model": "oauth2providerconfig", "app_label": "third_party_auth"}, "model": "contenttypes.contenttype", "pk": 83}, {"fields": {"model": "samlproviderconfig", "app_label": "third_party_auth"}, "model": "contenttypes.contenttype", "pk": 84}, {"fields": {"model": "samlconfiguration", "app_label": "third_party_auth"}, "model": "contenttypes.contenttype", "pk": 85}, {"fields": {"model": "samlproviderdata", "app_label": "third_party_auth"}, "model": "contenttypes.contenttype", "pk": 86}, {"fields": {"model": "ltiproviderconfig", "app_label": "third_party_auth"}, "model": "contenttypes.contenttype", "pk": 87}, {"fields": {"model": "providerapipermissions", "app_label": "third_party_auth"}, "model": "contenttypes.contenttype", "pk": 88}, {"fields": {"model": "nonce", "app_label": "oauth_provider"}, "model": "contenttypes.contenttype", "pk": 89}, {"fields": {"model": "scope", "app_label": "oauth_provider"}, "model": "contenttypes.contenttype", "pk": 90}, {"fields": {"model": "consumer", "app_label": "oauth_provider"}, "model": "contenttypes.contenttype", "pk": 91}, {"fields": {"model": "token", "app_label": "oauth_provider"}, "model": "contenttypes.contenttype", "pk": 92}, {"fields": {"model": "resource", "app_label": "oauth_provider"}, "model": "contenttypes.contenttype", "pk": 93}, {"fields": {"model": "article", "app_label": "wiki"}, "model": "contenttypes.contenttype", "pk": 94}, {"fields": {"model": "articleforobject", "app_label": "wiki"}, "model": "contenttypes.contenttype", "pk": 95}, {"fields": {"model": "articlerevision", "app_label": "wiki"}, "model": "contenttypes.contenttype", "pk": 96}, {"fields": {"model": "urlpath", "app_label": "wiki"}, "model": "contenttypes.contenttype", "pk": 97}, {"fields": {"model": "articleplugin", "app_label": "wiki"}, "model": "contenttypes.contenttype", "pk": 98}, {"fields": {"model": "reusableplugin", "app_label": "wiki"}, "model": "contenttypes.contenttype", "pk": 99}, {"fields": {"model": "simpleplugin", "app_label": "wiki"}, "model": "contenttypes.contenttype", "pk": 100}, {"fields": {"model": "revisionplugin", "app_label": "wiki"}, "model": "contenttypes.contenttype", "pk": 101}, {"fields": {"model": "revisionpluginrevision", "app_label": "wiki"}, "model": "contenttypes.contenttype", "pk": 102}, {"fields": {"model": "image", "app_label": "wiki"}, "model": "contenttypes.contenttype", "pk": 103}, {"fields": {"model": "imagerevision", "app_label": "wiki"}, "model": "contenttypes.contenttype", "pk": 104}, {"fields": {"model": "attachment", "app_label": "wiki"}, "model": "contenttypes.contenttype", "pk": 105}, {"fields": {"model": "attachmentrevision", "app_label": "wiki"}, "model": "contenttypes.contenttype", "pk": 106}, {"fields": {"model": "notificationtype", "app_label": "django_notify"}, "model": "contenttypes.contenttype", "pk": 107}, {"fields": {"model": "settings", "app_label": "django_notify"}, "model": "contenttypes.contenttype", "pk": 108}, {"fields": {"model": "subscription", "app_label": "django_notify"}, "model": "contenttypes.contenttype", "pk": 109}, {"fields": {"model": "notification", "app_label": "django_notify"}, "model": "contenttypes.contenttype", "pk": 110}, {"fields": {"model": "score", "app_label": "foldit"}, "model": "contenttypes.contenttype", "pk": 111}, {"fields": {"model": "puzzlecomplete", "app_label": "foldit"}, "model": "contenttypes.contenttype", "pk": 112}, {"fields": {"model": "logentry", "app_label": "admin"}, "model": "contenttypes.contenttype", "pk": 113}, {"fields": {"model": "role", "app_label": "django_comment_common"}, "model": "contenttypes.contenttype", "pk": 114}, {"fields": {"model": "permission", "app_label": "django_comment_common"}, "model": "contenttypes.contenttype", "pk": 115}, {"fields": {"model": "note", "app_label": "notes"}, "model": "contenttypes.contenttype", "pk": 116}, {"fields": {"model": "splashconfig", "app_label": "splash"}, "model": "contenttypes.contenttype", "pk": 117}, {"fields": {"model": "userpreference", "app_label": "user_api"}, "model": "contenttypes.contenttype", "pk": 118}, {"fields": {"model": "usercoursetag", "app_label": "user_api"}, "model": "contenttypes.contenttype", "pk": 119}, {"fields": {"model": "userorgtag", "app_label": "user_api"}, "model": "contenttypes.contenttype", "pk": 120}, {"fields": {"model": "order", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 121}, {"fields": {"model": "orderitem", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 122}, {"fields": {"model": "invoice", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 123}, {"fields": {"model": "invoicetransaction", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 124}, {"fields": {"model": "invoiceitem", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 125}, {"fields": {"model": "courseregistrationcodeinvoiceitem", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 126}, {"fields": {"model": "invoicehistory", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 127}, {"fields": {"model": "courseregistrationcode", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 128}, {"fields": {"model": "registrationcoderedemption", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 129}, {"fields": {"model": "coupon", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 130}, {"fields": {"model": "couponredemption", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 131}, {"fields": {"model": "paidcourseregistration", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 132}, {"fields": {"model": "courseregcodeitem", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 133}, {"fields": {"model": "courseregcodeitemannotation", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 134}, {"fields": {"model": "paidcourseregistrationannotation", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 135}, {"fields": {"model": "certificateitem", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 136}, {"fields": {"model": "donationconfiguration", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 137}, {"fields": {"model": "donation", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 138}, {"fields": {"model": "coursemode", "app_label": "course_modes"}, "model": "contenttypes.contenttype", "pk": 139}, {"fields": {"model": "coursemodesarchive", "app_label": "course_modes"}, "model": "contenttypes.contenttype", "pk": 140}, {"fields": {"model": "softwaresecurephotoverification", "app_label": "verify_student"}, "model": "contenttypes.contenttype", "pk": 141}, {"fields": {"model": "historicalverificationdeadline", "app_label": "verify_student"}, "model": "contenttypes.contenttype", "pk": 142}, {"fields": {"model": "verificationdeadline", "app_label": "verify_student"}, "model": "contenttypes.contenttype", "pk": 143}, {"fields": {"model": "verificationcheckpoint", "app_label": "verify_student"}, "model": "contenttypes.contenttype", "pk": 144}, {"fields": {"model": "verificationstatus", "app_label": "verify_student"}, "model": "contenttypes.contenttype", "pk": 145}, {"fields": {"model": "incoursereverificationconfiguration", "app_label": "verify_student"}, "model": "contenttypes.contenttype", "pk": 146}, {"fields": {"model": "icrvstatusemailsconfiguration", "app_label": "verify_student"}, "model": "contenttypes.contenttype", "pk": 147}, {"fields": {"model": "skippedreverification", "app_label": "verify_student"}, "model": "contenttypes.contenttype", "pk": 148}, {"fields": {"model": "darklangconfig", "app_label": "dark_lang"}, "model": "contenttypes.contenttype", "pk": 149}, {"fields": {"model": "embargoedcourse", "app_label": "embargo"}, "model": "contenttypes.contenttype", "pk": 150}, {"fields": {"model": "embargoedstate", "app_label": "embargo"}, "model": "contenttypes.contenttype", "pk": 151}, {"fields": {"model": "restrictedcourse", "app_label": "embargo"}, "model": "contenttypes.contenttype", "pk": 152}, {"fields": {"model": "country", "app_label": "embargo"}, "model": "contenttypes.contenttype", "pk": 153}, {"fields": {"model": "countryaccessrule", "app_label": "embargo"}, "model": "contenttypes.contenttype", "pk": 154}, {"fields": {"model": "courseaccessrulehistory", "app_label": "embargo"}, "model": "contenttypes.contenttype", "pk": 155}, {"fields": {"model": "ipfilter", "app_label": "embargo"}, "model": "contenttypes.contenttype", "pk": 156}, {"fields": {"model": "coursererunstate", "app_label": "course_action_state"}, "model": "contenttypes.contenttype", "pk": 157}, {"fields": {"model": "mobileapiconfig", "app_label": "mobile_api"}, "model": "contenttypes.contenttype", "pk": 158}, {"fields": {"model": "usersocialauth", "app_label": "default"}, "model": "contenttypes.contenttype", "pk": 159}, {"fields": {"model": "nonce", "app_label": "default"}, "model": "contenttypes.contenttype", "pk": 160}, {"fields": {"model": "association", "app_label": "default"}, "model": "contenttypes.contenttype", "pk": 161}, {"fields": {"model": "code", "app_label": "default"}, "model": "contenttypes.contenttype", "pk": 162}, {"fields": {"model": "surveyform", "app_label": "survey"}, "model": "contenttypes.contenttype", "pk": 163}, {"fields": {"model": "surveyanswer", "app_label": "survey"}, "model": "contenttypes.contenttype", "pk": 164}, {"fields": {"model": "xblockasidesconfig", "app_label": "lms_xblock"}, "model": "contenttypes.contenttype", "pk": 165}, {"fields": {"model": "courseoverview", "app_label": "course_overviews"}, "model": "contenttypes.contenttype", "pk": 166}, {"fields": {"model": "courseoverviewtab", "app_label": "course_overviews"}, "model": "contenttypes.contenttype", "pk": 167}, {"fields": {"model": "coursestructure", "app_label": "course_structures"}, "model": "contenttypes.contenttype", "pk": 168}, {"fields": {"model": "corsmodel", "app_label": "corsheaders"}, "model": "contenttypes.contenttype", "pk": 169}, {"fields": {"model": "xdomainproxyconfiguration", "app_label": "cors_csrf"}, "model": "contenttypes.contenttype", "pk": 170}, {"fields": {"model": "creditprovider", "app_label": "credit"}, "model": "contenttypes.contenttype", "pk": 171}, {"fields": {"model": "creditcourse", "app_label": "credit"}, "model": "contenttypes.contenttype", "pk": 172}, {"fields": {"model": "creditrequirement", "app_label": "credit"}, "model": "contenttypes.contenttype", "pk": 173}, {"fields": {"model": "historicalcreditrequirementstatus", "app_label": "credit"}, "model": "contenttypes.contenttype", "pk": 174}, {"fields": {"model": "creditrequirementstatus", "app_label": "credit"}, "model": "contenttypes.contenttype", "pk": 175}, {"fields": {"model": "crediteligibility", "app_label": "credit"}, "model": "contenttypes.contenttype", "pk": 176}, {"fields": {"model": "historicalcreditrequest", "app_label": "credit"}, "model": "contenttypes.contenttype", "pk": 177}, {"fields": {"model": "creditrequest", "app_label": "credit"}, "model": "contenttypes.contenttype", "pk": 178}, {"fields": {"model": "courseteam", "app_label": "teams"}, "model": "contenttypes.contenttype", "pk": 179}, {"fields": {"model": "courseteammembership", "app_label": "teams"}, "model": "contenttypes.contenttype", "pk": 180}, {"fields": {"model": "xblockdisableconfig", "app_label": "xblock_django"}, "model": "contenttypes.contenttype", "pk": 181}, {"fields": {"model": "programsapiconfig", "app_label": "programs"}, "model": "contenttypes.contenttype", "pk": 182}, {"fields": {"model": "selfpacedconfiguration", "app_label": "self_paced"}, "model": "contenttypes.contenttype", "pk": 183}, {"fields": {"model": "kvstore", "app_label": "thumbnail"}, "model": "contenttypes.contenttype", "pk": 184}, {"fields": {"model": "studentitem", "app_label": "submissions"}, "model": "contenttypes.contenttype", "pk": 185}, {"fields": {"model": "submission", "app_label": "submissions"}, "model": "contenttypes.contenttype", "pk": 186}, {"fields": {"model": "score", "app_label": "submissions"}, "model": "contenttypes.contenttype", "pk": 187}, {"fields": {"model": "scoresummary", "app_label": "submissions"}, "model": "contenttypes.contenttype", "pk": 188}, {"fields": {"model": "rubric", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 189}, {"fields": {"model": "criterion", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 190}, {"fields": {"model": "criterionoption", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 191}, {"fields": {"model": "assessment", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 192}, {"fields": {"model": "assessmentpart", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 193}, {"fields": {"model": "assessmentfeedbackoption", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 194}, {"fields": {"model": "assessmentfeedback", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 195}, {"fields": {"model": "peerworkflow", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 196}, {"fields": {"model": "peerworkflowitem", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 197}, {"fields": {"model": "trainingexample", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 198}, {"fields": {"model": "studenttrainingworkflow", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 199}, {"fields": {"model": "studenttrainingworkflowitem", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 200}, {"fields": {"model": "aiclassifierset", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 201}, {"fields": {"model": "aiclassifier", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 202}, {"fields": {"model": "aitrainingworkflow", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 203}, {"fields": {"model": "aigradingworkflow", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 204}, {"fields": {"model": "assessmentworkflow", "app_label": "workflow"}, "model": "contenttypes.contenttype", "pk": 205}, {"fields": {"model": "assessmentworkflowstep", "app_label": "workflow"}, "model": "contenttypes.contenttype", "pk": 206}, {"fields": {"model": "assessmentworkflowcancellation", "app_label": "workflow"}, "model": "contenttypes.contenttype", "pk": 207}, {"fields": {"model": "profile", "app_label": "edxval"}, "model": "contenttypes.contenttype", "pk": 208}, {"fields": {"model": "video", "app_label": "edxval"}, "model": "contenttypes.contenttype", "pk": 209}, {"fields": {"model": "coursevideo", "app_label": "edxval"}, "model": "contenttypes.contenttype", "pk": 210}, {"fields": {"model": "encodedvideo", "app_label": "edxval"}, "model": "contenttypes.contenttype", "pk": 211}, {"fields": {"model": "subtitle", "app_label": "edxval"}, "model": "contenttypes.contenttype", "pk": 212}, {"fields": {"model": "milestone", "app_label": "milestones"}, "model": "contenttypes.contenttype", "pk": 213}, {"fields": {"model": "milestonerelationshiptype", "app_label": "milestones"}, "model": "contenttypes.contenttype", "pk": 214}, {"fields": {"model": "coursemilestone", "app_label": "milestones"}, "model": "contenttypes.contenttype", "pk": 215}, {"fields": {"model": "coursecontentmilestone", "app_label": "milestones"}, "model": "contenttypes.contenttype", "pk": 216}, {"fields": {"model": "usermilestone", "app_label": "milestones"}, "model": "contenttypes.contenttype", "pk": 217}, {"fields": {"model": "proctoredexam", "app_label": "edx_proctoring"}, "model": "contenttypes.contenttype", "pk": 218}, {"fields": {"model": "proctoredexamreviewpolicy", "app_label": "edx_proctoring"}, "model": "contenttypes.contenttype", "pk": 219}, {"fields": {"model": "proctoredexamreviewpolicyhistory", "app_label": "edx_proctoring"}, "model": "contenttypes.contenttype", "pk": 220}, {"fields": {"model": "proctoredexamstudentattempt", "app_label": "edx_proctoring"}, "model": "contenttypes.contenttype", "pk": 221}, {"fields": {"model": "proctoredexamstudentattempthistory", "app_label": "edx_proctoring"}, "model": "contenttypes.contenttype", "pk": 222}, {"fields": {"model": "proctoredexamstudentallowance", "app_label": "edx_proctoring"}, "model": "contenttypes.contenttype", "pk": 223}, {"fields": {"model": "proctoredexamstudentallowancehistory", "app_label": "edx_proctoring"}, "model": "contenttypes.contenttype", "pk": 224}, {"fields": {"model": "proctoredexamsoftwaresecurereview", "app_label": "edx_proctoring"}, "model": "contenttypes.contenttype", "pk": 225}, {"fields": {"model": "proctoredexamsoftwaresecurereviewhistory", "app_label": "edx_proctoring"}, "model": "contenttypes.contenttype", "pk": 226}, {"fields": {"model": "proctoredexamsoftwaresecurecomment", "app_label": "edx_proctoring"}, "model": "contenttypes.contenttype", "pk": 227}, {"fields": {"model": "organization", "app_label": "organizations"}, "model": "contenttypes.contenttype", "pk": 228}, {"fields": {"model": "organizationcourse", "app_label": "organizations"}, "model": "contenttypes.contenttype", "pk": 229}, {"fields": {"model": "videouploadconfig", "app_label": "contentstore"}, "model": "contenttypes.contenttype", "pk": 230}, {"fields": {"model": "pushnotificationconfig", "app_label": "contentstore"}, "model": "contenttypes.contenttype", "pk": 231}, {"fields": {"model": "coursecreator", "app_label": "course_creators"}, "model": "contenttypes.contenttype", "pk": 232}, {"fields": {"model": "studioconfig", "app_label": "xblock_config"}, "model": "contenttypes.contenttype", "pk": 233}, {"fields": {"domain": "example.com", "name": "example.com"}, "model": "sites.site", "pk": 1}, {"fields": {"default": false, "mode": "honor", "icon": "badges/honor_MDmkxcI.png"}, "model": "certificates.badgeimageconfiguration", "pk": 1}, {"fields": {"default": false, "mode": "verified", "icon": "badges/verified_UjvtLzD.png"}, "model": "certificates.badgeimageconfiguration", "pk": 2}, {"fields": {"default": false, "mode": "professional", "icon": "badges/professional_Lg7aA7P.png"}, "model": "certificates.badgeimageconfiguration", "pk": 3}, {"fields": {"plain_template": "{course_title}\n\n{{message_body}}\r\n----\r\nCopyright 2013 edX, All rights reserved.\r\n----\r\nConnect with edX:\r\nFacebook (http://facebook.com/edxonline)\r\nTwitter (http://twitter.com/edxonline)\r\nGoogle+ (https://plus.google.com/108235383044095082735)\r\nMeetup (http://www.meetup.com/edX-Communities/)\r\n----\r\nThis email was automatically sent from {platform_name}.\r\nYou are receiving this email at address {email} because you are enrolled in {course_title}\r\n(URL: {course_url} ).\r\nTo stop receiving email like this, update your course email settings at {email_settings_url}.\r\n", "html_template": " Update from {course_title}

edX
Connect with edX:        

{course_title}


{{message_body}}
       
Copyright \u00a9 2013 edX, All rights reserved.


Our mailing address is:
edX
11 Cambridge Center, Suite 101
Cambridge, MA, USA 02142


This email was automatically sent from {platform_name}.
You are receiving this email at address {email} because you are enrolled in {course_title}.
To stop receiving email like this, update your course email settings here.
", "name": null}, "model": "bulk_email.courseemailtemplate", "pk": 1}, {"fields": {"plain_template": "THIS IS A BRANDED TEXT TEMPLATE. {course_title}\n\n{{message_body}}\r\n----\r\nCopyright 2013 edX, All rights reserved.\r\n----\r\nConnect with edX:\r\nFacebook (http://facebook.com/edxonline)\r\nTwitter (http://twitter.com/edxonline)\r\nGoogle+ (https://plus.google.com/108235383044095082735)\r\nMeetup (http://www.meetup.com/edX-Communities/)\r\n----\r\nThis email was automatically sent from {platform_name}.\r\nYou are receiving this email at address {email} because you are enrolled in {course_title}\r\n(URL: {course_url} ).\r\nTo stop receiving email like this, update your course email settings at {email_settings_url}.\r\n", "html_template": " THIS IS A BRANDED HTML TEMPLATE Update from {course_title}

edX
Connect with edX:        

{course_title}


{{message_body}}
       
Copyright \u00a9 2013 edX, All rights reserved.


Our mailing address is:
edX
11 Cambridge Center, Suite 101
Cambridge, MA, USA 02142


This email was automatically sent from {platform_name}.
You are receiving this email at address {email} because you are enrolled in {course_title}.
To stop receiving email like this, update your course email settings here.
", "name": "branded.template"}, "model": "bulk_email.courseemailtemplate", "pk": 2}, {"fields": {"country": "AF"}, "model": "embargo.country", "pk": 1}, {"fields": {"country": "AX"}, "model": "embargo.country", "pk": 2}, {"fields": {"country": "AL"}, "model": "embargo.country", "pk": 3}, {"fields": {"country": "DZ"}, "model": "embargo.country", "pk": 4}, {"fields": {"country": "AS"}, "model": "embargo.country", "pk": 5}, {"fields": {"country": "AD"}, "model": "embargo.country", "pk": 6}, {"fields": {"country": "AO"}, "model": "embargo.country", "pk": 7}, {"fields": {"country": "AI"}, "model": "embargo.country", "pk": 8}, {"fields": {"country": "AQ"}, "model": "embargo.country", "pk": 9}, {"fields": {"country": "AG"}, "model": "embargo.country", "pk": 10}, {"fields": {"country": "AR"}, "model": "embargo.country", "pk": 11}, {"fields": {"country": "AM"}, "model": "embargo.country", "pk": 12}, {"fields": {"country": "AW"}, "model": "embargo.country", "pk": 13}, {"fields": {"country": "AU"}, "model": "embargo.country", "pk": 14}, {"fields": {"country": "AT"}, "model": "embargo.country", "pk": 15}, {"fields": {"country": "AZ"}, "model": "embargo.country", "pk": 16}, {"fields": {"country": "BS"}, "model": "embargo.country", "pk": 17}, {"fields": {"country": "BH"}, "model": "embargo.country", "pk": 18}, {"fields": {"country": "BD"}, "model": "embargo.country", "pk": 19}, {"fields": {"country": "BB"}, "model": "embargo.country", "pk": 20}, {"fields": {"country": "BY"}, "model": "embargo.country", "pk": 21}, {"fields": {"country": "BE"}, "model": "embargo.country", "pk": 22}, {"fields": {"country": "BZ"}, "model": "embargo.country", "pk": 23}, {"fields": {"country": "BJ"}, "model": "embargo.country", "pk": 24}, {"fields": {"country": "BM"}, "model": "embargo.country", "pk": 25}, {"fields": {"country": "BT"}, "model": "embargo.country", "pk": 26}, {"fields": {"country": "BO"}, "model": "embargo.country", "pk": 27}, {"fields": {"country": "BQ"}, "model": "embargo.country", "pk": 28}, {"fields": {"country": "BA"}, "model": "embargo.country", "pk": 29}, {"fields": {"country": "BW"}, "model": "embargo.country", "pk": 30}, {"fields": {"country": "BV"}, "model": "embargo.country", "pk": 31}, {"fields": {"country": "BR"}, "model": "embargo.country", "pk": 32}, {"fields": {"country": "IO"}, "model": "embargo.country", "pk": 33}, {"fields": {"country": "BN"}, "model": "embargo.country", "pk": 34}, {"fields": {"country": "BG"}, "model": "embargo.country", "pk": 35}, {"fields": {"country": "BF"}, "model": "embargo.country", "pk": 36}, {"fields": {"country": "BI"}, "model": "embargo.country", "pk": 37}, {"fields": {"country": "CV"}, "model": "embargo.country", "pk": 38}, {"fields": {"country": "KH"}, "model": "embargo.country", "pk": 39}, {"fields": {"country": "CM"}, "model": "embargo.country", "pk": 40}, {"fields": {"country": "CA"}, "model": "embargo.country", "pk": 41}, {"fields": {"country": "KY"}, "model": "embargo.country", "pk": 42}, {"fields": {"country": "CF"}, "model": "embargo.country", "pk": 43}, {"fields": {"country": "TD"}, "model": "embargo.country", "pk": 44}, {"fields": {"country": "CL"}, "model": "embargo.country", "pk": 45}, {"fields": {"country": "CN"}, "model": "embargo.country", "pk": 46}, {"fields": {"country": "CX"}, "model": "embargo.country", "pk": 47}, {"fields": {"country": "CC"}, "model": "embargo.country", "pk": 48}, {"fields": {"country": "CO"}, "model": "embargo.country", "pk": 49}, {"fields": {"country": "KM"}, "model": "embargo.country", "pk": 50}, {"fields": {"country": "CG"}, "model": "embargo.country", "pk": 51}, {"fields": {"country": "CD"}, "model": "embargo.country", "pk": 52}, {"fields": {"country": "CK"}, "model": "embargo.country", "pk": 53}, {"fields": {"country": "CR"}, "model": "embargo.country", "pk": 54}, {"fields": {"country": "CI"}, "model": "embargo.country", "pk": 55}, {"fields": {"country": "HR"}, "model": "embargo.country", "pk": 56}, {"fields": {"country": "CU"}, "model": "embargo.country", "pk": 57}, {"fields": {"country": "CW"}, "model": "embargo.country", "pk": 58}, {"fields": {"country": "CY"}, "model": "embargo.country", "pk": 59}, {"fields": {"country": "CZ"}, "model": "embargo.country", "pk": 60}, {"fields": {"country": "DK"}, "model": "embargo.country", "pk": 61}, {"fields": {"country": "DJ"}, "model": "embargo.country", "pk": 62}, {"fields": {"country": "DM"}, "model": "embargo.country", "pk": 63}, {"fields": {"country": "DO"}, "model": "embargo.country", "pk": 64}, {"fields": {"country": "EC"}, "model": "embargo.country", "pk": 65}, {"fields": {"country": "EG"}, "model": "embargo.country", "pk": 66}, {"fields": {"country": "SV"}, "model": "embargo.country", "pk": 67}, {"fields": {"country": "GQ"}, "model": "embargo.country", "pk": 68}, {"fields": {"country": "ER"}, "model": "embargo.country", "pk": 69}, {"fields": {"country": "EE"}, "model": "embargo.country", "pk": 70}, {"fields": {"country": "ET"}, "model": "embargo.country", "pk": 71}, {"fields": {"country": "FK"}, "model": "embargo.country", "pk": 72}, {"fields": {"country": "FO"}, "model": "embargo.country", "pk": 73}, {"fields": {"country": "FJ"}, "model": "embargo.country", "pk": 74}, {"fields": {"country": "FI"}, "model": "embargo.country", "pk": 75}, {"fields": {"country": "FR"}, "model": "embargo.country", "pk": 76}, {"fields": {"country": "GF"}, "model": "embargo.country", "pk": 77}, {"fields": {"country": "PF"}, "model": "embargo.country", "pk": 78}, {"fields": {"country": "TF"}, "model": "embargo.country", "pk": 79}, {"fields": {"country": "GA"}, "model": "embargo.country", "pk": 80}, {"fields": {"country": "GM"}, "model": "embargo.country", "pk": 81}, {"fields": {"country": "GE"}, "model": "embargo.country", "pk": 82}, {"fields": {"country": "DE"}, "model": "embargo.country", "pk": 83}, {"fields": {"country": "GH"}, "model": "embargo.country", "pk": 84}, {"fields": {"country": "GI"}, "model": "embargo.country", "pk": 85}, {"fields": {"country": "GR"}, "model": "embargo.country", "pk": 86}, {"fields": {"country": "GL"}, "model": "embargo.country", "pk": 87}, {"fields": {"country": "GD"}, "model": "embargo.country", "pk": 88}, {"fields": {"country": "GP"}, "model": "embargo.country", "pk": 89}, {"fields": {"country": "GU"}, "model": "embargo.country", "pk": 90}, {"fields": {"country": "GT"}, "model": "embargo.country", "pk": 91}, {"fields": {"country": "GG"}, "model": "embargo.country", "pk": 92}, {"fields": {"country": "GN"}, "model": "embargo.country", "pk": 93}, {"fields": {"country": "GW"}, "model": "embargo.country", "pk": 94}, {"fields": {"country": "GY"}, "model": "embargo.country", "pk": 95}, {"fields": {"country": "HT"}, "model": "embargo.country", "pk": 96}, {"fields": {"country": "HM"}, "model": "embargo.country", "pk": 97}, {"fields": {"country": "VA"}, "model": "embargo.country", "pk": 98}, {"fields": {"country": "HN"}, "model": "embargo.country", "pk": 99}, {"fields": {"country": "HK"}, "model": "embargo.country", "pk": 100}, {"fields": {"country": "HU"}, "model": "embargo.country", "pk": 101}, {"fields": {"country": "IS"}, "model": "embargo.country", "pk": 102}, {"fields": {"country": "IN"}, "model": "embargo.country", "pk": 103}, {"fields": {"country": "ID"}, "model": "embargo.country", "pk": 104}, {"fields": {"country": "IR"}, "model": "embargo.country", "pk": 105}, {"fields": {"country": "IQ"}, "model": "embargo.country", "pk": 106}, {"fields": {"country": "IE"}, "model": "embargo.country", "pk": 107}, {"fields": {"country": "IM"}, "model": "embargo.country", "pk": 108}, {"fields": {"country": "IL"}, "model": "embargo.country", "pk": 109}, {"fields": {"country": "IT"}, "model": "embargo.country", "pk": 110}, {"fields": {"country": "JM"}, "model": "embargo.country", "pk": 111}, {"fields": {"country": "JP"}, "model": "embargo.country", "pk": 112}, {"fields": {"country": "JE"}, "model": "embargo.country", "pk": 113}, {"fields": {"country": "JO"}, "model": "embargo.country", "pk": 114}, {"fields": {"country": "KZ"}, "model": "embargo.country", "pk": 115}, {"fields": {"country": "KE"}, "model": "embargo.country", "pk": 116}, {"fields": {"country": "KI"}, "model": "embargo.country", "pk": 117}, {"fields": {"country": "KW"}, "model": "embargo.country", "pk": 118}, {"fields": {"country": "KG"}, "model": "embargo.country", "pk": 119}, {"fields": {"country": "LA"}, "model": "embargo.country", "pk": 120}, {"fields": {"country": "LV"}, "model": "embargo.country", "pk": 121}, {"fields": {"country": "LB"}, "model": "embargo.country", "pk": 122}, {"fields": {"country": "LS"}, "model": "embargo.country", "pk": 123}, {"fields": {"country": "LR"}, "model": "embargo.country", "pk": 124}, {"fields": {"country": "LY"}, "model": "embargo.country", "pk": 125}, {"fields": {"country": "LI"}, "model": "embargo.country", "pk": 126}, {"fields": {"country": "LT"}, "model": "embargo.country", "pk": 127}, {"fields": {"country": "LU"}, "model": "embargo.country", "pk": 128}, {"fields": {"country": "MO"}, "model": "embargo.country", "pk": 129}, {"fields": {"country": "MK"}, "model": "embargo.country", "pk": 130}, {"fields": {"country": "MG"}, "model": "embargo.country", "pk": 131}, {"fields": {"country": "MW"}, "model": "embargo.country", "pk": 132}, {"fields": {"country": "MY"}, "model": "embargo.country", "pk": 133}, {"fields": {"country": "MV"}, "model": "embargo.country", "pk": 134}, {"fields": {"country": "ML"}, "model": "embargo.country", "pk": 135}, {"fields": {"country": "MT"}, "model": "embargo.country", "pk": 136}, {"fields": {"country": "MH"}, "model": "embargo.country", "pk": 137}, {"fields": {"country": "MQ"}, "model": "embargo.country", "pk": 138}, {"fields": {"country": "MR"}, "model": "embargo.country", "pk": 139}, {"fields": {"country": "MU"}, "model": "embargo.country", "pk": 140}, {"fields": {"country": "YT"}, "model": "embargo.country", "pk": 141}, {"fields": {"country": "MX"}, "model": "embargo.country", "pk": 142}, {"fields": {"country": "FM"}, "model": "embargo.country", "pk": 143}, {"fields": {"country": "MD"}, "model": "embargo.country", "pk": 144}, {"fields": {"country": "MC"}, "model": "embargo.country", "pk": 145}, {"fields": {"country": "MN"}, "model": "embargo.country", "pk": 146}, {"fields": {"country": "ME"}, "model": "embargo.country", "pk": 147}, {"fields": {"country": "MS"}, "model": "embargo.country", "pk": 148}, {"fields": {"country": "MA"}, "model": "embargo.country", "pk": 149}, {"fields": {"country": "MZ"}, "model": "embargo.country", "pk": 150}, {"fields": {"country": "MM"}, "model": "embargo.country", "pk": 151}, {"fields": {"country": "NA"}, "model": "embargo.country", "pk": 152}, {"fields": {"country": "NR"}, "model": "embargo.country", "pk": 153}, {"fields": {"country": "NP"}, "model": "embargo.country", "pk": 154}, {"fields": {"country": "NL"}, "model": "embargo.country", "pk": 155}, {"fields": {"country": "NC"}, "model": "embargo.country", "pk": 156}, {"fields": {"country": "NZ"}, "model": "embargo.country", "pk": 157}, {"fields": {"country": "NI"}, "model": "embargo.country", "pk": 158}, {"fields": {"country": "NE"}, "model": "embargo.country", "pk": 159}, {"fields": {"country": "NG"}, "model": "embargo.country", "pk": 160}, {"fields": {"country": "NU"}, "model": "embargo.country", "pk": 161}, {"fields": {"country": "NF"}, "model": "embargo.country", "pk": 162}, {"fields": {"country": "KP"}, "model": "embargo.country", "pk": 163}, {"fields": {"country": "MP"}, "model": "embargo.country", "pk": 164}, {"fields": {"country": "NO"}, "model": "embargo.country", "pk": 165}, {"fields": {"country": "OM"}, "model": "embargo.country", "pk": 166}, {"fields": {"country": "PK"}, "model": "embargo.country", "pk": 167}, {"fields": {"country": "PW"}, "model": "embargo.country", "pk": 168}, {"fields": {"country": "PS"}, "model": "embargo.country", "pk": 169}, {"fields": {"country": "PA"}, "model": "embargo.country", "pk": 170}, {"fields": {"country": "PG"}, "model": "embargo.country", "pk": 171}, {"fields": {"country": "PY"}, "model": "embargo.country", "pk": 172}, {"fields": {"country": "PE"}, "model": "embargo.country", "pk": 173}, {"fields": {"country": "PH"}, "model": "embargo.country", "pk": 174}, {"fields": {"country": "PN"}, "model": "embargo.country", "pk": 175}, {"fields": {"country": "PL"}, "model": "embargo.country", "pk": 176}, {"fields": {"country": "PT"}, "model": "embargo.country", "pk": 177}, {"fields": {"country": "PR"}, "model": "embargo.country", "pk": 178}, {"fields": {"country": "QA"}, "model": "embargo.country", "pk": 179}, {"fields": {"country": "RE"}, "model": "embargo.country", "pk": 180}, {"fields": {"country": "RO"}, "model": "embargo.country", "pk": 181}, {"fields": {"country": "RU"}, "model": "embargo.country", "pk": 182}, {"fields": {"country": "RW"}, "model": "embargo.country", "pk": 183}, {"fields": {"country": "BL"}, "model": "embargo.country", "pk": 184}, {"fields": {"country": "SH"}, "model": "embargo.country", "pk": 185}, {"fields": {"country": "KN"}, "model": "embargo.country", "pk": 186}, {"fields": {"country": "LC"}, "model": "embargo.country", "pk": 187}, {"fields": {"country": "MF"}, "model": "embargo.country", "pk": 188}, {"fields": {"country": "PM"}, "model": "embargo.country", "pk": 189}, {"fields": {"country": "VC"}, "model": "embargo.country", "pk": 190}, {"fields": {"country": "WS"}, "model": "embargo.country", "pk": 191}, {"fields": {"country": "SM"}, "model": "embargo.country", "pk": 192}, {"fields": {"country": "ST"}, "model": "embargo.country", "pk": 193}, {"fields": {"country": "SA"}, "model": "embargo.country", "pk": 194}, {"fields": {"country": "SN"}, "model": "embargo.country", "pk": 195}, {"fields": {"country": "RS"}, "model": "embargo.country", "pk": 196}, {"fields": {"country": "SC"}, "model": "embargo.country", "pk": 197}, {"fields": {"country": "SL"}, "model": "embargo.country", "pk": 198}, {"fields": {"country": "SG"}, "model": "embargo.country", "pk": 199}, {"fields": {"country": "SX"}, "model": "embargo.country", "pk": 200}, {"fields": {"country": "SK"}, "model": "embargo.country", "pk": 201}, {"fields": {"country": "SI"}, "model": "embargo.country", "pk": 202}, {"fields": {"country": "SB"}, "model": "embargo.country", "pk": 203}, {"fields": {"country": "SO"}, "model": "embargo.country", "pk": 204}, {"fields": {"country": "ZA"}, "model": "embargo.country", "pk": 205}, {"fields": {"country": "GS"}, "model": "embargo.country", "pk": 206}, {"fields": {"country": "KR"}, "model": "embargo.country", "pk": 207}, {"fields": {"country": "SS"}, "model": "embargo.country", "pk": 208}, {"fields": {"country": "ES"}, "model": "embargo.country", "pk": 209}, {"fields": {"country": "LK"}, "model": "embargo.country", "pk": 210}, {"fields": {"country": "SD"}, "model": "embargo.country", "pk": 211}, {"fields": {"country": "SR"}, "model": "embargo.country", "pk": 212}, {"fields": {"country": "SJ"}, "model": "embargo.country", "pk": 213}, {"fields": {"country": "SZ"}, "model": "embargo.country", "pk": 214}, {"fields": {"country": "SE"}, "model": "embargo.country", "pk": 215}, {"fields": {"country": "CH"}, "model": "embargo.country", "pk": 216}, {"fields": {"country": "SY"}, "model": "embargo.country", "pk": 217}, {"fields": {"country": "TW"}, "model": "embargo.country", "pk": 218}, {"fields": {"country": "TJ"}, "model": "embargo.country", "pk": 219}, {"fields": {"country": "TZ"}, "model": "embargo.country", "pk": 220}, {"fields": {"country": "TH"}, "model": "embargo.country", "pk": 221}, {"fields": {"country": "TL"}, "model": "embargo.country", "pk": 222}, {"fields": {"country": "TG"}, "model": "embargo.country", "pk": 223}, {"fields": {"country": "TK"}, "model": "embargo.country", "pk": 224}, {"fields": {"country": "TO"}, "model": "embargo.country", "pk": 225}, {"fields": {"country": "TT"}, "model": "embargo.country", "pk": 226}, {"fields": {"country": "TN"}, "model": "embargo.country", "pk": 227}, {"fields": {"country": "TR"}, "model": "embargo.country", "pk": 228}, {"fields": {"country": "TM"}, "model": "embargo.country", "pk": 229}, {"fields": {"country": "TC"}, "model": "embargo.country", "pk": 230}, {"fields": {"country": "TV"}, "model": "embargo.country", "pk": 231}, {"fields": {"country": "UG"}, "model": "embargo.country", "pk": 232}, {"fields": {"country": "UA"}, "model": "embargo.country", "pk": 233}, {"fields": {"country": "AE"}, "model": "embargo.country", "pk": 234}, {"fields": {"country": "GB"}, "model": "embargo.country", "pk": 235}, {"fields": {"country": "UM"}, "model": "embargo.country", "pk": 236}, {"fields": {"country": "US"}, "model": "embargo.country", "pk": 237}, {"fields": {"country": "UY"}, "model": "embargo.country", "pk": 238}, {"fields": {"country": "UZ"}, "model": "embargo.country", "pk": 239}, {"fields": {"country": "VU"}, "model": "embargo.country", "pk": 240}, {"fields": {"country": "VE"}, "model": "embargo.country", "pk": 241}, {"fields": {"country": "VN"}, "model": "embargo.country", "pk": 242}, {"fields": {"country": "VG"}, "model": "embargo.country", "pk": 243}, {"fields": {"country": "VI"}, "model": "embargo.country", "pk": 244}, {"fields": {"country": "WF"}, "model": "embargo.country", "pk": 245}, {"fields": {"country": "EH"}, "model": "embargo.country", "pk": 246}, {"fields": {"country": "YE"}, "model": "embargo.country", "pk": 247}, {"fields": {"country": "ZM"}, "model": "embargo.country", "pk": 248}, {"fields": {"country": "ZW"}, "model": "embargo.country", "pk": 249}, {"fields": {"profile_name": "desktop_mp4"}, "model": "edxval.profile", "pk": 1}, {"fields": {"profile_name": "desktop_webm"}, "model": "edxval.profile", "pk": 2}, {"fields": {"profile_name": "mobile_high"}, "model": "edxval.profile", "pk": 3}, {"fields": {"profile_name": "mobile_low"}, "model": "edxval.profile", "pk": 4}, {"fields": {"profile_name": "youtube"}, "model": "edxval.profile", "pk": 5}, {"fields": {"active": true, "description": "Autogenerated milestone relationship type \"fulfills\"", "modified": "2015-11-18T15:37:41.266Z", "name": "fulfills", "created": "2015-11-18T15:37:41.265Z"}, "model": "milestones.milestonerelationshiptype", "pk": 1}, {"fields": {"active": true, "description": "Autogenerated milestone relationship type \"requires\"", "modified": "2015-11-18T15:37:41.269Z", "name": "requires", "created": "2015-11-18T15:37:41.268Z"}, "model": "milestones.milestonerelationshiptype", "pk": 2}, {"fields": {"codename": "add_permission", "name": "Can add permission", "content_type": 1}, "model": "auth.permission", "pk": 1}, {"fields": {"codename": "change_permission", "name": "Can change permission", "content_type": 1}, "model": "auth.permission", "pk": 2}, {"fields": {"codename": "delete_permission", "name": "Can delete permission", "content_type": 1}, "model": "auth.permission", "pk": 3}, {"fields": {"codename": "add_group", "name": "Can add group", "content_type": 2}, "model": "auth.permission", "pk": 4}, {"fields": {"codename": "change_group", "name": "Can change group", "content_type": 2}, "model": "auth.permission", "pk": 5}, {"fields": {"codename": "delete_group", "name": "Can delete group", "content_type": 2}, "model": "auth.permission", "pk": 6}, {"fields": {"codename": "add_user", "name": "Can add user", "content_type": 3}, "model": "auth.permission", "pk": 7}, {"fields": {"codename": "change_user", "name": "Can change user", "content_type": 3}, "model": "auth.permission", "pk": 8}, {"fields": {"codename": "delete_user", "name": "Can delete user", "content_type": 3}, "model": "auth.permission", "pk": 9}, {"fields": {"codename": "add_contenttype", "name": "Can add content type", "content_type": 4}, "model": "auth.permission", "pk": 10}, {"fields": {"codename": "change_contenttype", "name": "Can change content type", "content_type": 4}, "model": "auth.permission", "pk": 11}, {"fields": {"codename": "delete_contenttype", "name": "Can delete content type", "content_type": 4}, "model": "auth.permission", "pk": 12}, {"fields": {"codename": "add_session", "name": "Can add session", "content_type": 5}, "model": "auth.permission", "pk": 13}, {"fields": {"codename": "change_session", "name": "Can change session", "content_type": 5}, "model": "auth.permission", "pk": 14}, {"fields": {"codename": "delete_session", "name": "Can delete session", "content_type": 5}, "model": "auth.permission", "pk": 15}, {"fields": {"codename": "add_site", "name": "Can add site", "content_type": 6}, "model": "auth.permission", "pk": 16}, {"fields": {"codename": "change_site", "name": "Can change site", "content_type": 6}, "model": "auth.permission", "pk": 17}, {"fields": {"codename": "delete_site", "name": "Can delete site", "content_type": 6}, "model": "auth.permission", "pk": 18}, {"fields": {"codename": "add_taskmeta", "name": "Can add task state", "content_type": 7}, "model": "auth.permission", "pk": 19}, {"fields": {"codename": "change_taskmeta", "name": "Can change task state", "content_type": 7}, "model": "auth.permission", "pk": 20}, {"fields": {"codename": "delete_taskmeta", "name": "Can delete task state", "content_type": 7}, "model": "auth.permission", "pk": 21}, {"fields": {"codename": "add_tasksetmeta", "name": "Can add saved group result", "content_type": 8}, "model": "auth.permission", "pk": 22}, {"fields": {"codename": "change_tasksetmeta", "name": "Can change saved group result", "content_type": 8}, "model": "auth.permission", "pk": 23}, {"fields": {"codename": "delete_tasksetmeta", "name": "Can delete saved group result", "content_type": 8}, "model": "auth.permission", "pk": 24}, {"fields": {"codename": "add_intervalschedule", "name": "Can add interval", "content_type": 9}, "model": "auth.permission", "pk": 25}, {"fields": {"codename": "change_intervalschedule", "name": "Can change interval", "content_type": 9}, "model": "auth.permission", "pk": 26}, {"fields": {"codename": "delete_intervalschedule", "name": "Can delete interval", "content_type": 9}, "model": "auth.permission", "pk": 27}, {"fields": {"codename": "add_crontabschedule", "name": "Can add crontab", "content_type": 10}, "model": "auth.permission", "pk": 28}, {"fields": {"codename": "change_crontabschedule", "name": "Can change crontab", "content_type": 10}, "model": "auth.permission", "pk": 29}, {"fields": {"codename": "delete_crontabschedule", "name": "Can delete crontab", "content_type": 10}, "model": "auth.permission", "pk": 30}, {"fields": {"codename": "add_periodictasks", "name": "Can add periodic tasks", "content_type": 11}, "model": "auth.permission", "pk": 31}, {"fields": {"codename": "change_periodictasks", "name": "Can change periodic tasks", "content_type": 11}, "model": "auth.permission", "pk": 32}, {"fields": {"codename": "delete_periodictasks", "name": "Can delete periodic tasks", "content_type": 11}, "model": "auth.permission", "pk": 33}, {"fields": {"codename": "add_periodictask", "name": "Can add periodic task", "content_type": 12}, "model": "auth.permission", "pk": 34}, {"fields": {"codename": "change_periodictask", "name": "Can change periodic task", "content_type": 12}, "model": "auth.permission", "pk": 35}, {"fields": {"codename": "delete_periodictask", "name": "Can delete periodic task", "content_type": 12}, "model": "auth.permission", "pk": 36}, {"fields": {"codename": "add_workerstate", "name": "Can add worker", "content_type": 13}, "model": "auth.permission", "pk": 37}, {"fields": {"codename": "change_workerstate", "name": "Can change worker", "content_type": 13}, "model": "auth.permission", "pk": 38}, {"fields": {"codename": "delete_workerstate", "name": "Can delete worker", "content_type": 13}, "model": "auth.permission", "pk": 39}, {"fields": {"codename": "add_taskstate", "name": "Can add task", "content_type": 14}, "model": "auth.permission", "pk": 40}, {"fields": {"codename": "change_taskstate", "name": "Can change task", "content_type": 14}, "model": "auth.permission", "pk": 41}, {"fields": {"codename": "delete_taskstate", "name": "Can delete task", "content_type": 14}, "model": "auth.permission", "pk": 42}, {"fields": {"codename": "add_globalstatusmessage", "name": "Can add global status message", "content_type": 15}, "model": "auth.permission", "pk": 43}, {"fields": {"codename": "change_globalstatusmessage", "name": "Can change global status message", "content_type": 15}, "model": "auth.permission", "pk": 44}, {"fields": {"codename": "delete_globalstatusmessage", "name": "Can delete global status message", "content_type": 15}, "model": "auth.permission", "pk": 45}, {"fields": {"codename": "add_coursemessage", "name": "Can add course message", "content_type": 16}, "model": "auth.permission", "pk": 46}, {"fields": {"codename": "change_coursemessage", "name": "Can change course message", "content_type": 16}, "model": "auth.permission", "pk": 47}, {"fields": {"codename": "delete_coursemessage", "name": "Can delete course message", "content_type": 16}, "model": "auth.permission", "pk": 48}, {"fields": {"codename": "add_studentmodule", "name": "Can add student module", "content_type": 17}, "model": "auth.permission", "pk": 49}, {"fields": {"codename": "change_studentmodule", "name": "Can change student module", "content_type": 17}, "model": "auth.permission", "pk": 50}, {"fields": {"codename": "delete_studentmodule", "name": "Can delete student module", "content_type": 17}, "model": "auth.permission", "pk": 51}, {"fields": {"codename": "add_studentmodulehistory", "name": "Can add student module history", "content_type": 18}, "model": "auth.permission", "pk": 52}, {"fields": {"codename": "change_studentmodulehistory", "name": "Can change student module history", "content_type": 18}, "model": "auth.permission", "pk": 53}, {"fields": {"codename": "delete_studentmodulehistory", "name": "Can delete student module history", "content_type": 18}, "model": "auth.permission", "pk": 54}, {"fields": {"codename": "add_xmoduleuserstatesummaryfield", "name": "Can add x module user state summary field", "content_type": 19}, "model": "auth.permission", "pk": 55}, {"fields": {"codename": "change_xmoduleuserstatesummaryfield", "name": "Can change x module user state summary field", "content_type": 19}, "model": "auth.permission", "pk": 56}, {"fields": {"codename": "delete_xmoduleuserstatesummaryfield", "name": "Can delete x module user state summary field", "content_type": 19}, "model": "auth.permission", "pk": 57}, {"fields": {"codename": "add_xmodulestudentprefsfield", "name": "Can add x module student prefs field", "content_type": 20}, "model": "auth.permission", "pk": 58}, {"fields": {"codename": "change_xmodulestudentprefsfield", "name": "Can change x module student prefs field", "content_type": 20}, "model": "auth.permission", "pk": 59}, {"fields": {"codename": "delete_xmodulestudentprefsfield", "name": "Can delete x module student prefs field", "content_type": 20}, "model": "auth.permission", "pk": 60}, {"fields": {"codename": "add_xmodulestudentinfofield", "name": "Can add x module student info field", "content_type": 21}, "model": "auth.permission", "pk": 61}, {"fields": {"codename": "change_xmodulestudentinfofield", "name": "Can change x module student info field", "content_type": 21}, "model": "auth.permission", "pk": 62}, {"fields": {"codename": "delete_xmodulestudentinfofield", "name": "Can delete x module student info field", "content_type": 21}, "model": "auth.permission", "pk": 63}, {"fields": {"codename": "add_offlinecomputedgrade", "name": "Can add offline computed grade", "content_type": 22}, "model": "auth.permission", "pk": 64}, {"fields": {"codename": "change_offlinecomputedgrade", "name": "Can change offline computed grade", "content_type": 22}, "model": "auth.permission", "pk": 65}, {"fields": {"codename": "delete_offlinecomputedgrade", "name": "Can delete offline computed grade", "content_type": 22}, "model": "auth.permission", "pk": 66}, {"fields": {"codename": "add_offlinecomputedgradelog", "name": "Can add offline computed grade log", "content_type": 23}, "model": "auth.permission", "pk": 67}, {"fields": {"codename": "change_offlinecomputedgradelog", "name": "Can change offline computed grade log", "content_type": 23}, "model": "auth.permission", "pk": 68}, {"fields": {"codename": "delete_offlinecomputedgradelog", "name": "Can delete offline computed grade log", "content_type": 23}, "model": "auth.permission", "pk": 69}, {"fields": {"codename": "add_studentfieldoverride", "name": "Can add student field override", "content_type": 24}, "model": "auth.permission", "pk": 70}, {"fields": {"codename": "change_studentfieldoverride", "name": "Can change student field override", "content_type": 24}, "model": "auth.permission", "pk": 71}, {"fields": {"codename": "delete_studentfieldoverride", "name": "Can delete student field override", "content_type": 24}, "model": "auth.permission", "pk": 72}, {"fields": {"codename": "add_anonymoususerid", "name": "Can add anonymous user id", "content_type": 25}, "model": "auth.permission", "pk": 73}, {"fields": {"codename": "change_anonymoususerid", "name": "Can change anonymous user id", "content_type": 25}, "model": "auth.permission", "pk": 74}, {"fields": {"codename": "delete_anonymoususerid", "name": "Can delete anonymous user id", "content_type": 25}, "model": "auth.permission", "pk": 75}, {"fields": {"codename": "add_userstanding", "name": "Can add user standing", "content_type": 26}, "model": "auth.permission", "pk": 76}, {"fields": {"codename": "change_userstanding", "name": "Can change user standing", "content_type": 26}, "model": "auth.permission", "pk": 77}, {"fields": {"codename": "delete_userstanding", "name": "Can delete user standing", "content_type": 26}, "model": "auth.permission", "pk": 78}, {"fields": {"codename": "add_userprofile", "name": "Can add user profile", "content_type": 27}, "model": "auth.permission", "pk": 79}, {"fields": {"codename": "change_userprofile", "name": "Can change user profile", "content_type": 27}, "model": "auth.permission", "pk": 80}, {"fields": {"codename": "delete_userprofile", "name": "Can delete user profile", "content_type": 27}, "model": "auth.permission", "pk": 81}, {"fields": {"codename": "add_usersignupsource", "name": "Can add user signup source", "content_type": 28}, "model": "auth.permission", "pk": 82}, {"fields": {"codename": "change_usersignupsource", "name": "Can change user signup source", "content_type": 28}, "model": "auth.permission", "pk": 83}, {"fields": {"codename": "delete_usersignupsource", "name": "Can delete user signup source", "content_type": 28}, "model": "auth.permission", "pk": 84}, {"fields": {"codename": "add_usertestgroup", "name": "Can add user test group", "content_type": 29}, "model": "auth.permission", "pk": 85}, {"fields": {"codename": "change_usertestgroup", "name": "Can change user test group", "content_type": 29}, "model": "auth.permission", "pk": 86}, {"fields": {"codename": "delete_usertestgroup", "name": "Can delete user test group", "content_type": 29}, "model": "auth.permission", "pk": 87}, {"fields": {"codename": "add_registration", "name": "Can add registration", "content_type": 30}, "model": "auth.permission", "pk": 88}, {"fields": {"codename": "change_registration", "name": "Can change registration", "content_type": 30}, "model": "auth.permission", "pk": 89}, {"fields": {"codename": "delete_registration", "name": "Can delete registration", "content_type": 30}, "model": "auth.permission", "pk": 90}, {"fields": {"codename": "add_pendingnamechange", "name": "Can add pending name change", "content_type": 31}, "model": "auth.permission", "pk": 91}, {"fields": {"codename": "change_pendingnamechange", "name": "Can change pending name change", "content_type": 31}, "model": "auth.permission", "pk": 92}, {"fields": {"codename": "delete_pendingnamechange", "name": "Can delete pending name change", "content_type": 31}, "model": "auth.permission", "pk": 93}, {"fields": {"codename": "add_pendingemailchange", "name": "Can add pending email change", "content_type": 32}, "model": "auth.permission", "pk": 94}, {"fields": {"codename": "change_pendingemailchange", "name": "Can change pending email change", "content_type": 32}, "model": "auth.permission", "pk": 95}, {"fields": {"codename": "delete_pendingemailchange", "name": "Can delete pending email change", "content_type": 32}, "model": "auth.permission", "pk": 96}, {"fields": {"codename": "add_passwordhistory", "name": "Can add password history", "content_type": 33}, "model": "auth.permission", "pk": 97}, {"fields": {"codename": "change_passwordhistory", "name": "Can change password history", "content_type": 33}, "model": "auth.permission", "pk": 98}, {"fields": {"codename": "delete_passwordhistory", "name": "Can delete password history", "content_type": 33}, "model": "auth.permission", "pk": 99}, {"fields": {"codename": "add_loginfailures", "name": "Can add login failures", "content_type": 34}, "model": "auth.permission", "pk": 100}, {"fields": {"codename": "change_loginfailures", "name": "Can change login failures", "content_type": 34}, "model": "auth.permission", "pk": 101}, {"fields": {"codename": "delete_loginfailures", "name": "Can delete login failures", "content_type": 34}, "model": "auth.permission", "pk": 102}, {"fields": {"codename": "add_historicalcourseenrollment", "name": "Can add historical course enrollment", "content_type": 35}, "model": "auth.permission", "pk": 103}, {"fields": {"codename": "change_historicalcourseenrollment", "name": "Can change historical course enrollment", "content_type": 35}, "model": "auth.permission", "pk": 104}, {"fields": {"codename": "delete_historicalcourseenrollment", "name": "Can delete historical course enrollment", "content_type": 35}, "model": "auth.permission", "pk": 105}, {"fields": {"codename": "add_courseenrollment", "name": "Can add course enrollment", "content_type": 36}, "model": "auth.permission", "pk": 106}, {"fields": {"codename": "change_courseenrollment", "name": "Can change course enrollment", "content_type": 36}, "model": "auth.permission", "pk": 107}, {"fields": {"codename": "delete_courseenrollment", "name": "Can delete course enrollment", "content_type": 36}, "model": "auth.permission", "pk": 108}, {"fields": {"codename": "add_manualenrollmentaudit", "name": "Can add manual enrollment audit", "content_type": 37}, "model": "auth.permission", "pk": 109}, {"fields": {"codename": "change_manualenrollmentaudit", "name": "Can change manual enrollment audit", "content_type": 37}, "model": "auth.permission", "pk": 110}, {"fields": {"codename": "delete_manualenrollmentaudit", "name": "Can delete manual enrollment audit", "content_type": 37}, "model": "auth.permission", "pk": 111}, {"fields": {"codename": "add_courseenrollmentallowed", "name": "Can add course enrollment allowed", "content_type": 38}, "model": "auth.permission", "pk": 112}, {"fields": {"codename": "change_courseenrollmentallowed", "name": "Can change course enrollment allowed", "content_type": 38}, "model": "auth.permission", "pk": 113}, {"fields": {"codename": "delete_courseenrollmentallowed", "name": "Can delete course enrollment allowed", "content_type": 38}, "model": "auth.permission", "pk": 114}, {"fields": {"codename": "add_courseaccessrole", "name": "Can add course access role", "content_type": 39}, "model": "auth.permission", "pk": 115}, {"fields": {"codename": "change_courseaccessrole", "name": "Can change course access role", "content_type": 39}, "model": "auth.permission", "pk": 116}, {"fields": {"codename": "delete_courseaccessrole", "name": "Can delete course access role", "content_type": 39}, "model": "auth.permission", "pk": 117}, {"fields": {"codename": "add_dashboardconfiguration", "name": "Can add dashboard configuration", "content_type": 40}, "model": "auth.permission", "pk": 118}, {"fields": {"codename": "change_dashboardconfiguration", "name": "Can change dashboard configuration", "content_type": 40}, "model": "auth.permission", "pk": 119}, {"fields": {"codename": "delete_dashboardconfiguration", "name": "Can delete dashboard configuration", "content_type": 40}, "model": "auth.permission", "pk": 120}, {"fields": {"codename": "add_linkedinaddtoprofileconfiguration", "name": "Can add linked in add to profile configuration", "content_type": 41}, "model": "auth.permission", "pk": 121}, {"fields": {"codename": "change_linkedinaddtoprofileconfiguration", "name": "Can change linked in add to profile configuration", "content_type": 41}, "model": "auth.permission", "pk": 122}, {"fields": {"codename": "delete_linkedinaddtoprofileconfiguration", "name": "Can delete linked in add to profile configuration", "content_type": 41}, "model": "auth.permission", "pk": 123}, {"fields": {"codename": "add_entranceexamconfiguration", "name": "Can add entrance exam configuration", "content_type": 42}, "model": "auth.permission", "pk": 124}, {"fields": {"codename": "change_entranceexamconfiguration", "name": "Can change entrance exam configuration", "content_type": 42}, "model": "auth.permission", "pk": 125}, {"fields": {"codename": "delete_entranceexamconfiguration", "name": "Can delete entrance exam configuration", "content_type": 42}, "model": "auth.permission", "pk": 126}, {"fields": {"codename": "add_languageproficiency", "name": "Can add language proficiency", "content_type": 43}, "model": "auth.permission", "pk": 127}, {"fields": {"codename": "change_languageproficiency", "name": "Can change language proficiency", "content_type": 43}, "model": "auth.permission", "pk": 128}, {"fields": {"codename": "delete_languageproficiency", "name": "Can delete language proficiency", "content_type": 43}, "model": "auth.permission", "pk": 129}, {"fields": {"codename": "add_courseenrollmentattribute", "name": "Can add course enrollment attribute", "content_type": 44}, "model": "auth.permission", "pk": 130}, {"fields": {"codename": "change_courseenrollmentattribute", "name": "Can change course enrollment attribute", "content_type": 44}, "model": "auth.permission", "pk": 131}, {"fields": {"codename": "delete_courseenrollmentattribute", "name": "Can delete course enrollment attribute", "content_type": 44}, "model": "auth.permission", "pk": 132}, {"fields": {"codename": "add_enrollmentrefundconfiguration", "name": "Can add enrollment refund configuration", "content_type": 45}, "model": "auth.permission", "pk": 133}, {"fields": {"codename": "change_enrollmentrefundconfiguration", "name": "Can change enrollment refund configuration", "content_type": 45}, "model": "auth.permission", "pk": 134}, {"fields": {"codename": "delete_enrollmentrefundconfiguration", "name": "Can delete enrollment refund configuration", "content_type": 45}, "model": "auth.permission", "pk": 135}, {"fields": {"codename": "add_trackinglog", "name": "Can add tracking log", "content_type": 46}, "model": "auth.permission", "pk": 136}, {"fields": {"codename": "change_trackinglog", "name": "Can change tracking log", "content_type": 46}, "model": "auth.permission", "pk": 137}, {"fields": {"codename": "delete_trackinglog", "name": "Can delete tracking log", "content_type": 46}, "model": "auth.permission", "pk": 138}, {"fields": {"codename": "add_ratelimitconfiguration", "name": "Can add rate limit configuration", "content_type": 47}, "model": "auth.permission", "pk": 139}, {"fields": {"codename": "change_ratelimitconfiguration", "name": "Can change rate limit configuration", "content_type": 47}, "model": "auth.permission", "pk": 140}, {"fields": {"codename": "delete_ratelimitconfiguration", "name": "Can delete rate limit configuration", "content_type": 47}, "model": "auth.permission", "pk": 141}, {"fields": {"codename": "add_certificatewhitelist", "name": "Can add certificate whitelist", "content_type": 48}, "model": "auth.permission", "pk": 142}, {"fields": {"codename": "change_certificatewhitelist", "name": "Can change certificate whitelist", "content_type": 48}, "model": "auth.permission", "pk": 143}, {"fields": {"codename": "delete_certificatewhitelist", "name": "Can delete certificate whitelist", "content_type": 48}, "model": "auth.permission", "pk": 144}, {"fields": {"codename": "add_generatedcertificate", "name": "Can add generated certificate", "content_type": 49}, "model": "auth.permission", "pk": 145}, {"fields": {"codename": "change_generatedcertificate", "name": "Can change generated certificate", "content_type": 49}, "model": "auth.permission", "pk": 146}, {"fields": {"codename": "delete_generatedcertificate", "name": "Can delete generated certificate", "content_type": 49}, "model": "auth.permission", "pk": 147}, {"fields": {"codename": "add_examplecertificateset", "name": "Can add example certificate set", "content_type": 50}, "model": "auth.permission", "pk": 148}, {"fields": {"codename": "change_examplecertificateset", "name": "Can change example certificate set", "content_type": 50}, "model": "auth.permission", "pk": 149}, {"fields": {"codename": "delete_examplecertificateset", "name": "Can delete example certificate set", "content_type": 50}, "model": "auth.permission", "pk": 150}, {"fields": {"codename": "add_examplecertificate", "name": "Can add example certificate", "content_type": 51}, "model": "auth.permission", "pk": 151}, {"fields": {"codename": "change_examplecertificate", "name": "Can change example certificate", "content_type": 51}, "model": "auth.permission", "pk": 152}, {"fields": {"codename": "delete_examplecertificate", "name": "Can delete example certificate", "content_type": 51}, "model": "auth.permission", "pk": 153}, {"fields": {"codename": "add_certificategenerationcoursesetting", "name": "Can add certificate generation course setting", "content_type": 52}, "model": "auth.permission", "pk": 154}, {"fields": {"codename": "change_certificategenerationcoursesetting", "name": "Can change certificate generation course setting", "content_type": 52}, "model": "auth.permission", "pk": 155}, {"fields": {"codename": "delete_certificategenerationcoursesetting", "name": "Can delete certificate generation course setting", "content_type": 52}, "model": "auth.permission", "pk": 156}, {"fields": {"codename": "add_certificategenerationconfiguration", "name": "Can add certificate generation configuration", "content_type": 53}, "model": "auth.permission", "pk": 157}, {"fields": {"codename": "change_certificategenerationconfiguration", "name": "Can change certificate generation configuration", "content_type": 53}, "model": "auth.permission", "pk": 158}, {"fields": {"codename": "delete_certificategenerationconfiguration", "name": "Can delete certificate generation configuration", "content_type": 53}, "model": "auth.permission", "pk": 159}, {"fields": {"codename": "add_certificatehtmlviewconfiguration", "name": "Can add certificate html view configuration", "content_type": 54}, "model": "auth.permission", "pk": 160}, {"fields": {"codename": "change_certificatehtmlviewconfiguration", "name": "Can change certificate html view configuration", "content_type": 54}, "model": "auth.permission", "pk": 161}, {"fields": {"codename": "delete_certificatehtmlviewconfiguration", "name": "Can delete certificate html view configuration", "content_type": 54}, "model": "auth.permission", "pk": 162}, {"fields": {"codename": "add_badgeassertion", "name": "Can add badge assertion", "content_type": 55}, "model": "auth.permission", "pk": 163}, {"fields": {"codename": "change_badgeassertion", "name": "Can change badge assertion", "content_type": 55}, "model": "auth.permission", "pk": 164}, {"fields": {"codename": "delete_badgeassertion", "name": "Can delete badge assertion", "content_type": 55}, "model": "auth.permission", "pk": 165}, {"fields": {"codename": "add_badgeimageconfiguration", "name": "Can add badge image configuration", "content_type": 56}, "model": "auth.permission", "pk": 166}, {"fields": {"codename": "change_badgeimageconfiguration", "name": "Can change badge image configuration", "content_type": 56}, "model": "auth.permission", "pk": 167}, {"fields": {"codename": "delete_badgeimageconfiguration", "name": "Can delete badge image configuration", "content_type": 56}, "model": "auth.permission", "pk": 168}, {"fields": {"codename": "add_certificatetemplate", "name": "Can add certificate template", "content_type": 57}, "model": "auth.permission", "pk": 169}, {"fields": {"codename": "change_certificatetemplate", "name": "Can change certificate template", "content_type": 57}, "model": "auth.permission", "pk": 170}, {"fields": {"codename": "delete_certificatetemplate", "name": "Can delete certificate template", "content_type": 57}, "model": "auth.permission", "pk": 171}, {"fields": {"codename": "add_certificatetemplateasset", "name": "Can add certificate template asset", "content_type": 58}, "model": "auth.permission", "pk": 172}, {"fields": {"codename": "change_certificatetemplateasset", "name": "Can change certificate template asset", "content_type": 58}, "model": "auth.permission", "pk": 173}, {"fields": {"codename": "delete_certificatetemplateasset", "name": "Can delete certificate template asset", "content_type": 58}, "model": "auth.permission", "pk": 174}, {"fields": {"codename": "add_instructortask", "name": "Can add instructor task", "content_type": 59}, "model": "auth.permission", "pk": 175}, {"fields": {"codename": "change_instructortask", "name": "Can change instructor task", "content_type": 59}, "model": "auth.permission", "pk": 176}, {"fields": {"codename": "delete_instructortask", "name": "Can delete instructor task", "content_type": 59}, "model": "auth.permission", "pk": 177}, {"fields": {"codename": "add_psychometricdata", "name": "Can add psychometric data", "content_type": 60}, "model": "auth.permission", "pk": 178}, {"fields": {"codename": "change_psychometricdata", "name": "Can change psychometric data", "content_type": 60}, "model": "auth.permission", "pk": 179}, {"fields": {"codename": "delete_psychometricdata", "name": "Can delete psychometric data", "content_type": 60}, "model": "auth.permission", "pk": 180}, {"fields": {"codename": "add_coursesoftware", "name": "Can add course software", "content_type": 61}, "model": "auth.permission", "pk": 181}, {"fields": {"codename": "change_coursesoftware", "name": "Can change course software", "content_type": 61}, "model": "auth.permission", "pk": 182}, {"fields": {"codename": "delete_coursesoftware", "name": "Can delete course software", "content_type": 61}, "model": "auth.permission", "pk": 183}, {"fields": {"codename": "add_userlicense", "name": "Can add user license", "content_type": 62}, "model": "auth.permission", "pk": 184}, {"fields": {"codename": "change_userlicense", "name": "Can change user license", "content_type": 62}, "model": "auth.permission", "pk": 185}, {"fields": {"codename": "delete_userlicense", "name": "Can delete user license", "content_type": 62}, "model": "auth.permission", "pk": 186}, {"fields": {"codename": "add_courseusergroup", "name": "Can add course user group", "content_type": 63}, "model": "auth.permission", "pk": 187}, {"fields": {"codename": "change_courseusergroup", "name": "Can change course user group", "content_type": 63}, "model": "auth.permission", "pk": 188}, {"fields": {"codename": "delete_courseusergroup", "name": "Can delete course user group", "content_type": 63}, "model": "auth.permission", "pk": 189}, {"fields": {"codename": "add_cohortmembership", "name": "Can add cohort membership", "content_type": 64}, "model": "auth.permission", "pk": 190}, {"fields": {"codename": "change_cohortmembership", "name": "Can change cohort membership", "content_type": 64}, "model": "auth.permission", "pk": 191}, {"fields": {"codename": "delete_cohortmembership", "name": "Can delete cohort membership", "content_type": 64}, "model": "auth.permission", "pk": 192}, {"fields": {"codename": "add_courseusergrouppartitiongroup", "name": "Can add course user group partition group", "content_type": 65}, "model": "auth.permission", "pk": 193}, {"fields": {"codename": "change_courseusergrouppartitiongroup", "name": "Can change course user group partition group", "content_type": 65}, "model": "auth.permission", "pk": 194}, {"fields": {"codename": "delete_courseusergrouppartitiongroup", "name": "Can delete course user group partition group", "content_type": 65}, "model": "auth.permission", "pk": 195}, {"fields": {"codename": "add_coursecohortssettings", "name": "Can add course cohorts settings", "content_type": 66}, "model": "auth.permission", "pk": 196}, {"fields": {"codename": "change_coursecohortssettings", "name": "Can change course cohorts settings", "content_type": 66}, "model": "auth.permission", "pk": 197}, {"fields": {"codename": "delete_coursecohortssettings", "name": "Can delete course cohorts settings", "content_type": 66}, "model": "auth.permission", "pk": 198}, {"fields": {"codename": "add_coursecohort", "name": "Can add course cohort", "content_type": 67}, "model": "auth.permission", "pk": 199}, {"fields": {"codename": "change_coursecohort", "name": "Can change course cohort", "content_type": 67}, "model": "auth.permission", "pk": 200}, {"fields": {"codename": "delete_coursecohort", "name": "Can delete course cohort", "content_type": 67}, "model": "auth.permission", "pk": 201}, {"fields": {"codename": "add_courseemail", "name": "Can add course email", "content_type": 68}, "model": "auth.permission", "pk": 202}, {"fields": {"codename": "change_courseemail", "name": "Can change course email", "content_type": 68}, "model": "auth.permission", "pk": 203}, {"fields": {"codename": "delete_courseemail", "name": "Can delete course email", "content_type": 68}, "model": "auth.permission", "pk": 204}, {"fields": {"codename": "add_optout", "name": "Can add optout", "content_type": 69}, "model": "auth.permission", "pk": 205}, {"fields": {"codename": "change_optout", "name": "Can change optout", "content_type": 69}, "model": "auth.permission", "pk": 206}, {"fields": {"codename": "delete_optout", "name": "Can delete optout", "content_type": 69}, "model": "auth.permission", "pk": 207}, {"fields": {"codename": "add_courseemailtemplate", "name": "Can add course email template", "content_type": 70}, "model": "auth.permission", "pk": 208}, {"fields": {"codename": "change_courseemailtemplate", "name": "Can change course email template", "content_type": 70}, "model": "auth.permission", "pk": 209}, {"fields": {"codename": "delete_courseemailtemplate", "name": "Can delete course email template", "content_type": 70}, "model": "auth.permission", "pk": 210}, {"fields": {"codename": "add_courseauthorization", "name": "Can add course authorization", "content_type": 71}, "model": "auth.permission", "pk": 211}, {"fields": {"codename": "change_courseauthorization", "name": "Can change course authorization", "content_type": 71}, "model": "auth.permission", "pk": 212}, {"fields": {"codename": "delete_courseauthorization", "name": "Can delete course authorization", "content_type": 71}, "model": "auth.permission", "pk": 213}, {"fields": {"codename": "add_brandinginfoconfig", "name": "Can add branding info config", "content_type": 72}, "model": "auth.permission", "pk": 214}, {"fields": {"codename": "change_brandinginfoconfig", "name": "Can change branding info config", "content_type": 72}, "model": "auth.permission", "pk": 215}, {"fields": {"codename": "delete_brandinginfoconfig", "name": "Can delete branding info config", "content_type": 72}, "model": "auth.permission", "pk": 216}, {"fields": {"codename": "add_brandingapiconfig", "name": "Can add branding api config", "content_type": 73}, "model": "auth.permission", "pk": 217}, {"fields": {"codename": "change_brandingapiconfig", "name": "Can change branding api config", "content_type": 73}, "model": "auth.permission", "pk": 218}, {"fields": {"codename": "delete_brandingapiconfig", "name": "Can delete branding api config", "content_type": 73}, "model": "auth.permission", "pk": 219}, {"fields": {"codename": "add_externalauthmap", "name": "Can add external auth map", "content_type": 74}, "model": "auth.permission", "pk": 220}, {"fields": {"codename": "change_externalauthmap", "name": "Can change external auth map", "content_type": 74}, "model": "auth.permission", "pk": 221}, {"fields": {"codename": "delete_externalauthmap", "name": "Can delete external auth map", "content_type": 74}, "model": "auth.permission", "pk": 222}, {"fields": {"codename": "add_nonce", "name": "Can add nonce", "content_type": 75}, "model": "auth.permission", "pk": 223}, {"fields": {"codename": "change_nonce", "name": "Can change nonce", "content_type": 75}, "model": "auth.permission", "pk": 224}, {"fields": {"codename": "delete_nonce", "name": "Can delete nonce", "content_type": 75}, "model": "auth.permission", "pk": 225}, {"fields": {"codename": "add_association", "name": "Can add association", "content_type": 76}, "model": "auth.permission", "pk": 226}, {"fields": {"codename": "change_association", "name": "Can change association", "content_type": 76}, "model": "auth.permission", "pk": 227}, {"fields": {"codename": "delete_association", "name": "Can delete association", "content_type": 76}, "model": "auth.permission", "pk": 228}, {"fields": {"codename": "add_useropenid", "name": "Can add user open id", "content_type": 77}, "model": "auth.permission", "pk": 229}, {"fields": {"codename": "change_useropenid", "name": "Can change user open id", "content_type": 77}, "model": "auth.permission", "pk": 230}, {"fields": {"codename": "delete_useropenid", "name": "Can delete user open id", "content_type": 77}, "model": "auth.permission", "pk": 231}, {"fields": {"codename": "account_verified", "name": "The OpenID has been verified", "content_type": 77}, "model": "auth.permission", "pk": 232}, {"fields": {"codename": "add_client", "name": "Can add client", "content_type": 78}, "model": "auth.permission", "pk": 233}, {"fields": {"codename": "change_client", "name": "Can change client", "content_type": 78}, "model": "auth.permission", "pk": 234}, {"fields": {"codename": "delete_client", "name": "Can delete client", "content_type": 78}, "model": "auth.permission", "pk": 235}, {"fields": {"codename": "add_grant", "name": "Can add grant", "content_type": 79}, "model": "auth.permission", "pk": 236}, {"fields": {"codename": "change_grant", "name": "Can change grant", "content_type": 79}, "model": "auth.permission", "pk": 237}, {"fields": {"codename": "delete_grant", "name": "Can delete grant", "content_type": 79}, "model": "auth.permission", "pk": 238}, {"fields": {"codename": "add_accesstoken", "name": "Can add access token", "content_type": 80}, "model": "auth.permission", "pk": 239}, {"fields": {"codename": "change_accesstoken", "name": "Can change access token", "content_type": 80}, "model": "auth.permission", "pk": 240}, {"fields": {"codename": "delete_accesstoken", "name": "Can delete access token", "content_type": 80}, "model": "auth.permission", "pk": 241}, {"fields": {"codename": "add_refreshtoken", "name": "Can add refresh token", "content_type": 81}, "model": "auth.permission", "pk": 242}, {"fields": {"codename": "change_refreshtoken", "name": "Can change refresh token", "content_type": 81}, "model": "auth.permission", "pk": 243}, {"fields": {"codename": "delete_refreshtoken", "name": "Can delete refresh token", "content_type": 81}, "model": "auth.permission", "pk": 244}, {"fields": {"codename": "add_trustedclient", "name": "Can add trusted client", "content_type": 82}, "model": "auth.permission", "pk": 245}, {"fields": {"codename": "change_trustedclient", "name": "Can change trusted client", "content_type": 82}, "model": "auth.permission", "pk": 246}, {"fields": {"codename": "delete_trustedclient", "name": "Can delete trusted client", "content_type": 82}, "model": "auth.permission", "pk": 247}, {"fields": {"codename": "add_oauth2providerconfig", "name": "Can add Provider Configuration (OAuth)", "content_type": 83}, "model": "auth.permission", "pk": 248}, {"fields": {"codename": "change_oauth2providerconfig", "name": "Can change Provider Configuration (OAuth)", "content_type": 83}, "model": "auth.permission", "pk": 249}, {"fields": {"codename": "delete_oauth2providerconfig", "name": "Can delete Provider Configuration (OAuth)", "content_type": 83}, "model": "auth.permission", "pk": 250}, {"fields": {"codename": "add_samlproviderconfig", "name": "Can add Provider Configuration (SAML IdP)", "content_type": 84}, "model": "auth.permission", "pk": 251}, {"fields": {"codename": "change_samlproviderconfig", "name": "Can change Provider Configuration (SAML IdP)", "content_type": 84}, "model": "auth.permission", "pk": 252}, {"fields": {"codename": "delete_samlproviderconfig", "name": "Can delete Provider Configuration (SAML IdP)", "content_type": 84}, "model": "auth.permission", "pk": 253}, {"fields": {"codename": "add_samlconfiguration", "name": "Can add SAML Configuration", "content_type": 85}, "model": "auth.permission", "pk": 254}, {"fields": {"codename": "change_samlconfiguration", "name": "Can change SAML Configuration", "content_type": 85}, "model": "auth.permission", "pk": 255}, {"fields": {"codename": "delete_samlconfiguration", "name": "Can delete SAML Configuration", "content_type": 85}, "model": "auth.permission", "pk": 256}, {"fields": {"codename": "add_samlproviderdata", "name": "Can add SAML Provider Data", "content_type": 86}, "model": "auth.permission", "pk": 257}, {"fields": {"codename": "change_samlproviderdata", "name": "Can change SAML Provider Data", "content_type": 86}, "model": "auth.permission", "pk": 258}, {"fields": {"codename": "delete_samlproviderdata", "name": "Can delete SAML Provider Data", "content_type": 86}, "model": "auth.permission", "pk": 259}, {"fields": {"codename": "add_ltiproviderconfig", "name": "Can add Provider Configuration (LTI)", "content_type": 87}, "model": "auth.permission", "pk": 260}, {"fields": {"codename": "change_ltiproviderconfig", "name": "Can change Provider Configuration (LTI)", "content_type": 87}, "model": "auth.permission", "pk": 261}, {"fields": {"codename": "delete_ltiproviderconfig", "name": "Can delete Provider Configuration (LTI)", "content_type": 87}, "model": "auth.permission", "pk": 262}, {"fields": {"codename": "add_providerapipermissions", "name": "Can add Provider API Permission", "content_type": 88}, "model": "auth.permission", "pk": 263}, {"fields": {"codename": "change_providerapipermissions", "name": "Can change Provider API Permission", "content_type": 88}, "model": "auth.permission", "pk": 264}, {"fields": {"codename": "delete_providerapipermissions", "name": "Can delete Provider API Permission", "content_type": 88}, "model": "auth.permission", "pk": 265}, {"fields": {"codename": "add_nonce", "name": "Can add nonce", "content_type": 89}, "model": "auth.permission", "pk": 266}, {"fields": {"codename": "change_nonce", "name": "Can change nonce", "content_type": 89}, "model": "auth.permission", "pk": 267}, {"fields": {"codename": "delete_nonce", "name": "Can delete nonce", "content_type": 89}, "model": "auth.permission", "pk": 268}, {"fields": {"codename": "add_scope", "name": "Can add scope", "content_type": 90}, "model": "auth.permission", "pk": 269}, {"fields": {"codename": "change_scope", "name": "Can change scope", "content_type": 90}, "model": "auth.permission", "pk": 270}, {"fields": {"codename": "delete_scope", "name": "Can delete scope", "content_type": 90}, "model": "auth.permission", "pk": 271}, {"fields": {"codename": "add_resource", "name": "Can add resource", "content_type": 90}, "model": "auth.permission", "pk": 272}, {"fields": {"codename": "change_resource", "name": "Can change resource", "content_type": 90}, "model": "auth.permission", "pk": 273}, {"fields": {"codename": "delete_resource", "name": "Can delete resource", "content_type": 90}, "model": "auth.permission", "pk": 274}, {"fields": {"codename": "add_consumer", "name": "Can add consumer", "content_type": 91}, "model": "auth.permission", "pk": 275}, {"fields": {"codename": "change_consumer", "name": "Can change consumer", "content_type": 91}, "model": "auth.permission", "pk": 276}, {"fields": {"codename": "delete_consumer", "name": "Can delete consumer", "content_type": 91}, "model": "auth.permission", "pk": 277}, {"fields": {"codename": "add_token", "name": "Can add token", "content_type": 92}, "model": "auth.permission", "pk": 278}, {"fields": {"codename": "change_token", "name": "Can change token", "content_type": 92}, "model": "auth.permission", "pk": 279}, {"fields": {"codename": "delete_token", "name": "Can delete token", "content_type": 92}, "model": "auth.permission", "pk": 280}, {"fields": {"codename": "add_article", "name": "Can add article", "content_type": 94}, "model": "auth.permission", "pk": 281}, {"fields": {"codename": "change_article", "name": "Can change article", "content_type": 94}, "model": "auth.permission", "pk": 282}, {"fields": {"codename": "delete_article", "name": "Can delete article", "content_type": 94}, "model": "auth.permission", "pk": 283}, {"fields": {"codename": "moderate", "name": "Can edit all articles and lock/unlock/restore", "content_type": 94}, "model": "auth.permission", "pk": 284}, {"fields": {"codename": "assign", "name": "Can change ownership of any article", "content_type": 94}, "model": "auth.permission", "pk": 285}, {"fields": {"codename": "grant", "name": "Can assign permissions to other users", "content_type": 94}, "model": "auth.permission", "pk": 286}, {"fields": {"codename": "add_articleforobject", "name": "Can add Article for object", "content_type": 95}, "model": "auth.permission", "pk": 287}, {"fields": {"codename": "change_articleforobject", "name": "Can change Article for object", "content_type": 95}, "model": "auth.permission", "pk": 288}, {"fields": {"codename": "delete_articleforobject", "name": "Can delete Article for object", "content_type": 95}, "model": "auth.permission", "pk": 289}, {"fields": {"codename": "add_articlerevision", "name": "Can add article revision", "content_type": 96}, "model": "auth.permission", "pk": 290}, {"fields": {"codename": "change_articlerevision", "name": "Can change article revision", "content_type": 96}, "model": "auth.permission", "pk": 291}, {"fields": {"codename": "delete_articlerevision", "name": "Can delete article revision", "content_type": 96}, "model": "auth.permission", "pk": 292}, {"fields": {"codename": "add_urlpath", "name": "Can add URL path", "content_type": 97}, "model": "auth.permission", "pk": 293}, {"fields": {"codename": "change_urlpath", "name": "Can change URL path", "content_type": 97}, "model": "auth.permission", "pk": 294}, {"fields": {"codename": "delete_urlpath", "name": "Can delete URL path", "content_type": 97}, "model": "auth.permission", "pk": 295}, {"fields": {"codename": "add_articleplugin", "name": "Can add article plugin", "content_type": 98}, "model": "auth.permission", "pk": 296}, {"fields": {"codename": "change_articleplugin", "name": "Can change article plugin", "content_type": 98}, "model": "auth.permission", "pk": 297}, {"fields": {"codename": "delete_articleplugin", "name": "Can delete article plugin", "content_type": 98}, "model": "auth.permission", "pk": 298}, {"fields": {"codename": "add_reusableplugin", "name": "Can add reusable plugin", "content_type": 99}, "model": "auth.permission", "pk": 299}, {"fields": {"codename": "change_reusableplugin", "name": "Can change reusable plugin", "content_type": 99}, "model": "auth.permission", "pk": 300}, {"fields": {"codename": "delete_reusableplugin", "name": "Can delete reusable plugin", "content_type": 99}, "model": "auth.permission", "pk": 301}, {"fields": {"codename": "add_simpleplugin", "name": "Can add simple plugin", "content_type": 100}, "model": "auth.permission", "pk": 302}, {"fields": {"codename": "change_simpleplugin", "name": "Can change simple plugin", "content_type": 100}, "model": "auth.permission", "pk": 303}, {"fields": {"codename": "delete_simpleplugin", "name": "Can delete simple plugin", "content_type": 100}, "model": "auth.permission", "pk": 304}, {"fields": {"codename": "add_revisionplugin", "name": "Can add revision plugin", "content_type": 101}, "model": "auth.permission", "pk": 305}, {"fields": {"codename": "change_revisionplugin", "name": "Can change revision plugin", "content_type": 101}, "model": "auth.permission", "pk": 306}, {"fields": {"codename": "delete_revisionplugin", "name": "Can delete revision plugin", "content_type": 101}, "model": "auth.permission", "pk": 307}, {"fields": {"codename": "add_revisionpluginrevision", "name": "Can add revision plugin revision", "content_type": 102}, "model": "auth.permission", "pk": 308}, {"fields": {"codename": "change_revisionpluginrevision", "name": "Can change revision plugin revision", "content_type": 102}, "model": "auth.permission", "pk": 309}, {"fields": {"codename": "delete_revisionpluginrevision", "name": "Can delete revision plugin revision", "content_type": 102}, "model": "auth.permission", "pk": 310}, {"fields": {"codename": "add_image", "name": "Can add image", "content_type": 103}, "model": "auth.permission", "pk": 311}, {"fields": {"codename": "change_image", "name": "Can change image", "content_type": 103}, "model": "auth.permission", "pk": 312}, {"fields": {"codename": "delete_image", "name": "Can delete image", "content_type": 103}, "model": "auth.permission", "pk": 313}, {"fields": {"codename": "add_imagerevision", "name": "Can add image revision", "content_type": 104}, "model": "auth.permission", "pk": 314}, {"fields": {"codename": "change_imagerevision", "name": "Can change image revision", "content_type": 104}, "model": "auth.permission", "pk": 315}, {"fields": {"codename": "delete_imagerevision", "name": "Can delete image revision", "content_type": 104}, "model": "auth.permission", "pk": 316}, {"fields": {"codename": "add_attachment", "name": "Can add attachment", "content_type": 105}, "model": "auth.permission", "pk": 317}, {"fields": {"codename": "change_attachment", "name": "Can change attachment", "content_type": 105}, "model": "auth.permission", "pk": 318}, {"fields": {"codename": "delete_attachment", "name": "Can delete attachment", "content_type": 105}, "model": "auth.permission", "pk": 319}, {"fields": {"codename": "add_attachmentrevision", "name": "Can add attachment revision", "content_type": 106}, "model": "auth.permission", "pk": 320}, {"fields": {"codename": "change_attachmentrevision", "name": "Can change attachment revision", "content_type": 106}, "model": "auth.permission", "pk": 321}, {"fields": {"codename": "delete_attachmentrevision", "name": "Can delete attachment revision", "content_type": 106}, "model": "auth.permission", "pk": 322}, {"fields": {"codename": "add_notificationtype", "name": "Can add type", "content_type": 107}, "model": "auth.permission", "pk": 323}, {"fields": {"codename": "change_notificationtype", "name": "Can change type", "content_type": 107}, "model": "auth.permission", "pk": 324}, {"fields": {"codename": "delete_notificationtype", "name": "Can delete type", "content_type": 107}, "model": "auth.permission", "pk": 325}, {"fields": {"codename": "add_settings", "name": "Can add settings", "content_type": 108}, "model": "auth.permission", "pk": 326}, {"fields": {"codename": "change_settings", "name": "Can change settings", "content_type": 108}, "model": "auth.permission", "pk": 327}, {"fields": {"codename": "delete_settings", "name": "Can delete settings", "content_type": 108}, "model": "auth.permission", "pk": 328}, {"fields": {"codename": "add_subscription", "name": "Can add subscription", "content_type": 109}, "model": "auth.permission", "pk": 329}, {"fields": {"codename": "change_subscription", "name": "Can change subscription", "content_type": 109}, "model": "auth.permission", "pk": 330}, {"fields": {"codename": "delete_subscription", "name": "Can delete subscription", "content_type": 109}, "model": "auth.permission", "pk": 331}, {"fields": {"codename": "add_notification", "name": "Can add notification", "content_type": 110}, "model": "auth.permission", "pk": 332}, {"fields": {"codename": "change_notification", "name": "Can change notification", "content_type": 110}, "model": "auth.permission", "pk": 333}, {"fields": {"codename": "delete_notification", "name": "Can delete notification", "content_type": 110}, "model": "auth.permission", "pk": 334}, {"fields": {"codename": "add_score", "name": "Can add score", "content_type": 111}, "model": "auth.permission", "pk": 335}, {"fields": {"codename": "change_score", "name": "Can change score", "content_type": 111}, "model": "auth.permission", "pk": 336}, {"fields": {"codename": "delete_score", "name": "Can delete score", "content_type": 111}, "model": "auth.permission", "pk": 337}, {"fields": {"codename": "add_puzzlecomplete", "name": "Can add puzzle complete", "content_type": 112}, "model": "auth.permission", "pk": 338}, {"fields": {"codename": "change_puzzlecomplete", "name": "Can change puzzle complete", "content_type": 112}, "model": "auth.permission", "pk": 339}, {"fields": {"codename": "delete_puzzlecomplete", "name": "Can delete puzzle complete", "content_type": 112}, "model": "auth.permission", "pk": 340}, {"fields": {"codename": "add_logentry", "name": "Can add log entry", "content_type": 113}, "model": "auth.permission", "pk": 341}, {"fields": {"codename": "change_logentry", "name": "Can change log entry", "content_type": 113}, "model": "auth.permission", "pk": 342}, {"fields": {"codename": "delete_logentry", "name": "Can delete log entry", "content_type": 113}, "model": "auth.permission", "pk": 343}, {"fields": {"codename": "add_role", "name": "Can add role", "content_type": 114}, "model": "auth.permission", "pk": 344}, {"fields": {"codename": "change_role", "name": "Can change role", "content_type": 114}, "model": "auth.permission", "pk": 345}, {"fields": {"codename": "delete_role", "name": "Can delete role", "content_type": 114}, "model": "auth.permission", "pk": 346}, {"fields": {"codename": "add_permission", "name": "Can add permission", "content_type": 115}, "model": "auth.permission", "pk": 347}, {"fields": {"codename": "change_permission", "name": "Can change permission", "content_type": 115}, "model": "auth.permission", "pk": 348}, {"fields": {"codename": "delete_permission", "name": "Can delete permission", "content_type": 115}, "model": "auth.permission", "pk": 349}, {"fields": {"codename": "add_note", "name": "Can add note", "content_type": 116}, "model": "auth.permission", "pk": 350}, {"fields": {"codename": "change_note", "name": "Can change note", "content_type": 116}, "model": "auth.permission", "pk": 351}, {"fields": {"codename": "delete_note", "name": "Can delete note", "content_type": 116}, "model": "auth.permission", "pk": 352}, {"fields": {"codename": "add_splashconfig", "name": "Can add splash config", "content_type": 117}, "model": "auth.permission", "pk": 353}, {"fields": {"codename": "change_splashconfig", "name": "Can change splash config", "content_type": 117}, "model": "auth.permission", "pk": 354}, {"fields": {"codename": "delete_splashconfig", "name": "Can delete splash config", "content_type": 117}, "model": "auth.permission", "pk": 355}, {"fields": {"codename": "add_userpreference", "name": "Can add user preference", "content_type": 118}, "model": "auth.permission", "pk": 356}, {"fields": {"codename": "change_userpreference", "name": "Can change user preference", "content_type": 118}, "model": "auth.permission", "pk": 357}, {"fields": {"codename": "delete_userpreference", "name": "Can delete user preference", "content_type": 118}, "model": "auth.permission", "pk": 358}, {"fields": {"codename": "add_usercoursetag", "name": "Can add user course tag", "content_type": 119}, "model": "auth.permission", "pk": 359}, {"fields": {"codename": "change_usercoursetag", "name": "Can change user course tag", "content_type": 119}, "model": "auth.permission", "pk": 360}, {"fields": {"codename": "delete_usercoursetag", "name": "Can delete user course tag", "content_type": 119}, "model": "auth.permission", "pk": 361}, {"fields": {"codename": "add_userorgtag", "name": "Can add user org tag", "content_type": 120}, "model": "auth.permission", "pk": 362}, {"fields": {"codename": "change_userorgtag", "name": "Can change user org tag", "content_type": 120}, "model": "auth.permission", "pk": 363}, {"fields": {"codename": "delete_userorgtag", "name": "Can delete user org tag", "content_type": 120}, "model": "auth.permission", "pk": 364}, {"fields": {"codename": "add_order", "name": "Can add order", "content_type": 121}, "model": "auth.permission", "pk": 365}, {"fields": {"codename": "change_order", "name": "Can change order", "content_type": 121}, "model": "auth.permission", "pk": 366}, {"fields": {"codename": "delete_order", "name": "Can delete order", "content_type": 121}, "model": "auth.permission", "pk": 367}, {"fields": {"codename": "add_orderitem", "name": "Can add order item", "content_type": 122}, "model": "auth.permission", "pk": 368}, {"fields": {"codename": "change_orderitem", "name": "Can change order item", "content_type": 122}, "model": "auth.permission", "pk": 369}, {"fields": {"codename": "delete_orderitem", "name": "Can delete order item", "content_type": 122}, "model": "auth.permission", "pk": 370}, {"fields": {"codename": "add_invoice", "name": "Can add invoice", "content_type": 123}, "model": "auth.permission", "pk": 371}, {"fields": {"codename": "change_invoice", "name": "Can change invoice", "content_type": 123}, "model": "auth.permission", "pk": 372}, {"fields": {"codename": "delete_invoice", "name": "Can delete invoice", "content_type": 123}, "model": "auth.permission", "pk": 373}, {"fields": {"codename": "add_invoicetransaction", "name": "Can add invoice transaction", "content_type": 124}, "model": "auth.permission", "pk": 374}, {"fields": {"codename": "change_invoicetransaction", "name": "Can change invoice transaction", "content_type": 124}, "model": "auth.permission", "pk": 375}, {"fields": {"codename": "delete_invoicetransaction", "name": "Can delete invoice transaction", "content_type": 124}, "model": "auth.permission", "pk": 376}, {"fields": {"codename": "add_invoiceitem", "name": "Can add invoice item", "content_type": 125}, "model": "auth.permission", "pk": 377}, {"fields": {"codename": "change_invoiceitem", "name": "Can change invoice item", "content_type": 125}, "model": "auth.permission", "pk": 378}, {"fields": {"codename": "delete_invoiceitem", "name": "Can delete invoice item", "content_type": 125}, "model": "auth.permission", "pk": 379}, {"fields": {"codename": "add_courseregistrationcodeinvoiceitem", "name": "Can add course registration code invoice item", "content_type": 126}, "model": "auth.permission", "pk": 380}, {"fields": {"codename": "change_courseregistrationcodeinvoiceitem", "name": "Can change course registration code invoice item", "content_type": 126}, "model": "auth.permission", "pk": 381}, {"fields": {"codename": "delete_courseregistrationcodeinvoiceitem", "name": "Can delete course registration code invoice item", "content_type": 126}, "model": "auth.permission", "pk": 382}, {"fields": {"codename": "add_invoicehistory", "name": "Can add invoice history", "content_type": 127}, "model": "auth.permission", "pk": 383}, {"fields": {"codename": "change_invoicehistory", "name": "Can change invoice history", "content_type": 127}, "model": "auth.permission", "pk": 384}, {"fields": {"codename": "delete_invoicehistory", "name": "Can delete invoice history", "content_type": 127}, "model": "auth.permission", "pk": 385}, {"fields": {"codename": "add_courseregistrationcode", "name": "Can add course registration code", "content_type": 128}, "model": "auth.permission", "pk": 386}, {"fields": {"codename": "change_courseregistrationcode", "name": "Can change course registration code", "content_type": 128}, "model": "auth.permission", "pk": 387}, {"fields": {"codename": "delete_courseregistrationcode", "name": "Can delete course registration code", "content_type": 128}, "model": "auth.permission", "pk": 388}, {"fields": {"codename": "add_registrationcoderedemption", "name": "Can add registration code redemption", "content_type": 129}, "model": "auth.permission", "pk": 389}, {"fields": {"codename": "change_registrationcoderedemption", "name": "Can change registration code redemption", "content_type": 129}, "model": "auth.permission", "pk": 390}, {"fields": {"codename": "delete_registrationcoderedemption", "name": "Can delete registration code redemption", "content_type": 129}, "model": "auth.permission", "pk": 391}, {"fields": {"codename": "add_coupon", "name": "Can add coupon", "content_type": 130}, "model": "auth.permission", "pk": 392}, {"fields": {"codename": "change_coupon", "name": "Can change coupon", "content_type": 130}, "model": "auth.permission", "pk": 393}, {"fields": {"codename": "delete_coupon", "name": "Can delete coupon", "content_type": 130}, "model": "auth.permission", "pk": 394}, {"fields": {"codename": "add_couponredemption", "name": "Can add coupon redemption", "content_type": 131}, "model": "auth.permission", "pk": 395}, {"fields": {"codename": "change_couponredemption", "name": "Can change coupon redemption", "content_type": 131}, "model": "auth.permission", "pk": 396}, {"fields": {"codename": "delete_couponredemption", "name": "Can delete coupon redemption", "content_type": 131}, "model": "auth.permission", "pk": 397}, {"fields": {"codename": "add_paidcourseregistration", "name": "Can add paid course registration", "content_type": 132}, "model": "auth.permission", "pk": 398}, {"fields": {"codename": "change_paidcourseregistration", "name": "Can change paid course registration", "content_type": 132}, "model": "auth.permission", "pk": 399}, {"fields": {"codename": "delete_paidcourseregistration", "name": "Can delete paid course registration", "content_type": 132}, "model": "auth.permission", "pk": 400}, {"fields": {"codename": "add_courseregcodeitem", "name": "Can add course reg code item", "content_type": 133}, "model": "auth.permission", "pk": 401}, {"fields": {"codename": "change_courseregcodeitem", "name": "Can change course reg code item", "content_type": 133}, "model": "auth.permission", "pk": 402}, {"fields": {"codename": "delete_courseregcodeitem", "name": "Can delete course reg code item", "content_type": 133}, "model": "auth.permission", "pk": 403}, {"fields": {"codename": "add_courseregcodeitemannotation", "name": "Can add course reg code item annotation", "content_type": 134}, "model": "auth.permission", "pk": 404}, {"fields": {"codename": "change_courseregcodeitemannotation", "name": "Can change course reg code item annotation", "content_type": 134}, "model": "auth.permission", "pk": 405}, {"fields": {"codename": "delete_courseregcodeitemannotation", "name": "Can delete course reg code item annotation", "content_type": 134}, "model": "auth.permission", "pk": 406}, {"fields": {"codename": "add_paidcourseregistrationannotation", "name": "Can add paid course registration annotation", "content_type": 135}, "model": "auth.permission", "pk": 407}, {"fields": {"codename": "change_paidcourseregistrationannotation", "name": "Can change paid course registration annotation", "content_type": 135}, "model": "auth.permission", "pk": 408}, {"fields": {"codename": "delete_paidcourseregistrationannotation", "name": "Can delete paid course registration annotation", "content_type": 135}, "model": "auth.permission", "pk": 409}, {"fields": {"codename": "add_certificateitem", "name": "Can add certificate item", "content_type": 136}, "model": "auth.permission", "pk": 410}, {"fields": {"codename": "change_certificateitem", "name": "Can change certificate item", "content_type": 136}, "model": "auth.permission", "pk": 411}, {"fields": {"codename": "delete_certificateitem", "name": "Can delete certificate item", "content_type": 136}, "model": "auth.permission", "pk": 412}, {"fields": {"codename": "add_donationconfiguration", "name": "Can add donation configuration", "content_type": 137}, "model": "auth.permission", "pk": 413}, {"fields": {"codename": "change_donationconfiguration", "name": "Can change donation configuration", "content_type": 137}, "model": "auth.permission", "pk": 414}, {"fields": {"codename": "delete_donationconfiguration", "name": "Can delete donation configuration", "content_type": 137}, "model": "auth.permission", "pk": 415}, {"fields": {"codename": "add_donation", "name": "Can add donation", "content_type": 138}, "model": "auth.permission", "pk": 416}, {"fields": {"codename": "change_donation", "name": "Can change donation", "content_type": 138}, "model": "auth.permission", "pk": 417}, {"fields": {"codename": "delete_donation", "name": "Can delete donation", "content_type": 138}, "model": "auth.permission", "pk": 418}, {"fields": {"codename": "add_coursemode", "name": "Can add course mode", "content_type": 139}, "model": "auth.permission", "pk": 419}, {"fields": {"codename": "change_coursemode", "name": "Can change course mode", "content_type": 139}, "model": "auth.permission", "pk": 420}, {"fields": {"codename": "delete_coursemode", "name": "Can delete course mode", "content_type": 139}, "model": "auth.permission", "pk": 421}, {"fields": {"codename": "add_coursemodesarchive", "name": "Can add course modes archive", "content_type": 140}, "model": "auth.permission", "pk": 422}, {"fields": {"codename": "change_coursemodesarchive", "name": "Can change course modes archive", "content_type": 140}, "model": "auth.permission", "pk": 423}, {"fields": {"codename": "delete_coursemodesarchive", "name": "Can delete course modes archive", "content_type": 140}, "model": "auth.permission", "pk": 424}, {"fields": {"codename": "add_softwaresecurephotoverification", "name": "Can add software secure photo verification", "content_type": 141}, "model": "auth.permission", "pk": 425}, {"fields": {"codename": "change_softwaresecurephotoverification", "name": "Can change software secure photo verification", "content_type": 141}, "model": "auth.permission", "pk": 426}, {"fields": {"codename": "delete_softwaresecurephotoverification", "name": "Can delete software secure photo verification", "content_type": 141}, "model": "auth.permission", "pk": 427}, {"fields": {"codename": "add_historicalverificationdeadline", "name": "Can add historical verification deadline", "content_type": 142}, "model": "auth.permission", "pk": 428}, {"fields": {"codename": "change_historicalverificationdeadline", "name": "Can change historical verification deadline", "content_type": 142}, "model": "auth.permission", "pk": 429}, {"fields": {"codename": "delete_historicalverificationdeadline", "name": "Can delete historical verification deadline", "content_type": 142}, "model": "auth.permission", "pk": 430}, {"fields": {"codename": "add_verificationdeadline", "name": "Can add verification deadline", "content_type": 143}, "model": "auth.permission", "pk": 431}, {"fields": {"codename": "change_verificationdeadline", "name": "Can change verification deadline", "content_type": 143}, "model": "auth.permission", "pk": 432}, {"fields": {"codename": "delete_verificationdeadline", "name": "Can delete verification deadline", "content_type": 143}, "model": "auth.permission", "pk": 433}, {"fields": {"codename": "add_verificationcheckpoint", "name": "Can add verification checkpoint", "content_type": 144}, "model": "auth.permission", "pk": 434}, {"fields": {"codename": "change_verificationcheckpoint", "name": "Can change verification checkpoint", "content_type": 144}, "model": "auth.permission", "pk": 435}, {"fields": {"codename": "delete_verificationcheckpoint", "name": "Can delete verification checkpoint", "content_type": 144}, "model": "auth.permission", "pk": 436}, {"fields": {"codename": "add_verificationstatus", "name": "Can add Verification Status", "content_type": 145}, "model": "auth.permission", "pk": 437}, {"fields": {"codename": "change_verificationstatus", "name": "Can change Verification Status", "content_type": 145}, "model": "auth.permission", "pk": 438}, {"fields": {"codename": "delete_verificationstatus", "name": "Can delete Verification Status", "content_type": 145}, "model": "auth.permission", "pk": 439}, {"fields": {"codename": "add_incoursereverificationconfiguration", "name": "Can add in course reverification configuration", "content_type": 146}, "model": "auth.permission", "pk": 440}, {"fields": {"codename": "change_incoursereverificationconfiguration", "name": "Can change in course reverification configuration", "content_type": 146}, "model": "auth.permission", "pk": 441}, {"fields": {"codename": "delete_incoursereverificationconfiguration", "name": "Can delete in course reverification configuration", "content_type": 146}, "model": "auth.permission", "pk": 442}, {"fields": {"codename": "add_icrvstatusemailsconfiguration", "name": "Can add icrv status emails configuration", "content_type": 147}, "model": "auth.permission", "pk": 443}, {"fields": {"codename": "change_icrvstatusemailsconfiguration", "name": "Can change icrv status emails configuration", "content_type": 147}, "model": "auth.permission", "pk": 444}, {"fields": {"codename": "delete_icrvstatusemailsconfiguration", "name": "Can delete icrv status emails configuration", "content_type": 147}, "model": "auth.permission", "pk": 445}, {"fields": {"codename": "add_skippedreverification", "name": "Can add skipped reverification", "content_type": 148}, "model": "auth.permission", "pk": 446}, {"fields": {"codename": "change_skippedreverification", "name": "Can change skipped reverification", "content_type": 148}, "model": "auth.permission", "pk": 447}, {"fields": {"codename": "delete_skippedreverification", "name": "Can delete skipped reverification", "content_type": 148}, "model": "auth.permission", "pk": 448}, {"fields": {"codename": "add_darklangconfig", "name": "Can add dark lang config", "content_type": 149}, "model": "auth.permission", "pk": 449}, {"fields": {"codename": "change_darklangconfig", "name": "Can change dark lang config", "content_type": 149}, "model": "auth.permission", "pk": 450}, {"fields": {"codename": "delete_darklangconfig", "name": "Can delete dark lang config", "content_type": 149}, "model": "auth.permission", "pk": 451}, {"fields": {"codename": "add_embargoedcourse", "name": "Can add embargoed course", "content_type": 150}, "model": "auth.permission", "pk": 452}, {"fields": {"codename": "change_embargoedcourse", "name": "Can change embargoed course", "content_type": 150}, "model": "auth.permission", "pk": 453}, {"fields": {"codename": "delete_embargoedcourse", "name": "Can delete embargoed course", "content_type": 150}, "model": "auth.permission", "pk": 454}, {"fields": {"codename": "add_embargoedstate", "name": "Can add embargoed state", "content_type": 151}, "model": "auth.permission", "pk": 455}, {"fields": {"codename": "change_embargoedstate", "name": "Can change embargoed state", "content_type": 151}, "model": "auth.permission", "pk": 456}, {"fields": {"codename": "delete_embargoedstate", "name": "Can delete embargoed state", "content_type": 151}, "model": "auth.permission", "pk": 457}, {"fields": {"codename": "add_restrictedcourse", "name": "Can add restricted course", "content_type": 152}, "model": "auth.permission", "pk": 458}, {"fields": {"codename": "change_restrictedcourse", "name": "Can change restricted course", "content_type": 152}, "model": "auth.permission", "pk": 459}, {"fields": {"codename": "delete_restrictedcourse", "name": "Can delete restricted course", "content_type": 152}, "model": "auth.permission", "pk": 460}, {"fields": {"codename": "add_country", "name": "Can add country", "content_type": 153}, "model": "auth.permission", "pk": 461}, {"fields": {"codename": "change_country", "name": "Can change country", "content_type": 153}, "model": "auth.permission", "pk": 462}, {"fields": {"codename": "delete_country", "name": "Can delete country", "content_type": 153}, "model": "auth.permission", "pk": 463}, {"fields": {"codename": "add_countryaccessrule", "name": "Can add country access rule", "content_type": 154}, "model": "auth.permission", "pk": 464}, {"fields": {"codename": "change_countryaccessrule", "name": "Can change country access rule", "content_type": 154}, "model": "auth.permission", "pk": 465}, {"fields": {"codename": "delete_countryaccessrule", "name": "Can delete country access rule", "content_type": 154}, "model": "auth.permission", "pk": 466}, {"fields": {"codename": "add_courseaccessrulehistory", "name": "Can add course access rule history", "content_type": 155}, "model": "auth.permission", "pk": 467}, {"fields": {"codename": "change_courseaccessrulehistory", "name": "Can change course access rule history", "content_type": 155}, "model": "auth.permission", "pk": 468}, {"fields": {"codename": "delete_courseaccessrulehistory", "name": "Can delete course access rule history", "content_type": 155}, "model": "auth.permission", "pk": 469}, {"fields": {"codename": "add_ipfilter", "name": "Can add ip filter", "content_type": 156}, "model": "auth.permission", "pk": 470}, {"fields": {"codename": "change_ipfilter", "name": "Can change ip filter", "content_type": 156}, "model": "auth.permission", "pk": 471}, {"fields": {"codename": "delete_ipfilter", "name": "Can delete ip filter", "content_type": 156}, "model": "auth.permission", "pk": 472}, {"fields": {"codename": "add_coursererunstate", "name": "Can add course rerun state", "content_type": 157}, "model": "auth.permission", "pk": 473}, {"fields": {"codename": "change_coursererunstate", "name": "Can change course rerun state", "content_type": 157}, "model": "auth.permission", "pk": 474}, {"fields": {"codename": "delete_coursererunstate", "name": "Can delete course rerun state", "content_type": 157}, "model": "auth.permission", "pk": 475}, {"fields": {"codename": "add_mobileapiconfig", "name": "Can add mobile api config", "content_type": 158}, "model": "auth.permission", "pk": 476}, {"fields": {"codename": "change_mobileapiconfig", "name": "Can change mobile api config", "content_type": 158}, "model": "auth.permission", "pk": 477}, {"fields": {"codename": "delete_mobileapiconfig", "name": "Can delete mobile api config", "content_type": 158}, "model": "auth.permission", "pk": 478}, {"fields": {"codename": "add_usersocialauth", "name": "Can add user social auth", "content_type": 159}, "model": "auth.permission", "pk": 479}, {"fields": {"codename": "change_usersocialauth", "name": "Can change user social auth", "content_type": 159}, "model": "auth.permission", "pk": 480}, {"fields": {"codename": "delete_usersocialauth", "name": "Can delete user social auth", "content_type": 159}, "model": "auth.permission", "pk": 481}, {"fields": {"codename": "add_nonce", "name": "Can add nonce", "content_type": 160}, "model": "auth.permission", "pk": 482}, {"fields": {"codename": "change_nonce", "name": "Can change nonce", "content_type": 160}, "model": "auth.permission", "pk": 483}, {"fields": {"codename": "delete_nonce", "name": "Can delete nonce", "content_type": 160}, "model": "auth.permission", "pk": 484}, {"fields": {"codename": "add_association", "name": "Can add association", "content_type": 161}, "model": "auth.permission", "pk": 485}, {"fields": {"codename": "change_association", "name": "Can change association", "content_type": 161}, "model": "auth.permission", "pk": 486}, {"fields": {"codename": "delete_association", "name": "Can delete association", "content_type": 161}, "model": "auth.permission", "pk": 487}, {"fields": {"codename": "add_code", "name": "Can add code", "content_type": 162}, "model": "auth.permission", "pk": 488}, {"fields": {"codename": "change_code", "name": "Can change code", "content_type": 162}, "model": "auth.permission", "pk": 489}, {"fields": {"codename": "delete_code", "name": "Can delete code", "content_type": 162}, "model": "auth.permission", "pk": 490}, {"fields": {"codename": "add_surveyform", "name": "Can add survey form", "content_type": 163}, "model": "auth.permission", "pk": 491}, {"fields": {"codename": "change_surveyform", "name": "Can change survey form", "content_type": 163}, "model": "auth.permission", "pk": 492}, {"fields": {"codename": "delete_surveyform", "name": "Can delete survey form", "content_type": 163}, "model": "auth.permission", "pk": 493}, {"fields": {"codename": "add_surveyanswer", "name": "Can add survey answer", "content_type": 164}, "model": "auth.permission", "pk": 494}, {"fields": {"codename": "change_surveyanswer", "name": "Can change survey answer", "content_type": 164}, "model": "auth.permission", "pk": 495}, {"fields": {"codename": "delete_surveyanswer", "name": "Can delete survey answer", "content_type": 164}, "model": "auth.permission", "pk": 496}, {"fields": {"codename": "add_xblockasidesconfig", "name": "Can add x block asides config", "content_type": 165}, "model": "auth.permission", "pk": 497}, {"fields": {"codename": "change_xblockasidesconfig", "name": "Can change x block asides config", "content_type": 165}, "model": "auth.permission", "pk": 498}, {"fields": {"codename": "delete_xblockasidesconfig", "name": "Can delete x block asides config", "content_type": 165}, "model": "auth.permission", "pk": 499}, {"fields": {"codename": "add_courseoverview", "name": "Can add course overview", "content_type": 166}, "model": "auth.permission", "pk": 500}, {"fields": {"codename": "change_courseoverview", "name": "Can change course overview", "content_type": 166}, "model": "auth.permission", "pk": 501}, {"fields": {"codename": "delete_courseoverview", "name": "Can delete course overview", "content_type": 166}, "model": "auth.permission", "pk": 502}, {"fields": {"codename": "add_courseoverviewtab", "name": "Can add course overview tab", "content_type": 167}, "model": "auth.permission", "pk": 503}, {"fields": {"codename": "change_courseoverviewtab", "name": "Can change course overview tab", "content_type": 167}, "model": "auth.permission", "pk": 504}, {"fields": {"codename": "delete_courseoverviewtab", "name": "Can delete course overview tab", "content_type": 167}, "model": "auth.permission", "pk": 505}, {"fields": {"codename": "add_coursestructure", "name": "Can add course structure", "content_type": 168}, "model": "auth.permission", "pk": 506}, {"fields": {"codename": "change_coursestructure", "name": "Can change course structure", "content_type": 168}, "model": "auth.permission", "pk": 507}, {"fields": {"codename": "delete_coursestructure", "name": "Can delete course structure", "content_type": 168}, "model": "auth.permission", "pk": 508}, {"fields": {"codename": "add_corsmodel", "name": "Can add cors model", "content_type": 169}, "model": "auth.permission", "pk": 509}, {"fields": {"codename": "change_corsmodel", "name": "Can change cors model", "content_type": 169}, "model": "auth.permission", "pk": 510}, {"fields": {"codename": "delete_corsmodel", "name": "Can delete cors model", "content_type": 169}, "model": "auth.permission", "pk": 511}, {"fields": {"codename": "add_xdomainproxyconfiguration", "name": "Can add x domain proxy configuration", "content_type": 170}, "model": "auth.permission", "pk": 512}, {"fields": {"codename": "change_xdomainproxyconfiguration", "name": "Can change x domain proxy configuration", "content_type": 170}, "model": "auth.permission", "pk": 513}, {"fields": {"codename": "delete_xdomainproxyconfiguration", "name": "Can delete x domain proxy configuration", "content_type": 170}, "model": "auth.permission", "pk": 514}, {"fields": {"codename": "add_creditprovider", "name": "Can add credit provider", "content_type": 171}, "model": "auth.permission", "pk": 515}, {"fields": {"codename": "change_creditprovider", "name": "Can change credit provider", "content_type": 171}, "model": "auth.permission", "pk": 516}, {"fields": {"codename": "delete_creditprovider", "name": "Can delete credit provider", "content_type": 171}, "model": "auth.permission", "pk": 517}, {"fields": {"codename": "add_creditcourse", "name": "Can add credit course", "content_type": 172}, "model": "auth.permission", "pk": 518}, {"fields": {"codename": "change_creditcourse", "name": "Can change credit course", "content_type": 172}, "model": "auth.permission", "pk": 519}, {"fields": {"codename": "delete_creditcourse", "name": "Can delete credit course", "content_type": 172}, "model": "auth.permission", "pk": 520}, {"fields": {"codename": "add_creditrequirement", "name": "Can add credit requirement", "content_type": 173}, "model": "auth.permission", "pk": 521}, {"fields": {"codename": "change_creditrequirement", "name": "Can change credit requirement", "content_type": 173}, "model": "auth.permission", "pk": 522}, {"fields": {"codename": "delete_creditrequirement", "name": "Can delete credit requirement", "content_type": 173}, "model": "auth.permission", "pk": 523}, {"fields": {"codename": "add_historicalcreditrequirementstatus", "name": "Can add historical credit requirement status", "content_type": 174}, "model": "auth.permission", "pk": 524}, {"fields": {"codename": "change_historicalcreditrequirementstatus", "name": "Can change historical credit requirement status", "content_type": 174}, "model": "auth.permission", "pk": 525}, {"fields": {"codename": "delete_historicalcreditrequirementstatus", "name": "Can delete historical credit requirement status", "content_type": 174}, "model": "auth.permission", "pk": 526}, {"fields": {"codename": "add_creditrequirementstatus", "name": "Can add credit requirement status", "content_type": 175}, "model": "auth.permission", "pk": 527}, {"fields": {"codename": "change_creditrequirementstatus", "name": "Can change credit requirement status", "content_type": 175}, "model": "auth.permission", "pk": 528}, {"fields": {"codename": "delete_creditrequirementstatus", "name": "Can delete credit requirement status", "content_type": 175}, "model": "auth.permission", "pk": 529}, {"fields": {"codename": "add_crediteligibility", "name": "Can add credit eligibility", "content_type": 176}, "model": "auth.permission", "pk": 530}, {"fields": {"codename": "change_crediteligibility", "name": "Can change credit eligibility", "content_type": 176}, "model": "auth.permission", "pk": 531}, {"fields": {"codename": "delete_crediteligibility", "name": "Can delete credit eligibility", "content_type": 176}, "model": "auth.permission", "pk": 532}, {"fields": {"codename": "add_historicalcreditrequest", "name": "Can add historical credit request", "content_type": 177}, "model": "auth.permission", "pk": 533}, {"fields": {"codename": "change_historicalcreditrequest", "name": "Can change historical credit request", "content_type": 177}, "model": "auth.permission", "pk": 534}, {"fields": {"codename": "delete_historicalcreditrequest", "name": "Can delete historical credit request", "content_type": 177}, "model": "auth.permission", "pk": 535}, {"fields": {"codename": "add_creditrequest", "name": "Can add credit request", "content_type": 178}, "model": "auth.permission", "pk": 536}, {"fields": {"codename": "change_creditrequest", "name": "Can change credit request", "content_type": 178}, "model": "auth.permission", "pk": 537}, {"fields": {"codename": "delete_creditrequest", "name": "Can delete credit request", "content_type": 178}, "model": "auth.permission", "pk": 538}, {"fields": {"codename": "add_courseteam", "name": "Can add course team", "content_type": 179}, "model": "auth.permission", "pk": 539}, {"fields": {"codename": "change_courseteam", "name": "Can change course team", "content_type": 179}, "model": "auth.permission", "pk": 540}, {"fields": {"codename": "delete_courseteam", "name": "Can delete course team", "content_type": 179}, "model": "auth.permission", "pk": 541}, {"fields": {"codename": "add_courseteammembership", "name": "Can add course team membership", "content_type": 180}, "model": "auth.permission", "pk": 542}, {"fields": {"codename": "change_courseteammembership", "name": "Can change course team membership", "content_type": 180}, "model": "auth.permission", "pk": 543}, {"fields": {"codename": "delete_courseteammembership", "name": "Can delete course team membership", "content_type": 180}, "model": "auth.permission", "pk": 544}, {"fields": {"codename": "add_xblockdisableconfig", "name": "Can add x block disable config", "content_type": 181}, "model": "auth.permission", "pk": 545}, {"fields": {"codename": "change_xblockdisableconfig", "name": "Can change x block disable config", "content_type": 181}, "model": "auth.permission", "pk": 546}, {"fields": {"codename": "delete_xblockdisableconfig", "name": "Can delete x block disable config", "content_type": 181}, "model": "auth.permission", "pk": 547}, {"fields": {"codename": "add_programsapiconfig", "name": "Can add programs api config", "content_type": 182}, "model": "auth.permission", "pk": 548}, {"fields": {"codename": "change_programsapiconfig", "name": "Can change programs api config", "content_type": 182}, "model": "auth.permission", "pk": 549}, {"fields": {"codename": "delete_programsapiconfig", "name": "Can delete programs api config", "content_type": 182}, "model": "auth.permission", "pk": 550}, {"fields": {"codename": "add_selfpacedconfiguration", "name": "Can add self paced configuration", "content_type": 183}, "model": "auth.permission", "pk": 551}, {"fields": {"codename": "change_selfpacedconfiguration", "name": "Can change self paced configuration", "content_type": 183}, "model": "auth.permission", "pk": 552}, {"fields": {"codename": "delete_selfpacedconfiguration", "name": "Can delete self paced configuration", "content_type": 183}, "model": "auth.permission", "pk": 553}, {"fields": {"codename": "add_kvstore", "name": "Can add kv store", "content_type": 184}, "model": "auth.permission", "pk": 554}, {"fields": {"codename": "change_kvstore", "name": "Can change kv store", "content_type": 184}, "model": "auth.permission", "pk": 555}, {"fields": {"codename": "delete_kvstore", "name": "Can delete kv store", "content_type": 184}, "model": "auth.permission", "pk": 556}, {"fields": {"codename": "add_studentitem", "name": "Can add student item", "content_type": 185}, "model": "auth.permission", "pk": 557}, {"fields": {"codename": "change_studentitem", "name": "Can change student item", "content_type": 185}, "model": "auth.permission", "pk": 558}, {"fields": {"codename": "delete_studentitem", "name": "Can delete student item", "content_type": 185}, "model": "auth.permission", "pk": 559}, {"fields": {"codename": "add_submission", "name": "Can add submission", "content_type": 186}, "model": "auth.permission", "pk": 560}, {"fields": {"codename": "change_submission", "name": "Can change submission", "content_type": 186}, "model": "auth.permission", "pk": 561}, {"fields": {"codename": "delete_submission", "name": "Can delete submission", "content_type": 186}, "model": "auth.permission", "pk": 562}, {"fields": {"codename": "add_score", "name": "Can add score", "content_type": 187}, "model": "auth.permission", "pk": 563}, {"fields": {"codename": "change_score", "name": "Can change score", "content_type": 187}, "model": "auth.permission", "pk": 564}, {"fields": {"codename": "delete_score", "name": "Can delete score", "content_type": 187}, "model": "auth.permission", "pk": 565}, {"fields": {"codename": "add_scoresummary", "name": "Can add score summary", "content_type": 188}, "model": "auth.permission", "pk": 566}, {"fields": {"codename": "change_scoresummary", "name": "Can change score summary", "content_type": 188}, "model": "auth.permission", "pk": 567}, {"fields": {"codename": "delete_scoresummary", "name": "Can delete score summary", "content_type": 188}, "model": "auth.permission", "pk": 568}, {"fields": {"codename": "add_rubric", "name": "Can add rubric", "content_type": 189}, "model": "auth.permission", "pk": 569}, {"fields": {"codename": "change_rubric", "name": "Can change rubric", "content_type": 189}, "model": "auth.permission", "pk": 570}, {"fields": {"codename": "delete_rubric", "name": "Can delete rubric", "content_type": 189}, "model": "auth.permission", "pk": 571}, {"fields": {"codename": "add_criterion", "name": "Can add criterion", "content_type": 190}, "model": "auth.permission", "pk": 572}, {"fields": {"codename": "change_criterion", "name": "Can change criterion", "content_type": 190}, "model": "auth.permission", "pk": 573}, {"fields": {"codename": "delete_criterion", "name": "Can delete criterion", "content_type": 190}, "model": "auth.permission", "pk": 574}, {"fields": {"codename": "add_criterionoption", "name": "Can add criterion option", "content_type": 191}, "model": "auth.permission", "pk": 575}, {"fields": {"codename": "change_criterionoption", "name": "Can change criterion option", "content_type": 191}, "model": "auth.permission", "pk": 576}, {"fields": {"codename": "delete_criterionoption", "name": "Can delete criterion option", "content_type": 191}, "model": "auth.permission", "pk": 577}, {"fields": {"codename": "add_assessment", "name": "Can add assessment", "content_type": 192}, "model": "auth.permission", "pk": 578}, {"fields": {"codename": "change_assessment", "name": "Can change assessment", "content_type": 192}, "model": "auth.permission", "pk": 579}, {"fields": {"codename": "delete_assessment", "name": "Can delete assessment", "content_type": 192}, "model": "auth.permission", "pk": 580}, {"fields": {"codename": "add_assessmentpart", "name": "Can add assessment part", "content_type": 193}, "model": "auth.permission", "pk": 581}, {"fields": {"codename": "change_assessmentpart", "name": "Can change assessment part", "content_type": 193}, "model": "auth.permission", "pk": 582}, {"fields": {"codename": "delete_assessmentpart", "name": "Can delete assessment part", "content_type": 193}, "model": "auth.permission", "pk": 583}, {"fields": {"codename": "add_assessmentfeedbackoption", "name": "Can add assessment feedback option", "content_type": 194}, "model": "auth.permission", "pk": 584}, {"fields": {"codename": "change_assessmentfeedbackoption", "name": "Can change assessment feedback option", "content_type": 194}, "model": "auth.permission", "pk": 585}, {"fields": {"codename": "delete_assessmentfeedbackoption", "name": "Can delete assessment feedback option", "content_type": 194}, "model": "auth.permission", "pk": 586}, {"fields": {"codename": "add_assessmentfeedback", "name": "Can add assessment feedback", "content_type": 195}, "model": "auth.permission", "pk": 587}, {"fields": {"codename": "change_assessmentfeedback", "name": "Can change assessment feedback", "content_type": 195}, "model": "auth.permission", "pk": 588}, {"fields": {"codename": "delete_assessmentfeedback", "name": "Can delete assessment feedback", "content_type": 195}, "model": "auth.permission", "pk": 589}, {"fields": {"codename": "add_peerworkflow", "name": "Can add peer workflow", "content_type": 196}, "model": "auth.permission", "pk": 590}, {"fields": {"codename": "change_peerworkflow", "name": "Can change peer workflow", "content_type": 196}, "model": "auth.permission", "pk": 591}, {"fields": {"codename": "delete_peerworkflow", "name": "Can delete peer workflow", "content_type": 196}, "model": "auth.permission", "pk": 592}, {"fields": {"codename": "add_peerworkflowitem", "name": "Can add peer workflow item", "content_type": 197}, "model": "auth.permission", "pk": 593}, {"fields": {"codename": "change_peerworkflowitem", "name": "Can change peer workflow item", "content_type": 197}, "model": "auth.permission", "pk": 594}, {"fields": {"codename": "delete_peerworkflowitem", "name": "Can delete peer workflow item", "content_type": 197}, "model": "auth.permission", "pk": 595}, {"fields": {"codename": "add_trainingexample", "name": "Can add training example", "content_type": 198}, "model": "auth.permission", "pk": 596}, {"fields": {"codename": "change_trainingexample", "name": "Can change training example", "content_type": 198}, "model": "auth.permission", "pk": 597}, {"fields": {"codename": "delete_trainingexample", "name": "Can delete training example", "content_type": 198}, "model": "auth.permission", "pk": 598}, {"fields": {"codename": "add_studenttrainingworkflow", "name": "Can add student training workflow", "content_type": 199}, "model": "auth.permission", "pk": 599}, {"fields": {"codename": "change_studenttrainingworkflow", "name": "Can change student training workflow", "content_type": 199}, "model": "auth.permission", "pk": 600}, {"fields": {"codename": "delete_studenttrainingworkflow", "name": "Can delete student training workflow", "content_type": 199}, "model": "auth.permission", "pk": 601}, {"fields": {"codename": "add_studenttrainingworkflowitem", "name": "Can add student training workflow item", "content_type": 200}, "model": "auth.permission", "pk": 602}, {"fields": {"codename": "change_studenttrainingworkflowitem", "name": "Can change student training workflow item", "content_type": 200}, "model": "auth.permission", "pk": 603}, {"fields": {"codename": "delete_studenttrainingworkflowitem", "name": "Can delete student training workflow item", "content_type": 200}, "model": "auth.permission", "pk": 604}, {"fields": {"codename": "add_aiclassifierset", "name": "Can add ai classifier set", "content_type": 201}, "model": "auth.permission", "pk": 605}, {"fields": {"codename": "change_aiclassifierset", "name": "Can change ai classifier set", "content_type": 201}, "model": "auth.permission", "pk": 606}, {"fields": {"codename": "delete_aiclassifierset", "name": "Can delete ai classifier set", "content_type": 201}, "model": "auth.permission", "pk": 607}, {"fields": {"codename": "add_aiclassifier", "name": "Can add ai classifier", "content_type": 202}, "model": "auth.permission", "pk": 608}, {"fields": {"codename": "change_aiclassifier", "name": "Can change ai classifier", "content_type": 202}, "model": "auth.permission", "pk": 609}, {"fields": {"codename": "delete_aiclassifier", "name": "Can delete ai classifier", "content_type": 202}, "model": "auth.permission", "pk": 610}, {"fields": {"codename": "add_aitrainingworkflow", "name": "Can add ai training workflow", "content_type": 203}, "model": "auth.permission", "pk": 611}, {"fields": {"codename": "change_aitrainingworkflow", "name": "Can change ai training workflow", "content_type": 203}, "model": "auth.permission", "pk": 612}, {"fields": {"codename": "delete_aitrainingworkflow", "name": "Can delete ai training workflow", "content_type": 203}, "model": "auth.permission", "pk": 613}, {"fields": {"codename": "add_aigradingworkflow", "name": "Can add ai grading workflow", "content_type": 204}, "model": "auth.permission", "pk": 614}, {"fields": {"codename": "change_aigradingworkflow", "name": "Can change ai grading workflow", "content_type": 204}, "model": "auth.permission", "pk": 615}, {"fields": {"codename": "delete_aigradingworkflow", "name": "Can delete ai grading workflow", "content_type": 204}, "model": "auth.permission", "pk": 616}, {"fields": {"codename": "add_assessmentworkflow", "name": "Can add assessment workflow", "content_type": 205}, "model": "auth.permission", "pk": 617}, {"fields": {"codename": "change_assessmentworkflow", "name": "Can change assessment workflow", "content_type": 205}, "model": "auth.permission", "pk": 618}, {"fields": {"codename": "delete_assessmentworkflow", "name": "Can delete assessment workflow", "content_type": 205}, "model": "auth.permission", "pk": 619}, {"fields": {"codename": "add_assessmentworkflowstep", "name": "Can add assessment workflow step", "content_type": 206}, "model": "auth.permission", "pk": 620}, {"fields": {"codename": "change_assessmentworkflowstep", "name": "Can change assessment workflow step", "content_type": 206}, "model": "auth.permission", "pk": 621}, {"fields": {"codename": "delete_assessmentworkflowstep", "name": "Can delete assessment workflow step", "content_type": 206}, "model": "auth.permission", "pk": 622}, {"fields": {"codename": "add_assessmentworkflowcancellation", "name": "Can add assessment workflow cancellation", "content_type": 207}, "model": "auth.permission", "pk": 623}, {"fields": {"codename": "change_assessmentworkflowcancellation", "name": "Can change assessment workflow cancellation", "content_type": 207}, "model": "auth.permission", "pk": 624}, {"fields": {"codename": "delete_assessmentworkflowcancellation", "name": "Can delete assessment workflow cancellation", "content_type": 207}, "model": "auth.permission", "pk": 625}, {"fields": {"codename": "add_profile", "name": "Can add profile", "content_type": 208}, "model": "auth.permission", "pk": 626}, {"fields": {"codename": "change_profile", "name": "Can change profile", "content_type": 208}, "model": "auth.permission", "pk": 627}, {"fields": {"codename": "delete_profile", "name": "Can delete profile", "content_type": 208}, "model": "auth.permission", "pk": 628}, {"fields": {"codename": "add_video", "name": "Can add video", "content_type": 209}, "model": "auth.permission", "pk": 629}, {"fields": {"codename": "change_video", "name": "Can change video", "content_type": 209}, "model": "auth.permission", "pk": 630}, {"fields": {"codename": "delete_video", "name": "Can delete video", "content_type": 209}, "model": "auth.permission", "pk": 631}, {"fields": {"codename": "add_coursevideo", "name": "Can add course video", "content_type": 210}, "model": "auth.permission", "pk": 632}, {"fields": {"codename": "change_coursevideo", "name": "Can change course video", "content_type": 210}, "model": "auth.permission", "pk": 633}, {"fields": {"codename": "delete_coursevideo", "name": "Can delete course video", "content_type": 210}, "model": "auth.permission", "pk": 634}, {"fields": {"codename": "add_encodedvideo", "name": "Can add encoded video", "content_type": 211}, "model": "auth.permission", "pk": 635}, {"fields": {"codename": "change_encodedvideo", "name": "Can change encoded video", "content_type": 211}, "model": "auth.permission", "pk": 636}, {"fields": {"codename": "delete_encodedvideo", "name": "Can delete encoded video", "content_type": 211}, "model": "auth.permission", "pk": 637}, {"fields": {"codename": "add_subtitle", "name": "Can add subtitle", "content_type": 212}, "model": "auth.permission", "pk": 638}, {"fields": {"codename": "change_subtitle", "name": "Can change subtitle", "content_type": 212}, "model": "auth.permission", "pk": 639}, {"fields": {"codename": "delete_subtitle", "name": "Can delete subtitle", "content_type": 212}, "model": "auth.permission", "pk": 640}, {"fields": {"codename": "add_milestone", "name": "Can add milestone", "content_type": 213}, "model": "auth.permission", "pk": 641}, {"fields": {"codename": "change_milestone", "name": "Can change milestone", "content_type": 213}, "model": "auth.permission", "pk": 642}, {"fields": {"codename": "delete_milestone", "name": "Can delete milestone", "content_type": 213}, "model": "auth.permission", "pk": 643}, {"fields": {"codename": "add_milestonerelationshiptype", "name": "Can add milestone relationship type", "content_type": 214}, "model": "auth.permission", "pk": 644}, {"fields": {"codename": "change_milestonerelationshiptype", "name": "Can change milestone relationship type", "content_type": 214}, "model": "auth.permission", "pk": 645}, {"fields": {"codename": "delete_milestonerelationshiptype", "name": "Can delete milestone relationship type", "content_type": 214}, "model": "auth.permission", "pk": 646}, {"fields": {"codename": "add_coursemilestone", "name": "Can add course milestone", "content_type": 215}, "model": "auth.permission", "pk": 647}, {"fields": {"codename": "change_coursemilestone", "name": "Can change course milestone", "content_type": 215}, "model": "auth.permission", "pk": 648}, {"fields": {"codename": "delete_coursemilestone", "name": "Can delete course milestone", "content_type": 215}, "model": "auth.permission", "pk": 649}, {"fields": {"codename": "add_coursecontentmilestone", "name": "Can add course content milestone", "content_type": 216}, "model": "auth.permission", "pk": 650}, {"fields": {"codename": "change_coursecontentmilestone", "name": "Can change course content milestone", "content_type": 216}, "model": "auth.permission", "pk": 651}, {"fields": {"codename": "delete_coursecontentmilestone", "name": "Can delete course content milestone", "content_type": 216}, "model": "auth.permission", "pk": 652}, {"fields": {"codename": "add_usermilestone", "name": "Can add user milestone", "content_type": 217}, "model": "auth.permission", "pk": 653}, {"fields": {"codename": "change_usermilestone", "name": "Can change user milestone", "content_type": 217}, "model": "auth.permission", "pk": 654}, {"fields": {"codename": "delete_usermilestone", "name": "Can delete user milestone", "content_type": 217}, "model": "auth.permission", "pk": 655}, {"fields": {"codename": "add_proctoredexam", "name": "Can add proctored exam", "content_type": 218}, "model": "auth.permission", "pk": 656}, {"fields": {"codename": "change_proctoredexam", "name": "Can change proctored exam", "content_type": 218}, "model": "auth.permission", "pk": 657}, {"fields": {"codename": "delete_proctoredexam", "name": "Can delete proctored exam", "content_type": 218}, "model": "auth.permission", "pk": 658}, {"fields": {"codename": "add_proctoredexamreviewpolicy", "name": "Can add Proctored exam review policy", "content_type": 219}, "model": "auth.permission", "pk": 659}, {"fields": {"codename": "change_proctoredexamreviewpolicy", "name": "Can change Proctored exam review policy", "content_type": 219}, "model": "auth.permission", "pk": 660}, {"fields": {"codename": "delete_proctoredexamreviewpolicy", "name": "Can delete Proctored exam review policy", "content_type": 219}, "model": "auth.permission", "pk": 661}, {"fields": {"codename": "add_proctoredexamreviewpolicyhistory", "name": "Can add proctored exam review policy history", "content_type": 220}, "model": "auth.permission", "pk": 662}, {"fields": {"codename": "change_proctoredexamreviewpolicyhistory", "name": "Can change proctored exam review policy history", "content_type": 220}, "model": "auth.permission", "pk": 663}, {"fields": {"codename": "delete_proctoredexamreviewpolicyhistory", "name": "Can delete proctored exam review policy history", "content_type": 220}, "model": "auth.permission", "pk": 664}, {"fields": {"codename": "add_proctoredexamstudentattempt", "name": "Can add proctored exam attempt", "content_type": 221}, "model": "auth.permission", "pk": 665}, {"fields": {"codename": "change_proctoredexamstudentattempt", "name": "Can change proctored exam attempt", "content_type": 221}, "model": "auth.permission", "pk": 666}, {"fields": {"codename": "delete_proctoredexamstudentattempt", "name": "Can delete proctored exam attempt", "content_type": 221}, "model": "auth.permission", "pk": 667}, {"fields": {"codename": "add_proctoredexamstudentattempthistory", "name": "Can add proctored exam attempt history", "content_type": 222}, "model": "auth.permission", "pk": 668}, {"fields": {"codename": "change_proctoredexamstudentattempthistory", "name": "Can change proctored exam attempt history", "content_type": 222}, "model": "auth.permission", "pk": 669}, {"fields": {"codename": "delete_proctoredexamstudentattempthistory", "name": "Can delete proctored exam attempt history", "content_type": 222}, "model": "auth.permission", "pk": 670}, {"fields": {"codename": "add_proctoredexamstudentallowance", "name": "Can add proctored allowance", "content_type": 223}, "model": "auth.permission", "pk": 671}, {"fields": {"codename": "change_proctoredexamstudentallowance", "name": "Can change proctored allowance", "content_type": 223}, "model": "auth.permission", "pk": 672}, {"fields": {"codename": "delete_proctoredexamstudentallowance", "name": "Can delete proctored allowance", "content_type": 223}, "model": "auth.permission", "pk": 673}, {"fields": {"codename": "add_proctoredexamstudentallowancehistory", "name": "Can add proctored allowance history", "content_type": 224}, "model": "auth.permission", "pk": 674}, {"fields": {"codename": "change_proctoredexamstudentallowancehistory", "name": "Can change proctored allowance history", "content_type": 224}, "model": "auth.permission", "pk": 675}, {"fields": {"codename": "delete_proctoredexamstudentallowancehistory", "name": "Can delete proctored allowance history", "content_type": 224}, "model": "auth.permission", "pk": 676}, {"fields": {"codename": "add_proctoredexamsoftwaresecurereview", "name": "Can add Proctored exam software secure review", "content_type": 225}, "model": "auth.permission", "pk": 677}, {"fields": {"codename": "change_proctoredexamsoftwaresecurereview", "name": "Can change Proctored exam software secure review", "content_type": 225}, "model": "auth.permission", "pk": 678}, {"fields": {"codename": "delete_proctoredexamsoftwaresecurereview", "name": "Can delete Proctored exam software secure review", "content_type": 225}, "model": "auth.permission", "pk": 679}, {"fields": {"codename": "add_proctoredexamsoftwaresecurereviewhistory", "name": "Can add Proctored exam review archive", "content_type": 226}, "model": "auth.permission", "pk": 680}, {"fields": {"codename": "change_proctoredexamsoftwaresecurereviewhistory", "name": "Can change Proctored exam review archive", "content_type": 226}, "model": "auth.permission", "pk": 681}, {"fields": {"codename": "delete_proctoredexamsoftwaresecurereviewhistory", "name": "Can delete Proctored exam review archive", "content_type": 226}, "model": "auth.permission", "pk": 682}, {"fields": {"codename": "add_proctoredexamsoftwaresecurecomment", "name": "Can add proctored exam software secure comment", "content_type": 227}, "model": "auth.permission", "pk": 683}, {"fields": {"codename": "change_proctoredexamsoftwaresecurecomment", "name": "Can change proctored exam software secure comment", "content_type": 227}, "model": "auth.permission", "pk": 684}, {"fields": {"codename": "delete_proctoredexamsoftwaresecurecomment", "name": "Can delete proctored exam software secure comment", "content_type": 227}, "model": "auth.permission", "pk": 685}, {"fields": {"codename": "add_organization", "name": "Can add organization", "content_type": 228}, "model": "auth.permission", "pk": 686}, {"fields": {"codename": "change_organization", "name": "Can change organization", "content_type": 228}, "model": "auth.permission", "pk": 687}, {"fields": {"codename": "delete_organization", "name": "Can delete organization", "content_type": 228}, "model": "auth.permission", "pk": 688}, {"fields": {"codename": "add_organizationcourse", "name": "Can add Link Course", "content_type": 229}, "model": "auth.permission", "pk": 689}, {"fields": {"codename": "change_organizationcourse", "name": "Can change Link Course", "content_type": 229}, "model": "auth.permission", "pk": 690}, {"fields": {"codename": "delete_organizationcourse", "name": "Can delete Link Course", "content_type": 229}, "model": "auth.permission", "pk": 691}, {"fields": {"codename": "add_videouploadconfig", "name": "Can add video upload config", "content_type": 230}, "model": "auth.permission", "pk": 692}, {"fields": {"codename": "change_videouploadconfig", "name": "Can change video upload config", "content_type": 230}, "model": "auth.permission", "pk": 693}, {"fields": {"codename": "delete_videouploadconfig", "name": "Can delete video upload config", "content_type": 230}, "model": "auth.permission", "pk": 694}, {"fields": {"codename": "add_pushnotificationconfig", "name": "Can add push notification config", "content_type": 231}, "model": "auth.permission", "pk": 695}, {"fields": {"codename": "change_pushnotificationconfig", "name": "Can change push notification config", "content_type": 231}, "model": "auth.permission", "pk": 696}, {"fields": {"codename": "delete_pushnotificationconfig", "name": "Can delete push notification config", "content_type": 231}, "model": "auth.permission", "pk": 697}, {"fields": {"codename": "add_coursecreator", "name": "Can add course creator", "content_type": 232}, "model": "auth.permission", "pk": 698}, {"fields": {"codename": "change_coursecreator", "name": "Can change course creator", "content_type": 232}, "model": "auth.permission", "pk": 699}, {"fields": {"codename": "delete_coursecreator", "name": "Can delete course creator", "content_type": 232}, "model": "auth.permission", "pk": 700}, {"fields": {"codename": "add_studioconfig", "name": "Can add studio config", "content_type": 233}, "model": "auth.permission", "pk": 701}, {"fields": {"codename": "change_studioconfig", "name": "Can change studio config", "content_type": 233}, "model": "auth.permission", "pk": 702}, {"fields": {"codename": "delete_studioconfig", "name": "Can delete studio config", "content_type": 233}, "model": "auth.permission", "pk": 703}, {"fields": {"username": "ecommerce_worker", "first_name": "", "last_name": "", "is_active": true, "is_superuser": false, "is_staff": false, "last_login": null, "groups": [], "user_permissions": [], "password": "!0m5sUKBMVXqMUTBYafhaZdGTCm3zKrBFjYVvTTag", "email": "ecommerce_worker@fake.email", "date_joined": "2015-11-18T15:37:13.234Z"}, "model": "auth.user", "pk": 1}, {"fields": {"change_date": "2015-11-18T15:38:43.819Z", "changed_by": null, "enabled": true}, "model": "util.ratelimitconfiguration", "pk": 1}, {"fields": {"change_date": "2015-11-18T15:37:12.737Z", "changed_by": null, "configuration": "{\"default\": {\"accomplishment_class_append\": \"accomplishment-certificate\", \"platform_name\": \"Your Platform Name Here\", \"logo_src\": \"/static/certificates/images/logo.png\", \"logo_url\": \"http://www.example.com\", \"company_verified_certificate_url\": \"http://www.example.com/verified-certificate\", \"company_privacy_url\": \"http://www.example.com/privacy-policy\", \"company_tos_url\": \"http://www.example.com/terms-service\", \"company_about_url\": \"http://www.example.com/about-us\"}, \"verified\": {\"certificate_type\": \"Verified\", \"certificate_title\": \"Verified Certificate of Achievement\"}, \"honor\": {\"certificate_type\": \"Honor Code\", \"certificate_title\": \"Certificate of Achievement\"}}", "enabled": false}, "model": "certificates.certificatehtmlviewconfiguration", "pk": 1}, {"fields": {"change_date": "2015-11-18T15:37:21.957Z", "changed_by": null, "enabled": true, "released_languages": ""}, "model": "dark_lang.darklangconfig", "pk": 1}] \ No newline at end of file +[{"fields": {"model": "permission", "app_label": "auth"}, "model": "contenttypes.contenttype", "pk": 1}, {"fields": {"model": "group", "app_label": "auth"}, "model": "contenttypes.contenttype", "pk": 2}, {"fields": {"model": "user", "app_label": "auth"}, "model": "contenttypes.contenttype", "pk": 3}, {"fields": {"model": "contenttype", "app_label": "contenttypes"}, "model": "contenttypes.contenttype", "pk": 4}, {"fields": {"model": "session", "app_label": "sessions"}, "model": "contenttypes.contenttype", "pk": 5}, {"fields": {"model": "site", "app_label": "sites"}, "model": "contenttypes.contenttype", "pk": 6}, {"fields": {"model": "taskmeta", "app_label": "djcelery"}, "model": "contenttypes.contenttype", "pk": 7}, {"fields": {"model": "tasksetmeta", "app_label": "djcelery"}, "model": "contenttypes.contenttype", "pk": 8}, {"fields": {"model": "intervalschedule", "app_label": "djcelery"}, "model": "contenttypes.contenttype", "pk": 9}, {"fields": {"model": "crontabschedule", "app_label": "djcelery"}, "model": "contenttypes.contenttype", "pk": 10}, {"fields": {"model": "periodictasks", "app_label": "djcelery"}, "model": "contenttypes.contenttype", "pk": 11}, {"fields": {"model": "periodictask", "app_label": "djcelery"}, "model": "contenttypes.contenttype", "pk": 12}, {"fields": {"model": "workerstate", "app_label": "djcelery"}, "model": "contenttypes.contenttype", "pk": 13}, {"fields": {"model": "taskstate", "app_label": "djcelery"}, "model": "contenttypes.contenttype", "pk": 14}, {"fields": {"model": "globalstatusmessage", "app_label": "status"}, "model": "contenttypes.contenttype", "pk": 15}, {"fields": {"model": "coursemessage", "app_label": "status"}, "model": "contenttypes.contenttype", "pk": 16}, {"fields": {"model": "studentmodule", "app_label": "courseware"}, "model": "contenttypes.contenttype", "pk": 17}, {"fields": {"model": "studentmodulehistory", "app_label": "courseware"}, "model": "contenttypes.contenttype", "pk": 18}, {"fields": {"model": "xmoduleuserstatesummaryfield", "app_label": "courseware"}, "model": "contenttypes.contenttype", "pk": 19}, {"fields": {"model": "xmodulestudentprefsfield", "app_label": "courseware"}, "model": "contenttypes.contenttype", "pk": 20}, {"fields": {"model": "xmodulestudentinfofield", "app_label": "courseware"}, "model": "contenttypes.contenttype", "pk": 21}, {"fields": {"model": "offlinecomputedgrade", "app_label": "courseware"}, "model": "contenttypes.contenttype", "pk": 22}, {"fields": {"model": "offlinecomputedgradelog", "app_label": "courseware"}, "model": "contenttypes.contenttype", "pk": 23}, {"fields": {"model": "studentfieldoverride", "app_label": "courseware"}, "model": "contenttypes.contenttype", "pk": 24}, {"fields": {"model": "anonymoususerid", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 25}, {"fields": {"model": "userstanding", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 26}, {"fields": {"model": "userprofile", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 27}, {"fields": {"model": "usersignupsource", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 28}, {"fields": {"model": "usertestgroup", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 29}, {"fields": {"model": "registration", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 30}, {"fields": {"model": "pendingnamechange", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 31}, {"fields": {"model": "pendingemailchange", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 32}, {"fields": {"model": "passwordhistory", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 33}, {"fields": {"model": "loginfailures", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 34}, {"fields": {"model": "historicalcourseenrollment", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 35}, {"fields": {"model": "courseenrollment", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 36}, {"fields": {"model": "manualenrollmentaudit", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 37}, {"fields": {"model": "courseenrollmentallowed", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 38}, {"fields": {"model": "courseaccessrole", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 39}, {"fields": {"model": "dashboardconfiguration", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 40}, {"fields": {"model": "linkedinaddtoprofileconfiguration", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 41}, {"fields": {"model": "entranceexamconfiguration", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 42}, {"fields": {"model": "languageproficiency", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 43}, {"fields": {"model": "courseenrollmentattribute", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 44}, {"fields": {"model": "enrollmentrefundconfiguration", "app_label": "student"}, "model": "contenttypes.contenttype", "pk": 45}, {"fields": {"model": "trackinglog", "app_label": "track"}, "model": "contenttypes.contenttype", "pk": 46}, {"fields": {"model": "ratelimitconfiguration", "app_label": "util"}, "model": "contenttypes.contenttype", "pk": 47}, {"fields": {"model": "certificatewhitelist", "app_label": "certificates"}, "model": "contenttypes.contenttype", "pk": 48}, {"fields": {"model": "generatedcertificate", "app_label": "certificates"}, "model": "contenttypes.contenttype", "pk": 49}, {"fields": {"model": "examplecertificateset", "app_label": "certificates"}, "model": "contenttypes.contenttype", "pk": 50}, {"fields": {"model": "examplecertificate", "app_label": "certificates"}, "model": "contenttypes.contenttype", "pk": 51}, {"fields": {"model": "certificategenerationcoursesetting", "app_label": "certificates"}, "model": "contenttypes.contenttype", "pk": 52}, {"fields": {"model": "certificategenerationconfiguration", "app_label": "certificates"}, "model": "contenttypes.contenttype", "pk": 53}, {"fields": {"model": "certificatehtmlviewconfiguration", "app_label": "certificates"}, "model": "contenttypes.contenttype", "pk": 54}, {"fields": {"model": "certificatetemplate", "app_label": "certificates"}, "model": "contenttypes.contenttype", "pk": 55}, {"fields": {"model": "certificatetemplateasset", "app_label": "certificates"}, "model": "contenttypes.contenttype", "pk": 56}, {"fields": {"model": "instructortask", "app_label": "instructor_task"}, "model": "contenttypes.contenttype", "pk": 57}, {"fields": {"model": "psychometricdata", "app_label": "psychometrics"}, "model": "contenttypes.contenttype", "pk": 58}, {"fields": {"model": "coursesoftware", "app_label": "licenses"}, "model": "contenttypes.contenttype", "pk": 59}, {"fields": {"model": "userlicense", "app_label": "licenses"}, "model": "contenttypes.contenttype", "pk": 60}, {"fields": {"model": "courseusergroup", "app_label": "course_groups"}, "model": "contenttypes.contenttype", "pk": 61}, {"fields": {"model": "cohortmembership", "app_label": "course_groups"}, "model": "contenttypes.contenttype", "pk": 62}, {"fields": {"model": "courseusergrouppartitiongroup", "app_label": "course_groups"}, "model": "contenttypes.contenttype", "pk": 63}, {"fields": {"model": "coursecohortssettings", "app_label": "course_groups"}, "model": "contenttypes.contenttype", "pk": 64}, {"fields": {"model": "coursecohort", "app_label": "course_groups"}, "model": "contenttypes.contenttype", "pk": 65}, {"fields": {"model": "courseemail", "app_label": "bulk_email"}, "model": "contenttypes.contenttype", "pk": 66}, {"fields": {"model": "optout", "app_label": "bulk_email"}, "model": "contenttypes.contenttype", "pk": 67}, {"fields": {"model": "courseemailtemplate", "app_label": "bulk_email"}, "model": "contenttypes.contenttype", "pk": 68}, {"fields": {"model": "courseauthorization", "app_label": "bulk_email"}, "model": "contenttypes.contenttype", "pk": 69}, {"fields": {"model": "brandinginfoconfig", "app_label": "branding"}, "model": "contenttypes.contenttype", "pk": 70}, {"fields": {"model": "brandingapiconfig", "app_label": "branding"}, "model": "contenttypes.contenttype", "pk": 71}, {"fields": {"model": "externalauthmap", "app_label": "external_auth"}, "model": "contenttypes.contenttype", "pk": 72}, {"fields": {"model": "nonce", "app_label": "django_openid_auth"}, "model": "contenttypes.contenttype", "pk": 73}, {"fields": {"model": "association", "app_label": "django_openid_auth"}, "model": "contenttypes.contenttype", "pk": 74}, {"fields": {"model": "useropenid", "app_label": "django_openid_auth"}, "model": "contenttypes.contenttype", "pk": 75}, {"fields": {"model": "client", "app_label": "oauth2"}, "model": "contenttypes.contenttype", "pk": 76}, {"fields": {"model": "grant", "app_label": "oauth2"}, "model": "contenttypes.contenttype", "pk": 77}, {"fields": {"model": "accesstoken", "app_label": "oauth2"}, "model": "contenttypes.contenttype", "pk": 78}, {"fields": {"model": "refreshtoken", "app_label": "oauth2"}, "model": "contenttypes.contenttype", "pk": 79}, {"fields": {"model": "trustedclient", "app_label": "oauth2_provider"}, "model": "contenttypes.contenttype", "pk": 80}, {"fields": {"model": "oauth2providerconfig", "app_label": "third_party_auth"}, "model": "contenttypes.contenttype", "pk": 81}, {"fields": {"model": "samlproviderconfig", "app_label": "third_party_auth"}, "model": "contenttypes.contenttype", "pk": 82}, {"fields": {"model": "samlconfiguration", "app_label": "third_party_auth"}, "model": "contenttypes.contenttype", "pk": 83}, {"fields": {"model": "samlproviderdata", "app_label": "third_party_auth"}, "model": "contenttypes.contenttype", "pk": 84}, {"fields": {"model": "ltiproviderconfig", "app_label": "third_party_auth"}, "model": "contenttypes.contenttype", "pk": 85}, {"fields": {"model": "providerapipermissions", "app_label": "third_party_auth"}, "model": "contenttypes.contenttype", "pk": 86}, {"fields": {"model": "nonce", "app_label": "oauth_provider"}, "model": "contenttypes.contenttype", "pk": 87}, {"fields": {"model": "scope", "app_label": "oauth_provider"}, "model": "contenttypes.contenttype", "pk": 88}, {"fields": {"model": "consumer", "app_label": "oauth_provider"}, "model": "contenttypes.contenttype", "pk": 89}, {"fields": {"model": "token", "app_label": "oauth_provider"}, "model": "contenttypes.contenttype", "pk": 90}, {"fields": {"model": "resource", "app_label": "oauth_provider"}, "model": "contenttypes.contenttype", "pk": 91}, {"fields": {"model": "article", "app_label": "wiki"}, "model": "contenttypes.contenttype", "pk": 92}, {"fields": {"model": "articleforobject", "app_label": "wiki"}, "model": "contenttypes.contenttype", "pk": 93}, {"fields": {"model": "articlerevision", "app_label": "wiki"}, "model": "contenttypes.contenttype", "pk": 94}, {"fields": {"model": "urlpath", "app_label": "wiki"}, "model": "contenttypes.contenttype", "pk": 95}, {"fields": {"model": "articleplugin", "app_label": "wiki"}, "model": "contenttypes.contenttype", "pk": 96}, {"fields": {"model": "reusableplugin", "app_label": "wiki"}, "model": "contenttypes.contenttype", "pk": 97}, {"fields": {"model": "simpleplugin", "app_label": "wiki"}, "model": "contenttypes.contenttype", "pk": 98}, {"fields": {"model": "revisionplugin", "app_label": "wiki"}, "model": "contenttypes.contenttype", "pk": 99}, {"fields": {"model": "revisionpluginrevision", "app_label": "wiki"}, "model": "contenttypes.contenttype", "pk": 100}, {"fields": {"model": "image", "app_label": "wiki"}, "model": "contenttypes.contenttype", "pk": 101}, {"fields": {"model": "imagerevision", "app_label": "wiki"}, "model": "contenttypes.contenttype", "pk": 102}, {"fields": {"model": "attachment", "app_label": "wiki"}, "model": "contenttypes.contenttype", "pk": 103}, {"fields": {"model": "attachmentrevision", "app_label": "wiki"}, "model": "contenttypes.contenttype", "pk": 104}, {"fields": {"model": "notificationtype", "app_label": "django_notify"}, "model": "contenttypes.contenttype", "pk": 105}, {"fields": {"model": "settings", "app_label": "django_notify"}, "model": "contenttypes.contenttype", "pk": 106}, {"fields": {"model": "subscription", "app_label": "django_notify"}, "model": "contenttypes.contenttype", "pk": 107}, {"fields": {"model": "notification", "app_label": "django_notify"}, "model": "contenttypes.contenttype", "pk": 108}, {"fields": {"model": "score", "app_label": "foldit"}, "model": "contenttypes.contenttype", "pk": 109}, {"fields": {"model": "puzzlecomplete", "app_label": "foldit"}, "model": "contenttypes.contenttype", "pk": 110}, {"fields": {"model": "logentry", "app_label": "admin"}, "model": "contenttypes.contenttype", "pk": 111}, {"fields": {"model": "role", "app_label": "django_comment_common"}, "model": "contenttypes.contenttype", "pk": 112}, {"fields": {"model": "permission", "app_label": "django_comment_common"}, "model": "contenttypes.contenttype", "pk": 113}, {"fields": {"model": "note", "app_label": "notes"}, "model": "contenttypes.contenttype", "pk": 114}, {"fields": {"model": "splashconfig", "app_label": "splash"}, "model": "contenttypes.contenttype", "pk": 115}, {"fields": {"model": "userpreference", "app_label": "user_api"}, "model": "contenttypes.contenttype", "pk": 116}, {"fields": {"model": "usercoursetag", "app_label": "user_api"}, "model": "contenttypes.contenttype", "pk": 117}, {"fields": {"model": "userorgtag", "app_label": "user_api"}, "model": "contenttypes.contenttype", "pk": 118}, {"fields": {"model": "order", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 119}, {"fields": {"model": "orderitem", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 120}, {"fields": {"model": "invoice", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 121}, {"fields": {"model": "invoicetransaction", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 122}, {"fields": {"model": "invoiceitem", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 123}, {"fields": {"model": "courseregistrationcodeinvoiceitem", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 124}, {"fields": {"model": "invoicehistory", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 125}, {"fields": {"model": "courseregistrationcode", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 126}, {"fields": {"model": "registrationcoderedemption", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 127}, {"fields": {"model": "coupon", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 128}, {"fields": {"model": "couponredemption", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 129}, {"fields": {"model": "paidcourseregistration", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 130}, {"fields": {"model": "courseregcodeitem", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 131}, {"fields": {"model": "courseregcodeitemannotation", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 132}, {"fields": {"model": "paidcourseregistrationannotation", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 133}, {"fields": {"model": "certificateitem", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 134}, {"fields": {"model": "donationconfiguration", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 135}, {"fields": {"model": "donation", "app_label": "shoppingcart"}, "model": "contenttypes.contenttype", "pk": 136}, {"fields": {"model": "coursemode", "app_label": "course_modes"}, "model": "contenttypes.contenttype", "pk": 137}, {"fields": {"model": "coursemodesarchive", "app_label": "course_modes"}, "model": "contenttypes.contenttype", "pk": 138}, {"fields": {"model": "softwaresecurephotoverification", "app_label": "verify_student"}, "model": "contenttypes.contenttype", "pk": 139}, {"fields": {"model": "historicalverificationdeadline", "app_label": "verify_student"}, "model": "contenttypes.contenttype", "pk": 140}, {"fields": {"model": "verificationdeadline", "app_label": "verify_student"}, "model": "contenttypes.contenttype", "pk": 141}, {"fields": {"model": "verificationcheckpoint", "app_label": "verify_student"}, "model": "contenttypes.contenttype", "pk": 142}, {"fields": {"model": "verificationstatus", "app_label": "verify_student"}, "model": "contenttypes.contenttype", "pk": 143}, {"fields": {"model": "incoursereverificationconfiguration", "app_label": "verify_student"}, "model": "contenttypes.contenttype", "pk": 144}, {"fields": {"model": "icrvstatusemailsconfiguration", "app_label": "verify_student"}, "model": "contenttypes.contenttype", "pk": 145}, {"fields": {"model": "skippedreverification", "app_label": "verify_student"}, "model": "contenttypes.contenttype", "pk": 146}, {"fields": {"model": "darklangconfig", "app_label": "dark_lang"}, "model": "contenttypes.contenttype", "pk": 147}, {"fields": {"model": "embargoedcourse", "app_label": "embargo"}, "model": "contenttypes.contenttype", "pk": 148}, {"fields": {"model": "embargoedstate", "app_label": "embargo"}, "model": "contenttypes.contenttype", "pk": 149}, {"fields": {"model": "restrictedcourse", "app_label": "embargo"}, "model": "contenttypes.contenttype", "pk": 150}, {"fields": {"model": "country", "app_label": "embargo"}, "model": "contenttypes.contenttype", "pk": 151}, {"fields": {"model": "countryaccessrule", "app_label": "embargo"}, "model": "contenttypes.contenttype", "pk": 152}, {"fields": {"model": "courseaccessrulehistory", "app_label": "embargo"}, "model": "contenttypes.contenttype", "pk": 153}, {"fields": {"model": "ipfilter", "app_label": "embargo"}, "model": "contenttypes.contenttype", "pk": 154}, {"fields": {"model": "coursererunstate", "app_label": "course_action_state"}, "model": "contenttypes.contenttype", "pk": 155}, {"fields": {"model": "mobileapiconfig", "app_label": "mobile_api"}, "model": "contenttypes.contenttype", "pk": 156}, {"fields": {"model": "usersocialauth", "app_label": "default"}, "model": "contenttypes.contenttype", "pk": 157}, {"fields": {"model": "nonce", "app_label": "default"}, "model": "contenttypes.contenttype", "pk": 158}, {"fields": {"model": "association", "app_label": "default"}, "model": "contenttypes.contenttype", "pk": 159}, {"fields": {"model": "code", "app_label": "default"}, "model": "contenttypes.contenttype", "pk": 160}, {"fields": {"model": "surveyform", "app_label": "survey"}, "model": "contenttypes.contenttype", "pk": 161}, {"fields": {"model": "surveyanswer", "app_label": "survey"}, "model": "contenttypes.contenttype", "pk": 162}, {"fields": {"model": "xblockasidesconfig", "app_label": "lms_xblock"}, "model": "contenttypes.contenttype", "pk": 163}, {"fields": {"model": "courseoverview", "app_label": "course_overviews"}, "model": "contenttypes.contenttype", "pk": 164}, {"fields": {"model": "courseoverviewtab", "app_label": "course_overviews"}, "model": "contenttypes.contenttype", "pk": 165}, {"fields": {"model": "coursestructure", "app_label": "course_structures"}, "model": "contenttypes.contenttype", "pk": 166}, {"fields": {"model": "corsmodel", "app_label": "corsheaders"}, "model": "contenttypes.contenttype", "pk": 167}, {"fields": {"model": "xdomainproxyconfiguration", "app_label": "cors_csrf"}, "model": "contenttypes.contenttype", "pk": 168}, {"fields": {"model": "creditprovider", "app_label": "credit"}, "model": "contenttypes.contenttype", "pk": 169}, {"fields": {"model": "creditcourse", "app_label": "credit"}, "model": "contenttypes.contenttype", "pk": 170}, {"fields": {"model": "creditrequirement", "app_label": "credit"}, "model": "contenttypes.contenttype", "pk": 171}, {"fields": {"model": "historicalcreditrequirementstatus", "app_label": "credit"}, "model": "contenttypes.contenttype", "pk": 172}, {"fields": {"model": "creditrequirementstatus", "app_label": "credit"}, "model": "contenttypes.contenttype", "pk": 173}, {"fields": {"model": "crediteligibility", "app_label": "credit"}, "model": "contenttypes.contenttype", "pk": 174}, {"fields": {"model": "historicalcreditrequest", "app_label": "credit"}, "model": "contenttypes.contenttype", "pk": 175}, {"fields": {"model": "creditrequest", "app_label": "credit"}, "model": "contenttypes.contenttype", "pk": 176}, {"fields": {"model": "courseteam", "app_label": "teams"}, "model": "contenttypes.contenttype", "pk": 177}, {"fields": {"model": "courseteammembership", "app_label": "teams"}, "model": "contenttypes.contenttype", "pk": 178}, {"fields": {"model": "xblockdisableconfig", "app_label": "xblock_django"}, "model": "contenttypes.contenttype", "pk": 179}, {"fields": {"model": "programsapiconfig", "app_label": "programs"}, "model": "contenttypes.contenttype", "pk": 180}, {"fields": {"model": "selfpacedconfiguration", "app_label": "self_paced"}, "model": "contenttypes.contenttype", "pk": 181}, {"fields": {"model": "kvstore", "app_label": "thumbnail"}, "model": "contenttypes.contenttype", "pk": 182}, {"fields": {"model": "badgeclass", "app_label": "badges"}, "model": "contenttypes.contenttype", "pk": 183}, {"fields": {"model": "badgeassertion", "app_label": "badges"}, "model": "contenttypes.contenttype", "pk": 184}, {"fields": {"model": "coursecompleteimageconfiguration", "app_label": "badges"}, "model": "contenttypes.contenttype", "pk": 185}, {"fields": {"model": "studentitem", "app_label": "submissions"}, "model": "contenttypes.contenttype", "pk": 186}, {"fields": {"model": "submission", "app_label": "submissions"}, "model": "contenttypes.contenttype", "pk": 187}, {"fields": {"model": "score", "app_label": "submissions"}, "model": "contenttypes.contenttype", "pk": 188}, {"fields": {"model": "scoresummary", "app_label": "submissions"}, "model": "contenttypes.contenttype", "pk": 189}, {"fields": {"model": "rubric", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 190}, {"fields": {"model": "criterion", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 191}, {"fields": {"model": "criterionoption", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 192}, {"fields": {"model": "assessment", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 193}, {"fields": {"model": "assessmentpart", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 194}, {"fields": {"model": "assessmentfeedbackoption", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 195}, {"fields": {"model": "assessmentfeedback", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 196}, {"fields": {"model": "peerworkflow", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 197}, {"fields": {"model": "peerworkflowitem", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 198}, {"fields": {"model": "trainingexample", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 199}, {"fields": {"model": "studenttrainingworkflow", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 200}, {"fields": {"model": "studenttrainingworkflowitem", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 201}, {"fields": {"model": "aiclassifierset", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 202}, {"fields": {"model": "aiclassifier", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 203}, {"fields": {"model": "aitrainingworkflow", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 204}, {"fields": {"model": "aigradingworkflow", "app_label": "assessment"}, "model": "contenttypes.contenttype", "pk": 205}, {"fields": {"model": "assessmentworkflow", "app_label": "workflow"}, "model": "contenttypes.contenttype", "pk": 206}, {"fields": {"model": "assessmentworkflowstep", "app_label": "workflow"}, "model": "contenttypes.contenttype", "pk": 207}, {"fields": {"model": "assessmentworkflowcancellation", "app_label": "workflow"}, "model": "contenttypes.contenttype", "pk": 208}, {"fields": {"model": "profile", "app_label": "edxval"}, "model": "contenttypes.contenttype", "pk": 209}, {"fields": {"model": "video", "app_label": "edxval"}, "model": "contenttypes.contenttype", "pk": 210}, {"fields": {"model": "coursevideo", "app_label": "edxval"}, "model": "contenttypes.contenttype", "pk": 211}, {"fields": {"model": "encodedvideo", "app_label": "edxval"}, "model": "contenttypes.contenttype", "pk": 212}, {"fields": {"model": "subtitle", "app_label": "edxval"}, "model": "contenttypes.contenttype", "pk": 213}, {"fields": {"model": "milestone", "app_label": "milestones"}, "model": "contenttypes.contenttype", "pk": 214}, {"fields": {"model": "milestonerelationshiptype", "app_label": "milestones"}, "model": "contenttypes.contenttype", "pk": 215}, {"fields": {"model": "coursemilestone", "app_label": "milestones"}, "model": "contenttypes.contenttype", "pk": 216}, {"fields": {"model": "coursecontentmilestone", "app_label": "milestones"}, "model": "contenttypes.contenttype", "pk": 217}, {"fields": {"model": "usermilestone", "app_label": "milestones"}, "model": "contenttypes.contenttype", "pk": 218}, {"fields": {"model": "proctoredexam", "app_label": "edx_proctoring"}, "model": "contenttypes.contenttype", "pk": 219}, {"fields": {"model": "proctoredexamreviewpolicy", "app_label": "edx_proctoring"}, "model": "contenttypes.contenttype", "pk": 220}, {"fields": {"model": "proctoredexamreviewpolicyhistory", "app_label": "edx_proctoring"}, "model": "contenttypes.contenttype", "pk": 221}, {"fields": {"model": "proctoredexamstudentattempt", "app_label": "edx_proctoring"}, "model": "contenttypes.contenttype", "pk": 222}, {"fields": {"model": "proctoredexamstudentattempthistory", "app_label": "edx_proctoring"}, "model": "contenttypes.contenttype", "pk": 223}, {"fields": {"model": "proctoredexamstudentallowance", "app_label": "edx_proctoring"}, "model": "contenttypes.contenttype", "pk": 224}, {"fields": {"model": "proctoredexamstudentallowancehistory", "app_label": "edx_proctoring"}, "model": "contenttypes.contenttype", "pk": 225}, {"fields": {"model": "proctoredexamsoftwaresecurereview", "app_label": "edx_proctoring"}, "model": "contenttypes.contenttype", "pk": 226}, {"fields": {"model": "proctoredexamsoftwaresecurereviewhistory", "app_label": "edx_proctoring"}, "model": "contenttypes.contenttype", "pk": 227}, {"fields": {"model": "proctoredexamsoftwaresecurecomment", "app_label": "edx_proctoring"}, "model": "contenttypes.contenttype", "pk": 228}, {"fields": {"model": "organization", "app_label": "organizations"}, "model": "contenttypes.contenttype", "pk": 229}, {"fields": {"model": "organizationcourse", "app_label": "organizations"}, "model": "contenttypes.contenttype", "pk": 230}, {"fields": {"domain": "example.com", "name": "example.com"}, "model": "sites.site", "pk": 1}, {"fields": {"plain_template": "{course_title}\n\n{{message_body}}\r\n----\r\nCopyright 2013 edX, All rights reserved.\r\n----\r\nConnect with edX:\r\nFacebook (http://facebook.com/edxonline)\r\nTwitter (http://twitter.com/edxonline)\r\nGoogle+ (https://plus.google.com/108235383044095082735)\r\nMeetup (http://www.meetup.com/edX-Communities/)\r\n----\r\nThis email was automatically sent from {platform_name}.\r\nYou are receiving this email at address {email} because you are enrolled in {course_title}\r\n(URL: {course_url} ).\r\nTo stop receiving email like this, update your course email settings at {email_settings_url}.\r\n", "html_template": " Update from {course_title}

edX
Connect with edX:        

{course_title}


{{message_body}}
       
Copyright \u00a9 2013 edX, All rights reserved.


Our mailing address is:
edX
11 Cambridge Center, Suite 101
Cambridge, MA, USA 02142


This email was automatically sent from {platform_name}.
You are receiving this email at address {email} because you are enrolled in {course_title}.
To stop receiving email like this, update your course email settings here.
", "name": null}, "model": "bulk_email.courseemailtemplate", "pk": 1}, {"fields": {"plain_template": "THIS IS A BRANDED TEXT TEMPLATE. {course_title}\n\n{{message_body}}\r\n----\r\nCopyright 2013 edX, All rights reserved.\r\n----\r\nConnect with edX:\r\nFacebook (http://facebook.com/edxonline)\r\nTwitter (http://twitter.com/edxonline)\r\nGoogle+ (https://plus.google.com/108235383044095082735)\r\nMeetup (http://www.meetup.com/edX-Communities/)\r\n----\r\nThis email was automatically sent from {platform_name}.\r\nYou are receiving this email at address {email} because you are enrolled in {course_title}\r\n(URL: {course_url} ).\r\nTo stop receiving email like this, update your course email settings at {email_settings_url}.\r\n", "html_template": " THIS IS A BRANDED HTML TEMPLATE Update from {course_title}

edX
Connect with edX:        

{course_title}


{{message_body}}
       
Copyright \u00a9 2013 edX, All rights reserved.


Our mailing address is:
edX
11 Cambridge Center, Suite 101
Cambridge, MA, USA 02142


This email was automatically sent from {platform_name}.
You are receiving this email at address {email} because you are enrolled in {course_title}.
To stop receiving email like this, update your course email settings here.
", "name": "branded.template"}, "model": "bulk_email.courseemailtemplate", "pk": 2}, {"fields": {"country": "AF"}, "model": "embargo.country", "pk": 1}, {"fields": {"country": "AX"}, "model": "embargo.country", "pk": 2}, {"fields": {"country": "AL"}, "model": "embargo.country", "pk": 3}, {"fields": {"country": "DZ"}, "model": "embargo.country", "pk": 4}, {"fields": {"country": "AS"}, "model": "embargo.country", "pk": 5}, {"fields": {"country": "AD"}, "model": "embargo.country", "pk": 6}, {"fields": {"country": "AO"}, "model": "embargo.country", "pk": 7}, {"fields": {"country": "AI"}, "model": "embargo.country", "pk": 8}, {"fields": {"country": "AQ"}, "model": "embargo.country", "pk": 9}, {"fields": {"country": "AG"}, "model": "embargo.country", "pk": 10}, {"fields": {"country": "AR"}, "model": "embargo.country", "pk": 11}, {"fields": {"country": "AM"}, "model": "embargo.country", "pk": 12}, {"fields": {"country": "AW"}, "model": "embargo.country", "pk": 13}, {"fields": {"country": "AU"}, "model": "embargo.country", "pk": 14}, {"fields": {"country": "AT"}, "model": "embargo.country", "pk": 15}, {"fields": {"country": "AZ"}, "model": "embargo.country", "pk": 16}, {"fields": {"country": "BS"}, "model": "embargo.country", "pk": 17}, {"fields": {"country": "BH"}, "model": "embargo.country", "pk": 18}, {"fields": {"country": "BD"}, "model": "embargo.country", "pk": 19}, {"fields": {"country": "BB"}, "model": "embargo.country", "pk": 20}, {"fields": {"country": "BY"}, "model": "embargo.country", "pk": 21}, {"fields": {"country": "BE"}, "model": "embargo.country", "pk": 22}, {"fields": {"country": "BZ"}, "model": "embargo.country", "pk": 23}, {"fields": {"country": "BJ"}, "model": "embargo.country", "pk": 24}, {"fields": {"country": "BM"}, "model": "embargo.country", "pk": 25}, {"fields": {"country": "BT"}, "model": "embargo.country", "pk": 26}, {"fields": {"country": "BO"}, "model": "embargo.country", "pk": 27}, {"fields": {"country": "BQ"}, "model": "embargo.country", "pk": 28}, {"fields": {"country": "BA"}, "model": "embargo.country", "pk": 29}, {"fields": {"country": "BW"}, "model": "embargo.country", "pk": 30}, {"fields": {"country": "BV"}, "model": "embargo.country", "pk": 31}, {"fields": {"country": "BR"}, "model": "embargo.country", "pk": 32}, {"fields": {"country": "IO"}, "model": "embargo.country", "pk": 33}, {"fields": {"country": "BN"}, "model": "embargo.country", "pk": 34}, {"fields": {"country": "BG"}, "model": "embargo.country", "pk": 35}, {"fields": {"country": "BF"}, "model": "embargo.country", "pk": 36}, {"fields": {"country": "BI"}, "model": "embargo.country", "pk": 37}, {"fields": {"country": "CV"}, "model": "embargo.country", "pk": 38}, {"fields": {"country": "KH"}, "model": "embargo.country", "pk": 39}, {"fields": {"country": "CM"}, "model": "embargo.country", "pk": 40}, {"fields": {"country": "CA"}, "model": "embargo.country", "pk": 41}, {"fields": {"country": "KY"}, "model": "embargo.country", "pk": 42}, {"fields": {"country": "CF"}, "model": "embargo.country", "pk": 43}, {"fields": {"country": "TD"}, "model": "embargo.country", "pk": 44}, {"fields": {"country": "CL"}, "model": "embargo.country", "pk": 45}, {"fields": {"country": "CN"}, "model": "embargo.country", "pk": 46}, {"fields": {"country": "CX"}, "model": "embargo.country", "pk": 47}, {"fields": {"country": "CC"}, "model": "embargo.country", "pk": 48}, {"fields": {"country": "CO"}, "model": "embargo.country", "pk": 49}, {"fields": {"country": "KM"}, "model": "embargo.country", "pk": 50}, {"fields": {"country": "CG"}, "model": "embargo.country", "pk": 51}, {"fields": {"country": "CD"}, "model": "embargo.country", "pk": 52}, {"fields": {"country": "CK"}, "model": "embargo.country", "pk": 53}, {"fields": {"country": "CR"}, "model": "embargo.country", "pk": 54}, {"fields": {"country": "CI"}, "model": "embargo.country", "pk": 55}, {"fields": {"country": "HR"}, "model": "embargo.country", "pk": 56}, {"fields": {"country": "CU"}, "model": "embargo.country", "pk": 57}, {"fields": {"country": "CW"}, "model": "embargo.country", "pk": 58}, {"fields": {"country": "CY"}, "model": "embargo.country", "pk": 59}, {"fields": {"country": "CZ"}, "model": "embargo.country", "pk": 60}, {"fields": {"country": "DK"}, "model": "embargo.country", "pk": 61}, {"fields": {"country": "DJ"}, "model": "embargo.country", "pk": 62}, {"fields": {"country": "DM"}, "model": "embargo.country", "pk": 63}, {"fields": {"country": "DO"}, "model": "embargo.country", "pk": 64}, {"fields": {"country": "EC"}, "model": "embargo.country", "pk": 65}, {"fields": {"country": "EG"}, "model": "embargo.country", "pk": 66}, {"fields": {"country": "SV"}, "model": "embargo.country", "pk": 67}, {"fields": {"country": "GQ"}, "model": "embargo.country", "pk": 68}, {"fields": {"country": "ER"}, "model": "embargo.country", "pk": 69}, {"fields": {"country": "EE"}, "model": "embargo.country", "pk": 70}, {"fields": {"country": "ET"}, "model": "embargo.country", "pk": 71}, {"fields": {"country": "FK"}, "model": "embargo.country", "pk": 72}, {"fields": {"country": "FO"}, "model": "embargo.country", "pk": 73}, {"fields": {"country": "FJ"}, "model": "embargo.country", "pk": 74}, {"fields": {"country": "FI"}, "model": "embargo.country", "pk": 75}, {"fields": {"country": "FR"}, "model": "embargo.country", "pk": 76}, {"fields": {"country": "GF"}, "model": "embargo.country", "pk": 77}, {"fields": {"country": "PF"}, "model": "embargo.country", "pk": 78}, {"fields": {"country": "TF"}, "model": "embargo.country", "pk": 79}, {"fields": {"country": "GA"}, "model": "embargo.country", "pk": 80}, {"fields": {"country": "GM"}, "model": "embargo.country", "pk": 81}, {"fields": {"country": "GE"}, "model": "embargo.country", "pk": 82}, {"fields": {"country": "DE"}, "model": "embargo.country", "pk": 83}, {"fields": {"country": "GH"}, "model": "embargo.country", "pk": 84}, {"fields": {"country": "GI"}, "model": "embargo.country", "pk": 85}, {"fields": {"country": "GR"}, "model": "embargo.country", "pk": 86}, {"fields": {"country": "GL"}, "model": "embargo.country", "pk": 87}, {"fields": {"country": "GD"}, "model": "embargo.country", "pk": 88}, {"fields": {"country": "GP"}, "model": "embargo.country", "pk": 89}, {"fields": {"country": "GU"}, "model": "embargo.country", "pk": 90}, {"fields": {"country": "GT"}, "model": "embargo.country", "pk": 91}, {"fields": {"country": "GG"}, "model": "embargo.country", "pk": 92}, {"fields": {"country": "GN"}, "model": "embargo.country", "pk": 93}, {"fields": {"country": "GW"}, "model": "embargo.country", "pk": 94}, {"fields": {"country": "GY"}, "model": "embargo.country", "pk": 95}, {"fields": {"country": "HT"}, "model": "embargo.country", "pk": 96}, {"fields": {"country": "HM"}, "model": "embargo.country", "pk": 97}, {"fields": {"country": "VA"}, "model": "embargo.country", "pk": 98}, {"fields": {"country": "HN"}, "model": "embargo.country", "pk": 99}, {"fields": {"country": "HK"}, "model": "embargo.country", "pk": 100}, {"fields": {"country": "HU"}, "model": "embargo.country", "pk": 101}, {"fields": {"country": "IS"}, "model": "embargo.country", "pk": 102}, {"fields": {"country": "IN"}, "model": "embargo.country", "pk": 103}, {"fields": {"country": "ID"}, "model": "embargo.country", "pk": 104}, {"fields": {"country": "IR"}, "model": "embargo.country", "pk": 105}, {"fields": {"country": "IQ"}, "model": "embargo.country", "pk": 106}, {"fields": {"country": "IE"}, "model": "embargo.country", "pk": 107}, {"fields": {"country": "IM"}, "model": "embargo.country", "pk": 108}, {"fields": {"country": "IL"}, "model": "embargo.country", "pk": 109}, {"fields": {"country": "IT"}, "model": "embargo.country", "pk": 110}, {"fields": {"country": "JM"}, "model": "embargo.country", "pk": 111}, {"fields": {"country": "JP"}, "model": "embargo.country", "pk": 112}, {"fields": {"country": "JE"}, "model": "embargo.country", "pk": 113}, {"fields": {"country": "JO"}, "model": "embargo.country", "pk": 114}, {"fields": {"country": "KZ"}, "model": "embargo.country", "pk": 115}, {"fields": {"country": "KE"}, "model": "embargo.country", "pk": 116}, {"fields": {"country": "KI"}, "model": "embargo.country", "pk": 117}, {"fields": {"country": "KW"}, "model": "embargo.country", "pk": 118}, {"fields": {"country": "KG"}, "model": "embargo.country", "pk": 119}, {"fields": {"country": "LA"}, "model": "embargo.country", "pk": 120}, {"fields": {"country": "LV"}, "model": "embargo.country", "pk": 121}, {"fields": {"country": "LB"}, "model": "embargo.country", "pk": 122}, {"fields": {"country": "LS"}, "model": "embargo.country", "pk": 123}, {"fields": {"country": "LR"}, "model": "embargo.country", "pk": 124}, {"fields": {"country": "LY"}, "model": "embargo.country", "pk": 125}, {"fields": {"country": "LI"}, "model": "embargo.country", "pk": 126}, {"fields": {"country": "LT"}, "model": "embargo.country", "pk": 127}, {"fields": {"country": "LU"}, "model": "embargo.country", "pk": 128}, {"fields": {"country": "MO"}, "model": "embargo.country", "pk": 129}, {"fields": {"country": "MK"}, "model": "embargo.country", "pk": 130}, {"fields": {"country": "MG"}, "model": "embargo.country", "pk": 131}, {"fields": {"country": "MW"}, "model": "embargo.country", "pk": 132}, {"fields": {"country": "MY"}, "model": "embargo.country", "pk": 133}, {"fields": {"country": "MV"}, "model": "embargo.country", "pk": 134}, {"fields": {"country": "ML"}, "model": "embargo.country", "pk": 135}, {"fields": {"country": "MT"}, "model": "embargo.country", "pk": 136}, {"fields": {"country": "MH"}, "model": "embargo.country", "pk": 137}, {"fields": {"country": "MQ"}, "model": "embargo.country", "pk": 138}, {"fields": {"country": "MR"}, "model": "embargo.country", "pk": 139}, {"fields": {"country": "MU"}, "model": "embargo.country", "pk": 140}, {"fields": {"country": "YT"}, "model": "embargo.country", "pk": 141}, {"fields": {"country": "MX"}, "model": "embargo.country", "pk": 142}, {"fields": {"country": "FM"}, "model": "embargo.country", "pk": 143}, {"fields": {"country": "MD"}, "model": "embargo.country", "pk": 144}, {"fields": {"country": "MC"}, "model": "embargo.country", "pk": 145}, {"fields": {"country": "MN"}, "model": "embargo.country", "pk": 146}, {"fields": {"country": "ME"}, "model": "embargo.country", "pk": 147}, {"fields": {"country": "MS"}, "model": "embargo.country", "pk": 148}, {"fields": {"country": "MA"}, "model": "embargo.country", "pk": 149}, {"fields": {"country": "MZ"}, "model": "embargo.country", "pk": 150}, {"fields": {"country": "MM"}, "model": "embargo.country", "pk": 151}, {"fields": {"country": "NA"}, "model": "embargo.country", "pk": 152}, {"fields": {"country": "NR"}, "model": "embargo.country", "pk": 153}, {"fields": {"country": "NP"}, "model": "embargo.country", "pk": 154}, {"fields": {"country": "NL"}, "model": "embargo.country", "pk": 155}, {"fields": {"country": "NC"}, "model": "embargo.country", "pk": 156}, {"fields": {"country": "NZ"}, "model": "embargo.country", "pk": 157}, {"fields": {"country": "NI"}, "model": "embargo.country", "pk": 158}, {"fields": {"country": "NE"}, "model": "embargo.country", "pk": 159}, {"fields": {"country": "NG"}, "model": "embargo.country", "pk": 160}, {"fields": {"country": "NU"}, "model": "embargo.country", "pk": 161}, {"fields": {"country": "NF"}, "model": "embargo.country", "pk": 162}, {"fields": {"country": "KP"}, "model": "embargo.country", "pk": 163}, {"fields": {"country": "MP"}, "model": "embargo.country", "pk": 164}, {"fields": {"country": "NO"}, "model": "embargo.country", "pk": 165}, {"fields": {"country": "OM"}, "model": "embargo.country", "pk": 166}, {"fields": {"country": "PK"}, "model": "embargo.country", "pk": 167}, {"fields": {"country": "PW"}, "model": "embargo.country", "pk": 168}, {"fields": {"country": "PS"}, "model": "embargo.country", "pk": 169}, {"fields": {"country": "PA"}, "model": "embargo.country", "pk": 170}, {"fields": {"country": "PG"}, "model": "embargo.country", "pk": 171}, {"fields": {"country": "PY"}, "model": "embargo.country", "pk": 172}, {"fields": {"country": "PE"}, "model": "embargo.country", "pk": 173}, {"fields": {"country": "PH"}, "model": "embargo.country", "pk": 174}, {"fields": {"country": "PN"}, "model": "embargo.country", "pk": 175}, {"fields": {"country": "PL"}, "model": "embargo.country", "pk": 176}, {"fields": {"country": "PT"}, "model": "embargo.country", "pk": 177}, {"fields": {"country": "PR"}, "model": "embargo.country", "pk": 178}, {"fields": {"country": "QA"}, "model": "embargo.country", "pk": 179}, {"fields": {"country": "RE"}, "model": "embargo.country", "pk": 180}, {"fields": {"country": "RO"}, "model": "embargo.country", "pk": 181}, {"fields": {"country": "RU"}, "model": "embargo.country", "pk": 182}, {"fields": {"country": "RW"}, "model": "embargo.country", "pk": 183}, {"fields": {"country": "BL"}, "model": "embargo.country", "pk": 184}, {"fields": {"country": "SH"}, "model": "embargo.country", "pk": 185}, {"fields": {"country": "KN"}, "model": "embargo.country", "pk": 186}, {"fields": {"country": "LC"}, "model": "embargo.country", "pk": 187}, {"fields": {"country": "MF"}, "model": "embargo.country", "pk": 188}, {"fields": {"country": "PM"}, "model": "embargo.country", "pk": 189}, {"fields": {"country": "VC"}, "model": "embargo.country", "pk": 190}, {"fields": {"country": "WS"}, "model": "embargo.country", "pk": 191}, {"fields": {"country": "SM"}, "model": "embargo.country", "pk": 192}, {"fields": {"country": "ST"}, "model": "embargo.country", "pk": 193}, {"fields": {"country": "SA"}, "model": "embargo.country", "pk": 194}, {"fields": {"country": "SN"}, "model": "embargo.country", "pk": 195}, {"fields": {"country": "RS"}, "model": "embargo.country", "pk": 196}, {"fields": {"country": "SC"}, "model": "embargo.country", "pk": 197}, {"fields": {"country": "SL"}, "model": "embargo.country", "pk": 198}, {"fields": {"country": "SG"}, "model": "embargo.country", "pk": 199}, {"fields": {"country": "SX"}, "model": "embargo.country", "pk": 200}, {"fields": {"country": "SK"}, "model": "embargo.country", "pk": 201}, {"fields": {"country": "SI"}, "model": "embargo.country", "pk": 202}, {"fields": {"country": "SB"}, "model": "embargo.country", "pk": 203}, {"fields": {"country": "SO"}, "model": "embargo.country", "pk": 204}, {"fields": {"country": "ZA"}, "model": "embargo.country", "pk": 205}, {"fields": {"country": "GS"}, "model": "embargo.country", "pk": 206}, {"fields": {"country": "KR"}, "model": "embargo.country", "pk": 207}, {"fields": {"country": "SS"}, "model": "embargo.country", "pk": 208}, {"fields": {"country": "ES"}, "model": "embargo.country", "pk": 209}, {"fields": {"country": "LK"}, "model": "embargo.country", "pk": 210}, {"fields": {"country": "SD"}, "model": "embargo.country", "pk": 211}, {"fields": {"country": "SR"}, "model": "embargo.country", "pk": 212}, {"fields": {"country": "SJ"}, "model": "embargo.country", "pk": 213}, {"fields": {"country": "SZ"}, "model": "embargo.country", "pk": 214}, {"fields": {"country": "SE"}, "model": "embargo.country", "pk": 215}, {"fields": {"country": "CH"}, "model": "embargo.country", "pk": 216}, {"fields": {"country": "SY"}, "model": "embargo.country", "pk": 217}, {"fields": {"country": "TW"}, "model": "embargo.country", "pk": 218}, {"fields": {"country": "TJ"}, "model": "embargo.country", "pk": 219}, {"fields": {"country": "TZ"}, "model": "embargo.country", "pk": 220}, {"fields": {"country": "TH"}, "model": "embargo.country", "pk": 221}, {"fields": {"country": "TL"}, "model": "embargo.country", "pk": 222}, {"fields": {"country": "TG"}, "model": "embargo.country", "pk": 223}, {"fields": {"country": "TK"}, "model": "embargo.country", "pk": 224}, {"fields": {"country": "TO"}, "model": "embargo.country", "pk": 225}, {"fields": {"country": "TT"}, "model": "embargo.country", "pk": 226}, {"fields": {"country": "TN"}, "model": "embargo.country", "pk": 227}, {"fields": {"country": "TR"}, "model": "embargo.country", "pk": 228}, {"fields": {"country": "TM"}, "model": "embargo.country", "pk": 229}, {"fields": {"country": "TC"}, "model": "embargo.country", "pk": 230}, {"fields": {"country": "TV"}, "model": "embargo.country", "pk": 231}, {"fields": {"country": "UG"}, "model": "embargo.country", "pk": 232}, {"fields": {"country": "UA"}, "model": "embargo.country", "pk": 233}, {"fields": {"country": "AE"}, "model": "embargo.country", "pk": 234}, {"fields": {"country": "GB"}, "model": "embargo.country", "pk": 235}, {"fields": {"country": "UM"}, "model": "embargo.country", "pk": 236}, {"fields": {"country": "US"}, "model": "embargo.country", "pk": 237}, {"fields": {"country": "UY"}, "model": "embargo.country", "pk": 238}, {"fields": {"country": "UZ"}, "model": "embargo.country", "pk": 239}, {"fields": {"country": "VU"}, "model": "embargo.country", "pk": 240}, {"fields": {"country": "VE"}, "model": "embargo.country", "pk": 241}, {"fields": {"country": "VN"}, "model": "embargo.country", "pk": 242}, {"fields": {"country": "VG"}, "model": "embargo.country", "pk": 243}, {"fields": {"country": "VI"}, "model": "embargo.country", "pk": 244}, {"fields": {"country": "WF"}, "model": "embargo.country", "pk": 245}, {"fields": {"country": "EH"}, "model": "embargo.country", "pk": 246}, {"fields": {"country": "YE"}, "model": "embargo.country", "pk": 247}, {"fields": {"country": "ZM"}, "model": "embargo.country", "pk": 248}, {"fields": {"country": "ZW"}, "model": "embargo.country", "pk": 249}, {"fields": {"default": false, "mode": "honor", "icon": "course_complete_badges/honor.png"}, "model": "badges.coursecompleteimageconfiguration", "pk": 1}, {"fields": {"default": false, "mode": "verified", "icon": "course_complete_badges/verified.png"}, "model": "badges.coursecompleteimageconfiguration", "pk": 2}, {"fields": {"default": false, "mode": "professional", "icon": "course_complete_badges/professional.png"}, "model": "badges.coursecompleteimageconfiguration", "pk": 3}, {"fields": {"profile_name": "desktop_mp4"}, "model": "edxval.profile", "pk": 1}, {"fields": {"profile_name": "desktop_webm"}, "model": "edxval.profile", "pk": 2}, {"fields": {"profile_name": "mobile_high"}, "model": "edxval.profile", "pk": 3}, {"fields": {"profile_name": "mobile_low"}, "model": "edxval.profile", "pk": 4}, {"fields": {"profile_name": "youtube"}, "model": "edxval.profile", "pk": 5}, {"fields": {"active": true, "description": "Autogenerated milestone relationship type \"fulfills\"", "modified": "2015-11-20T03:58:34.228Z", "name": "fulfills", "created": "2015-11-20T03:58:34.227Z"}, "model": "milestones.milestonerelationshiptype", "pk": 1}, {"fields": {"active": true, "description": "Autogenerated milestone relationship type \"requires\"", "modified": "2015-11-20T03:58:34.230Z", "name": "requires", "created": "2015-11-20T03:58:34.230Z"}, "model": "milestones.milestonerelationshiptype", "pk": 2}, {"fields": {"codename": "add_permission", "name": "Can add permission", "content_type": 1}, "model": "auth.permission", "pk": 1}, {"fields": {"codename": "change_permission", "name": "Can change permission", "content_type": 1}, "model": "auth.permission", "pk": 2}, {"fields": {"codename": "delete_permission", "name": "Can delete permission", "content_type": 1}, "model": "auth.permission", "pk": 3}, {"fields": {"codename": "add_group", "name": "Can add group", "content_type": 2}, "model": "auth.permission", "pk": 4}, {"fields": {"codename": "change_group", "name": "Can change group", "content_type": 2}, "model": "auth.permission", "pk": 5}, {"fields": {"codename": "delete_group", "name": "Can delete group", "content_type": 2}, "model": "auth.permission", "pk": 6}, {"fields": {"codename": "add_user", "name": "Can add user", "content_type": 3}, "model": "auth.permission", "pk": 7}, {"fields": {"codename": "change_user", "name": "Can change user", "content_type": 3}, "model": "auth.permission", "pk": 8}, {"fields": {"codename": "delete_user", "name": "Can delete user", "content_type": 3}, "model": "auth.permission", "pk": 9}, {"fields": {"codename": "add_contenttype", "name": "Can add content type", "content_type": 4}, "model": "auth.permission", "pk": 10}, {"fields": {"codename": "change_contenttype", "name": "Can change content type", "content_type": 4}, "model": "auth.permission", "pk": 11}, {"fields": {"codename": "delete_contenttype", "name": "Can delete content type", "content_type": 4}, "model": "auth.permission", "pk": 12}, {"fields": {"codename": "add_session", "name": "Can add session", "content_type": 5}, "model": "auth.permission", "pk": 13}, {"fields": {"codename": "change_session", "name": "Can change session", "content_type": 5}, "model": "auth.permission", "pk": 14}, {"fields": {"codename": "delete_session", "name": "Can delete session", "content_type": 5}, "model": "auth.permission", "pk": 15}, {"fields": {"codename": "add_site", "name": "Can add site", "content_type": 6}, "model": "auth.permission", "pk": 16}, {"fields": {"codename": "change_site", "name": "Can change site", "content_type": 6}, "model": "auth.permission", "pk": 17}, {"fields": {"codename": "delete_site", "name": "Can delete site", "content_type": 6}, "model": "auth.permission", "pk": 18}, {"fields": {"codename": "add_taskmeta", "name": "Can add task state", "content_type": 7}, "model": "auth.permission", "pk": 19}, {"fields": {"codename": "change_taskmeta", "name": "Can change task state", "content_type": 7}, "model": "auth.permission", "pk": 20}, {"fields": {"codename": "delete_taskmeta", "name": "Can delete task state", "content_type": 7}, "model": "auth.permission", "pk": 21}, {"fields": {"codename": "add_tasksetmeta", "name": "Can add saved group result", "content_type": 8}, "model": "auth.permission", "pk": 22}, {"fields": {"codename": "change_tasksetmeta", "name": "Can change saved group result", "content_type": 8}, "model": "auth.permission", "pk": 23}, {"fields": {"codename": "delete_tasksetmeta", "name": "Can delete saved group result", "content_type": 8}, "model": "auth.permission", "pk": 24}, {"fields": {"codename": "add_intervalschedule", "name": "Can add interval", "content_type": 9}, "model": "auth.permission", "pk": 25}, {"fields": {"codename": "change_intervalschedule", "name": "Can change interval", "content_type": 9}, "model": "auth.permission", "pk": 26}, {"fields": {"codename": "delete_intervalschedule", "name": "Can delete interval", "content_type": 9}, "model": "auth.permission", "pk": 27}, {"fields": {"codename": "add_crontabschedule", "name": "Can add crontab", "content_type": 10}, "model": "auth.permission", "pk": 28}, {"fields": {"codename": "change_crontabschedule", "name": "Can change crontab", "content_type": 10}, "model": "auth.permission", "pk": 29}, {"fields": {"codename": "delete_crontabschedule", "name": "Can delete crontab", "content_type": 10}, "model": "auth.permission", "pk": 30}, {"fields": {"codename": "add_periodictasks", "name": "Can add periodic tasks", "content_type": 11}, "model": "auth.permission", "pk": 31}, {"fields": {"codename": "change_periodictasks", "name": "Can change periodic tasks", "content_type": 11}, "model": "auth.permission", "pk": 32}, {"fields": {"codename": "delete_periodictasks", "name": "Can delete periodic tasks", "content_type": 11}, "model": "auth.permission", "pk": 33}, {"fields": {"codename": "add_periodictask", "name": "Can add periodic task", "content_type": 12}, "model": "auth.permission", "pk": 34}, {"fields": {"codename": "change_periodictask", "name": "Can change periodic task", "content_type": 12}, "model": "auth.permission", "pk": 35}, {"fields": {"codename": "delete_periodictask", "name": "Can delete periodic task", "content_type": 12}, "model": "auth.permission", "pk": 36}, {"fields": {"codename": "add_workerstate", "name": "Can add worker", "content_type": 13}, "model": "auth.permission", "pk": 37}, {"fields": {"codename": "change_workerstate", "name": "Can change worker", "content_type": 13}, "model": "auth.permission", "pk": 38}, {"fields": {"codename": "delete_workerstate", "name": "Can delete worker", "content_type": 13}, "model": "auth.permission", "pk": 39}, {"fields": {"codename": "add_taskstate", "name": "Can add task", "content_type": 14}, "model": "auth.permission", "pk": 40}, {"fields": {"codename": "change_taskstate", "name": "Can change task", "content_type": 14}, "model": "auth.permission", "pk": 41}, {"fields": {"codename": "delete_taskstate", "name": "Can delete task", "content_type": 14}, "model": "auth.permission", "pk": 42}, {"fields": {"codename": "add_globalstatusmessage", "name": "Can add global status message", "content_type": 15}, "model": "auth.permission", "pk": 43}, {"fields": {"codename": "change_globalstatusmessage", "name": "Can change global status message", "content_type": 15}, "model": "auth.permission", "pk": 44}, {"fields": {"codename": "delete_globalstatusmessage", "name": "Can delete global status message", "content_type": 15}, "model": "auth.permission", "pk": 45}, {"fields": {"codename": "add_coursemessage", "name": "Can add course message", "content_type": 16}, "model": "auth.permission", "pk": 46}, {"fields": {"codename": "change_coursemessage", "name": "Can change course message", "content_type": 16}, "model": "auth.permission", "pk": 47}, {"fields": {"codename": "delete_coursemessage", "name": "Can delete course message", "content_type": 16}, "model": "auth.permission", "pk": 48}, {"fields": {"codename": "add_studentmodule", "name": "Can add student module", "content_type": 17}, "model": "auth.permission", "pk": 49}, {"fields": {"codename": "change_studentmodule", "name": "Can change student module", "content_type": 17}, "model": "auth.permission", "pk": 50}, {"fields": {"codename": "delete_studentmodule", "name": "Can delete student module", "content_type": 17}, "model": "auth.permission", "pk": 51}, {"fields": {"codename": "add_studentmodulehistory", "name": "Can add student module history", "content_type": 18}, "model": "auth.permission", "pk": 52}, {"fields": {"codename": "change_studentmodulehistory", "name": "Can change student module history", "content_type": 18}, "model": "auth.permission", "pk": 53}, {"fields": {"codename": "delete_studentmodulehistory", "name": "Can delete student module history", "content_type": 18}, "model": "auth.permission", "pk": 54}, {"fields": {"codename": "add_xmoduleuserstatesummaryfield", "name": "Can add x module user state summary field", "content_type": 19}, "model": "auth.permission", "pk": 55}, {"fields": {"codename": "change_xmoduleuserstatesummaryfield", "name": "Can change x module user state summary field", "content_type": 19}, "model": "auth.permission", "pk": 56}, {"fields": {"codename": "delete_xmoduleuserstatesummaryfield", "name": "Can delete x module user state summary field", "content_type": 19}, "model": "auth.permission", "pk": 57}, {"fields": {"codename": "add_xmodulestudentprefsfield", "name": "Can add x module student prefs field", "content_type": 20}, "model": "auth.permission", "pk": 58}, {"fields": {"codename": "change_xmodulestudentprefsfield", "name": "Can change x module student prefs field", "content_type": 20}, "model": "auth.permission", "pk": 59}, {"fields": {"codename": "delete_xmodulestudentprefsfield", "name": "Can delete x module student prefs field", "content_type": 20}, "model": "auth.permission", "pk": 60}, {"fields": {"codename": "add_xmodulestudentinfofield", "name": "Can add x module student info field", "content_type": 21}, "model": "auth.permission", "pk": 61}, {"fields": {"codename": "change_xmodulestudentinfofield", "name": "Can change x module student info field", "content_type": 21}, "model": "auth.permission", "pk": 62}, {"fields": {"codename": "delete_xmodulestudentinfofield", "name": "Can delete x module student info field", "content_type": 21}, "model": "auth.permission", "pk": 63}, {"fields": {"codename": "add_offlinecomputedgrade", "name": "Can add offline computed grade", "content_type": 22}, "model": "auth.permission", "pk": 64}, {"fields": {"codename": "change_offlinecomputedgrade", "name": "Can change offline computed grade", "content_type": 22}, "model": "auth.permission", "pk": 65}, {"fields": {"codename": "delete_offlinecomputedgrade", "name": "Can delete offline computed grade", "content_type": 22}, "model": "auth.permission", "pk": 66}, {"fields": {"codename": "add_offlinecomputedgradelog", "name": "Can add offline computed grade log", "content_type": 23}, "model": "auth.permission", "pk": 67}, {"fields": {"codename": "change_offlinecomputedgradelog", "name": "Can change offline computed grade log", "content_type": 23}, "model": "auth.permission", "pk": 68}, {"fields": {"codename": "delete_offlinecomputedgradelog", "name": "Can delete offline computed grade log", "content_type": 23}, "model": "auth.permission", "pk": 69}, {"fields": {"codename": "add_studentfieldoverride", "name": "Can add student field override", "content_type": 24}, "model": "auth.permission", "pk": 70}, {"fields": {"codename": "change_studentfieldoverride", "name": "Can change student field override", "content_type": 24}, "model": "auth.permission", "pk": 71}, {"fields": {"codename": "delete_studentfieldoverride", "name": "Can delete student field override", "content_type": 24}, "model": "auth.permission", "pk": 72}, {"fields": {"codename": "add_anonymoususerid", "name": "Can add anonymous user id", "content_type": 25}, "model": "auth.permission", "pk": 73}, {"fields": {"codename": "change_anonymoususerid", "name": "Can change anonymous user id", "content_type": 25}, "model": "auth.permission", "pk": 74}, {"fields": {"codename": "delete_anonymoususerid", "name": "Can delete anonymous user id", "content_type": 25}, "model": "auth.permission", "pk": 75}, {"fields": {"codename": "add_userstanding", "name": "Can add user standing", "content_type": 26}, "model": "auth.permission", "pk": 76}, {"fields": {"codename": "change_userstanding", "name": "Can change user standing", "content_type": 26}, "model": "auth.permission", "pk": 77}, {"fields": {"codename": "delete_userstanding", "name": "Can delete user standing", "content_type": 26}, "model": "auth.permission", "pk": 78}, {"fields": {"codename": "add_userprofile", "name": "Can add user profile", "content_type": 27}, "model": "auth.permission", "pk": 79}, {"fields": {"codename": "change_userprofile", "name": "Can change user profile", "content_type": 27}, "model": "auth.permission", "pk": 80}, {"fields": {"codename": "delete_userprofile", "name": "Can delete user profile", "content_type": 27}, "model": "auth.permission", "pk": 81}, {"fields": {"codename": "add_usersignupsource", "name": "Can add user signup source", "content_type": 28}, "model": "auth.permission", "pk": 82}, {"fields": {"codename": "change_usersignupsource", "name": "Can change user signup source", "content_type": 28}, "model": "auth.permission", "pk": 83}, {"fields": {"codename": "delete_usersignupsource", "name": "Can delete user signup source", "content_type": 28}, "model": "auth.permission", "pk": 84}, {"fields": {"codename": "add_usertestgroup", "name": "Can add user test group", "content_type": 29}, "model": "auth.permission", "pk": 85}, {"fields": {"codename": "change_usertestgroup", "name": "Can change user test group", "content_type": 29}, "model": "auth.permission", "pk": 86}, {"fields": {"codename": "delete_usertestgroup", "name": "Can delete user test group", "content_type": 29}, "model": "auth.permission", "pk": 87}, {"fields": {"codename": "add_registration", "name": "Can add registration", "content_type": 30}, "model": "auth.permission", "pk": 88}, {"fields": {"codename": "change_registration", "name": "Can change registration", "content_type": 30}, "model": "auth.permission", "pk": 89}, {"fields": {"codename": "delete_registration", "name": "Can delete registration", "content_type": 30}, "model": "auth.permission", "pk": 90}, {"fields": {"codename": "add_pendingnamechange", "name": "Can add pending name change", "content_type": 31}, "model": "auth.permission", "pk": 91}, {"fields": {"codename": "change_pendingnamechange", "name": "Can change pending name change", "content_type": 31}, "model": "auth.permission", "pk": 92}, {"fields": {"codename": "delete_pendingnamechange", "name": "Can delete pending name change", "content_type": 31}, "model": "auth.permission", "pk": 93}, {"fields": {"codename": "add_pendingemailchange", "name": "Can add pending email change", "content_type": 32}, "model": "auth.permission", "pk": 94}, {"fields": {"codename": "change_pendingemailchange", "name": "Can change pending email change", "content_type": 32}, "model": "auth.permission", "pk": 95}, {"fields": {"codename": "delete_pendingemailchange", "name": "Can delete pending email change", "content_type": 32}, "model": "auth.permission", "pk": 96}, {"fields": {"codename": "add_passwordhistory", "name": "Can add password history", "content_type": 33}, "model": "auth.permission", "pk": 97}, {"fields": {"codename": "change_passwordhistory", "name": "Can change password history", "content_type": 33}, "model": "auth.permission", "pk": 98}, {"fields": {"codename": "delete_passwordhistory", "name": "Can delete password history", "content_type": 33}, "model": "auth.permission", "pk": 99}, {"fields": {"codename": "add_loginfailures", "name": "Can add login failures", "content_type": 34}, "model": "auth.permission", "pk": 100}, {"fields": {"codename": "change_loginfailures", "name": "Can change login failures", "content_type": 34}, "model": "auth.permission", "pk": 101}, {"fields": {"codename": "delete_loginfailures", "name": "Can delete login failures", "content_type": 34}, "model": "auth.permission", "pk": 102}, {"fields": {"codename": "add_historicalcourseenrollment", "name": "Can add historical course enrollment", "content_type": 35}, "model": "auth.permission", "pk": 103}, {"fields": {"codename": "change_historicalcourseenrollment", "name": "Can change historical course enrollment", "content_type": 35}, "model": "auth.permission", "pk": 104}, {"fields": {"codename": "delete_historicalcourseenrollment", "name": "Can delete historical course enrollment", "content_type": 35}, "model": "auth.permission", "pk": 105}, {"fields": {"codename": "add_courseenrollment", "name": "Can add course enrollment", "content_type": 36}, "model": "auth.permission", "pk": 106}, {"fields": {"codename": "change_courseenrollment", "name": "Can change course enrollment", "content_type": 36}, "model": "auth.permission", "pk": 107}, {"fields": {"codename": "delete_courseenrollment", "name": "Can delete course enrollment", "content_type": 36}, "model": "auth.permission", "pk": 108}, {"fields": {"codename": "add_manualenrollmentaudit", "name": "Can add manual enrollment audit", "content_type": 37}, "model": "auth.permission", "pk": 109}, {"fields": {"codename": "change_manualenrollmentaudit", "name": "Can change manual enrollment audit", "content_type": 37}, "model": "auth.permission", "pk": 110}, {"fields": {"codename": "delete_manualenrollmentaudit", "name": "Can delete manual enrollment audit", "content_type": 37}, "model": "auth.permission", "pk": 111}, {"fields": {"codename": "add_courseenrollmentallowed", "name": "Can add course enrollment allowed", "content_type": 38}, "model": "auth.permission", "pk": 112}, {"fields": {"codename": "change_courseenrollmentallowed", "name": "Can change course enrollment allowed", "content_type": 38}, "model": "auth.permission", "pk": 113}, {"fields": {"codename": "delete_courseenrollmentallowed", "name": "Can delete course enrollment allowed", "content_type": 38}, "model": "auth.permission", "pk": 114}, {"fields": {"codename": "add_courseaccessrole", "name": "Can add course access role", "content_type": 39}, "model": "auth.permission", "pk": 115}, {"fields": {"codename": "change_courseaccessrole", "name": "Can change course access role", "content_type": 39}, "model": "auth.permission", "pk": 116}, {"fields": {"codename": "delete_courseaccessrole", "name": "Can delete course access role", "content_type": 39}, "model": "auth.permission", "pk": 117}, {"fields": {"codename": "add_dashboardconfiguration", "name": "Can add dashboard configuration", "content_type": 40}, "model": "auth.permission", "pk": 118}, {"fields": {"codename": "change_dashboardconfiguration", "name": "Can change dashboard configuration", "content_type": 40}, "model": "auth.permission", "pk": 119}, {"fields": {"codename": "delete_dashboardconfiguration", "name": "Can delete dashboard configuration", "content_type": 40}, "model": "auth.permission", "pk": 120}, {"fields": {"codename": "add_linkedinaddtoprofileconfiguration", "name": "Can add linked in add to profile configuration", "content_type": 41}, "model": "auth.permission", "pk": 121}, {"fields": {"codename": "change_linkedinaddtoprofileconfiguration", "name": "Can change linked in add to profile configuration", "content_type": 41}, "model": "auth.permission", "pk": 122}, {"fields": {"codename": "delete_linkedinaddtoprofileconfiguration", "name": "Can delete linked in add to profile configuration", "content_type": 41}, "model": "auth.permission", "pk": 123}, {"fields": {"codename": "add_entranceexamconfiguration", "name": "Can add entrance exam configuration", "content_type": 42}, "model": "auth.permission", "pk": 124}, {"fields": {"codename": "change_entranceexamconfiguration", "name": "Can change entrance exam configuration", "content_type": 42}, "model": "auth.permission", "pk": 125}, {"fields": {"codename": "delete_entranceexamconfiguration", "name": "Can delete entrance exam configuration", "content_type": 42}, "model": "auth.permission", "pk": 126}, {"fields": {"codename": "add_languageproficiency", "name": "Can add language proficiency", "content_type": 43}, "model": "auth.permission", "pk": 127}, {"fields": {"codename": "change_languageproficiency", "name": "Can change language proficiency", "content_type": 43}, "model": "auth.permission", "pk": 128}, {"fields": {"codename": "delete_languageproficiency", "name": "Can delete language proficiency", "content_type": 43}, "model": "auth.permission", "pk": 129}, {"fields": {"codename": "add_courseenrollmentattribute", "name": "Can add course enrollment attribute", "content_type": 44}, "model": "auth.permission", "pk": 130}, {"fields": {"codename": "change_courseenrollmentattribute", "name": "Can change course enrollment attribute", "content_type": 44}, "model": "auth.permission", "pk": 131}, {"fields": {"codename": "delete_courseenrollmentattribute", "name": "Can delete course enrollment attribute", "content_type": 44}, "model": "auth.permission", "pk": 132}, {"fields": {"codename": "add_enrollmentrefundconfiguration", "name": "Can add enrollment refund configuration", "content_type": 45}, "model": "auth.permission", "pk": 133}, {"fields": {"codename": "change_enrollmentrefundconfiguration", "name": "Can change enrollment refund configuration", "content_type": 45}, "model": "auth.permission", "pk": 134}, {"fields": {"codename": "delete_enrollmentrefundconfiguration", "name": "Can delete enrollment refund configuration", "content_type": 45}, "model": "auth.permission", "pk": 135}, {"fields": {"codename": "add_trackinglog", "name": "Can add tracking log", "content_type": 46}, "model": "auth.permission", "pk": 136}, {"fields": {"codename": "change_trackinglog", "name": "Can change tracking log", "content_type": 46}, "model": "auth.permission", "pk": 137}, {"fields": {"codename": "delete_trackinglog", "name": "Can delete tracking log", "content_type": 46}, "model": "auth.permission", "pk": 138}, {"fields": {"codename": "add_ratelimitconfiguration", "name": "Can add rate limit configuration", "content_type": 47}, "model": "auth.permission", "pk": 139}, {"fields": {"codename": "change_ratelimitconfiguration", "name": "Can change rate limit configuration", "content_type": 47}, "model": "auth.permission", "pk": 140}, {"fields": {"codename": "delete_ratelimitconfiguration", "name": "Can delete rate limit configuration", "content_type": 47}, "model": "auth.permission", "pk": 141}, {"fields": {"codename": "add_certificatewhitelist", "name": "Can add certificate whitelist", "content_type": 48}, "model": "auth.permission", "pk": 142}, {"fields": {"codename": "change_certificatewhitelist", "name": "Can change certificate whitelist", "content_type": 48}, "model": "auth.permission", "pk": 143}, {"fields": {"codename": "delete_certificatewhitelist", "name": "Can delete certificate whitelist", "content_type": 48}, "model": "auth.permission", "pk": 144}, {"fields": {"codename": "add_generatedcertificate", "name": "Can add generated certificate", "content_type": 49}, "model": "auth.permission", "pk": 145}, {"fields": {"codename": "change_generatedcertificate", "name": "Can change generated certificate", "content_type": 49}, "model": "auth.permission", "pk": 146}, {"fields": {"codename": "delete_generatedcertificate", "name": "Can delete generated certificate", "content_type": 49}, "model": "auth.permission", "pk": 147}, {"fields": {"codename": "add_examplecertificateset", "name": "Can add example certificate set", "content_type": 50}, "model": "auth.permission", "pk": 148}, {"fields": {"codename": "change_examplecertificateset", "name": "Can change example certificate set", "content_type": 50}, "model": "auth.permission", "pk": 149}, {"fields": {"codename": "delete_examplecertificateset", "name": "Can delete example certificate set", "content_type": 50}, "model": "auth.permission", "pk": 150}, {"fields": {"codename": "add_examplecertificate", "name": "Can add example certificate", "content_type": 51}, "model": "auth.permission", "pk": 151}, {"fields": {"codename": "change_examplecertificate", "name": "Can change example certificate", "content_type": 51}, "model": "auth.permission", "pk": 152}, {"fields": {"codename": "delete_examplecertificate", "name": "Can delete example certificate", "content_type": 51}, "model": "auth.permission", "pk": 153}, {"fields": {"codename": "add_certificategenerationcoursesetting", "name": "Can add certificate generation course setting", "content_type": 52}, "model": "auth.permission", "pk": 154}, {"fields": {"codename": "change_certificategenerationcoursesetting", "name": "Can change certificate generation course setting", "content_type": 52}, "model": "auth.permission", "pk": 155}, {"fields": {"codename": "delete_certificategenerationcoursesetting", "name": "Can delete certificate generation course setting", "content_type": 52}, "model": "auth.permission", "pk": 156}, {"fields": {"codename": "add_certificategenerationconfiguration", "name": "Can add certificate generation configuration", "content_type": 53}, "model": "auth.permission", "pk": 157}, {"fields": {"codename": "change_certificategenerationconfiguration", "name": "Can change certificate generation configuration", "content_type": 53}, "model": "auth.permission", "pk": 158}, {"fields": {"codename": "delete_certificategenerationconfiguration", "name": "Can delete certificate generation configuration", "content_type": 53}, "model": "auth.permission", "pk": 159}, {"fields": {"codename": "add_certificatehtmlviewconfiguration", "name": "Can add certificate html view configuration", "content_type": 54}, "model": "auth.permission", "pk": 160}, {"fields": {"codename": "change_certificatehtmlviewconfiguration", "name": "Can change certificate html view configuration", "content_type": 54}, "model": "auth.permission", "pk": 161}, {"fields": {"codename": "delete_certificatehtmlviewconfiguration", "name": "Can delete certificate html view configuration", "content_type": 54}, "model": "auth.permission", "pk": 162}, {"fields": {"codename": "add_certificatetemplate", "name": "Can add certificate template", "content_type": 55}, "model": "auth.permission", "pk": 163}, {"fields": {"codename": "change_certificatetemplate", "name": "Can change certificate template", "content_type": 55}, "model": "auth.permission", "pk": 164}, {"fields": {"codename": "delete_certificatetemplate", "name": "Can delete certificate template", "content_type": 55}, "model": "auth.permission", "pk": 165}, {"fields": {"codename": "add_certificatetemplateasset", "name": "Can add certificate template asset", "content_type": 56}, "model": "auth.permission", "pk": 166}, {"fields": {"codename": "change_certificatetemplateasset", "name": "Can change certificate template asset", "content_type": 56}, "model": "auth.permission", "pk": 167}, {"fields": {"codename": "delete_certificatetemplateasset", "name": "Can delete certificate template asset", "content_type": 56}, "model": "auth.permission", "pk": 168}, {"fields": {"codename": "add_instructortask", "name": "Can add instructor task", "content_type": 57}, "model": "auth.permission", "pk": 169}, {"fields": {"codename": "change_instructortask", "name": "Can change instructor task", "content_type": 57}, "model": "auth.permission", "pk": 170}, {"fields": {"codename": "delete_instructortask", "name": "Can delete instructor task", "content_type": 57}, "model": "auth.permission", "pk": 171}, {"fields": {"codename": "add_psychometricdata", "name": "Can add psychometric data", "content_type": 58}, "model": "auth.permission", "pk": 172}, {"fields": {"codename": "change_psychometricdata", "name": "Can change psychometric data", "content_type": 58}, "model": "auth.permission", "pk": 173}, {"fields": {"codename": "delete_psychometricdata", "name": "Can delete psychometric data", "content_type": 58}, "model": "auth.permission", "pk": 174}, {"fields": {"codename": "add_coursesoftware", "name": "Can add course software", "content_type": 59}, "model": "auth.permission", "pk": 175}, {"fields": {"codename": "change_coursesoftware", "name": "Can change course software", "content_type": 59}, "model": "auth.permission", "pk": 176}, {"fields": {"codename": "delete_coursesoftware", "name": "Can delete course software", "content_type": 59}, "model": "auth.permission", "pk": 177}, {"fields": {"codename": "add_userlicense", "name": "Can add user license", "content_type": 60}, "model": "auth.permission", "pk": 178}, {"fields": {"codename": "change_userlicense", "name": "Can change user license", "content_type": 60}, "model": "auth.permission", "pk": 179}, {"fields": {"codename": "delete_userlicense", "name": "Can delete user license", "content_type": 60}, "model": "auth.permission", "pk": 180}, {"fields": {"codename": "add_courseusergroup", "name": "Can add course user group", "content_type": 61}, "model": "auth.permission", "pk": 181}, {"fields": {"codename": "change_courseusergroup", "name": "Can change course user group", "content_type": 61}, "model": "auth.permission", "pk": 182}, {"fields": {"codename": "delete_courseusergroup", "name": "Can delete course user group", "content_type": 61}, "model": "auth.permission", "pk": 183}, {"fields": {"codename": "add_cohortmembership", "name": "Can add cohort membership", "content_type": 62}, "model": "auth.permission", "pk": 184}, {"fields": {"codename": "change_cohortmembership", "name": "Can change cohort membership", "content_type": 62}, "model": "auth.permission", "pk": 185}, {"fields": {"codename": "delete_cohortmembership", "name": "Can delete cohort membership", "content_type": 62}, "model": "auth.permission", "pk": 186}, {"fields": {"codename": "add_courseusergrouppartitiongroup", "name": "Can add course user group partition group", "content_type": 63}, "model": "auth.permission", "pk": 187}, {"fields": {"codename": "change_courseusergrouppartitiongroup", "name": "Can change course user group partition group", "content_type": 63}, "model": "auth.permission", "pk": 188}, {"fields": {"codename": "delete_courseusergrouppartitiongroup", "name": "Can delete course user group partition group", "content_type": 63}, "model": "auth.permission", "pk": 189}, {"fields": {"codename": "add_coursecohortssettings", "name": "Can add course cohorts settings", "content_type": 64}, "model": "auth.permission", "pk": 190}, {"fields": {"codename": "change_coursecohortssettings", "name": "Can change course cohorts settings", "content_type": 64}, "model": "auth.permission", "pk": 191}, {"fields": {"codename": "delete_coursecohortssettings", "name": "Can delete course cohorts settings", "content_type": 64}, "model": "auth.permission", "pk": 192}, {"fields": {"codename": "add_coursecohort", "name": "Can add course cohort", "content_type": 65}, "model": "auth.permission", "pk": 193}, {"fields": {"codename": "change_coursecohort", "name": "Can change course cohort", "content_type": 65}, "model": "auth.permission", "pk": 194}, {"fields": {"codename": "delete_coursecohort", "name": "Can delete course cohort", "content_type": 65}, "model": "auth.permission", "pk": 195}, {"fields": {"codename": "add_courseemail", "name": "Can add course email", "content_type": 66}, "model": "auth.permission", "pk": 196}, {"fields": {"codename": "change_courseemail", "name": "Can change course email", "content_type": 66}, "model": "auth.permission", "pk": 197}, {"fields": {"codename": "delete_courseemail", "name": "Can delete course email", "content_type": 66}, "model": "auth.permission", "pk": 198}, {"fields": {"codename": "add_optout", "name": "Can add optout", "content_type": 67}, "model": "auth.permission", "pk": 199}, {"fields": {"codename": "change_optout", "name": "Can change optout", "content_type": 67}, "model": "auth.permission", "pk": 200}, {"fields": {"codename": "delete_optout", "name": "Can delete optout", "content_type": 67}, "model": "auth.permission", "pk": 201}, {"fields": {"codename": "add_courseemailtemplate", "name": "Can add course email template", "content_type": 68}, "model": "auth.permission", "pk": 202}, {"fields": {"codename": "change_courseemailtemplate", "name": "Can change course email template", "content_type": 68}, "model": "auth.permission", "pk": 203}, {"fields": {"codename": "delete_courseemailtemplate", "name": "Can delete course email template", "content_type": 68}, "model": "auth.permission", "pk": 204}, {"fields": {"codename": "add_courseauthorization", "name": "Can add course authorization", "content_type": 69}, "model": "auth.permission", "pk": 205}, {"fields": {"codename": "change_courseauthorization", "name": "Can change course authorization", "content_type": 69}, "model": "auth.permission", "pk": 206}, {"fields": {"codename": "delete_courseauthorization", "name": "Can delete course authorization", "content_type": 69}, "model": "auth.permission", "pk": 207}, {"fields": {"codename": "add_brandinginfoconfig", "name": "Can add branding info config", "content_type": 70}, "model": "auth.permission", "pk": 208}, {"fields": {"codename": "change_brandinginfoconfig", "name": "Can change branding info config", "content_type": 70}, "model": "auth.permission", "pk": 209}, {"fields": {"codename": "delete_brandinginfoconfig", "name": "Can delete branding info config", "content_type": 70}, "model": "auth.permission", "pk": 210}, {"fields": {"codename": "add_brandingapiconfig", "name": "Can add branding api config", "content_type": 71}, "model": "auth.permission", "pk": 211}, {"fields": {"codename": "change_brandingapiconfig", "name": "Can change branding api config", "content_type": 71}, "model": "auth.permission", "pk": 212}, {"fields": {"codename": "delete_brandingapiconfig", "name": "Can delete branding api config", "content_type": 71}, "model": "auth.permission", "pk": 213}, {"fields": {"codename": "add_externalauthmap", "name": "Can add external auth map", "content_type": 72}, "model": "auth.permission", "pk": 214}, {"fields": {"codename": "change_externalauthmap", "name": "Can change external auth map", "content_type": 72}, "model": "auth.permission", "pk": 215}, {"fields": {"codename": "delete_externalauthmap", "name": "Can delete external auth map", "content_type": 72}, "model": "auth.permission", "pk": 216}, {"fields": {"codename": "add_nonce", "name": "Can add nonce", "content_type": 73}, "model": "auth.permission", "pk": 217}, {"fields": {"codename": "change_nonce", "name": "Can change nonce", "content_type": 73}, "model": "auth.permission", "pk": 218}, {"fields": {"codename": "delete_nonce", "name": "Can delete nonce", "content_type": 73}, "model": "auth.permission", "pk": 219}, {"fields": {"codename": "add_association", "name": "Can add association", "content_type": 74}, "model": "auth.permission", "pk": 220}, {"fields": {"codename": "change_association", "name": "Can change association", "content_type": 74}, "model": "auth.permission", "pk": 221}, {"fields": {"codename": "delete_association", "name": "Can delete association", "content_type": 74}, "model": "auth.permission", "pk": 222}, {"fields": {"codename": "add_useropenid", "name": "Can add user open id", "content_type": 75}, "model": "auth.permission", "pk": 223}, {"fields": {"codename": "change_useropenid", "name": "Can change user open id", "content_type": 75}, "model": "auth.permission", "pk": 224}, {"fields": {"codename": "delete_useropenid", "name": "Can delete user open id", "content_type": 75}, "model": "auth.permission", "pk": 225}, {"fields": {"codename": "account_verified", "name": "The OpenID has been verified", "content_type": 75}, "model": "auth.permission", "pk": 226}, {"fields": {"codename": "add_client", "name": "Can add client", "content_type": 76}, "model": "auth.permission", "pk": 227}, {"fields": {"codename": "change_client", "name": "Can change client", "content_type": 76}, "model": "auth.permission", "pk": 228}, {"fields": {"codename": "delete_client", "name": "Can delete client", "content_type": 76}, "model": "auth.permission", "pk": 229}, {"fields": {"codename": "add_grant", "name": "Can add grant", "content_type": 77}, "model": "auth.permission", "pk": 230}, {"fields": {"codename": "change_grant", "name": "Can change grant", "content_type": 77}, "model": "auth.permission", "pk": 231}, {"fields": {"codename": "delete_grant", "name": "Can delete grant", "content_type": 77}, "model": "auth.permission", "pk": 232}, {"fields": {"codename": "add_accesstoken", "name": "Can add access token", "content_type": 78}, "model": "auth.permission", "pk": 233}, {"fields": {"codename": "change_accesstoken", "name": "Can change access token", "content_type": 78}, "model": "auth.permission", "pk": 234}, {"fields": {"codename": "delete_accesstoken", "name": "Can delete access token", "content_type": 78}, "model": "auth.permission", "pk": 235}, {"fields": {"codename": "add_refreshtoken", "name": "Can add refresh token", "content_type": 79}, "model": "auth.permission", "pk": 236}, {"fields": {"codename": "change_refreshtoken", "name": "Can change refresh token", "content_type": 79}, "model": "auth.permission", "pk": 237}, {"fields": {"codename": "delete_refreshtoken", "name": "Can delete refresh token", "content_type": 79}, "model": "auth.permission", "pk": 238}, {"fields": {"codename": "add_trustedclient", "name": "Can add trusted client", "content_type": 80}, "model": "auth.permission", "pk": 239}, {"fields": {"codename": "change_trustedclient", "name": "Can change trusted client", "content_type": 80}, "model": "auth.permission", "pk": 240}, {"fields": {"codename": "delete_trustedclient", "name": "Can delete trusted client", "content_type": 80}, "model": "auth.permission", "pk": 241}, {"fields": {"codename": "add_oauth2providerconfig", "name": "Can add Provider Configuration (OAuth)", "content_type": 81}, "model": "auth.permission", "pk": 242}, {"fields": {"codename": "change_oauth2providerconfig", "name": "Can change Provider Configuration (OAuth)", "content_type": 81}, "model": "auth.permission", "pk": 243}, {"fields": {"codename": "delete_oauth2providerconfig", "name": "Can delete Provider Configuration (OAuth)", "content_type": 81}, "model": "auth.permission", "pk": 244}, {"fields": {"codename": "add_samlproviderconfig", "name": "Can add Provider Configuration (SAML IdP)", "content_type": 82}, "model": "auth.permission", "pk": 245}, {"fields": {"codename": "change_samlproviderconfig", "name": "Can change Provider Configuration (SAML IdP)", "content_type": 82}, "model": "auth.permission", "pk": 246}, {"fields": {"codename": "delete_samlproviderconfig", "name": "Can delete Provider Configuration (SAML IdP)", "content_type": 82}, "model": "auth.permission", "pk": 247}, {"fields": {"codename": "add_samlconfiguration", "name": "Can add SAML Configuration", "content_type": 83}, "model": "auth.permission", "pk": 248}, {"fields": {"codename": "change_samlconfiguration", "name": "Can change SAML Configuration", "content_type": 83}, "model": "auth.permission", "pk": 249}, {"fields": {"codename": "delete_samlconfiguration", "name": "Can delete SAML Configuration", "content_type": 83}, "model": "auth.permission", "pk": 250}, {"fields": {"codename": "add_samlproviderdata", "name": "Can add SAML Provider Data", "content_type": 84}, "model": "auth.permission", "pk": 251}, {"fields": {"codename": "change_samlproviderdata", "name": "Can change SAML Provider Data", "content_type": 84}, "model": "auth.permission", "pk": 252}, {"fields": {"codename": "delete_samlproviderdata", "name": "Can delete SAML Provider Data", "content_type": 84}, "model": "auth.permission", "pk": 253}, {"fields": {"codename": "add_ltiproviderconfig", "name": "Can add Provider Configuration (LTI)", "content_type": 85}, "model": "auth.permission", "pk": 254}, {"fields": {"codename": "change_ltiproviderconfig", "name": "Can change Provider Configuration (LTI)", "content_type": 85}, "model": "auth.permission", "pk": 255}, {"fields": {"codename": "delete_ltiproviderconfig", "name": "Can delete Provider Configuration (LTI)", "content_type": 85}, "model": "auth.permission", "pk": 256}, {"fields": {"codename": "add_providerapipermissions", "name": "Can add Provider API Permission", "content_type": 86}, "model": "auth.permission", "pk": 257}, {"fields": {"codename": "change_providerapipermissions", "name": "Can change Provider API Permission", "content_type": 86}, "model": "auth.permission", "pk": 258}, {"fields": {"codename": "delete_providerapipermissions", "name": "Can delete Provider API Permission", "content_type": 86}, "model": "auth.permission", "pk": 259}, {"fields": {"codename": "add_nonce", "name": "Can add nonce", "content_type": 87}, "model": "auth.permission", "pk": 260}, {"fields": {"codename": "change_nonce", "name": "Can change nonce", "content_type": 87}, "model": "auth.permission", "pk": 261}, {"fields": {"codename": "delete_nonce", "name": "Can delete nonce", "content_type": 87}, "model": "auth.permission", "pk": 262}, {"fields": {"codename": "add_scope", "name": "Can add scope", "content_type": 88}, "model": "auth.permission", "pk": 263}, {"fields": {"codename": "change_scope", "name": "Can change scope", "content_type": 88}, "model": "auth.permission", "pk": 264}, {"fields": {"codename": "delete_scope", "name": "Can delete scope", "content_type": 88}, "model": "auth.permission", "pk": 265}, {"fields": {"codename": "add_resource", "name": "Can add resource", "content_type": 88}, "model": "auth.permission", "pk": 266}, {"fields": {"codename": "change_resource", "name": "Can change resource", "content_type": 88}, "model": "auth.permission", "pk": 267}, {"fields": {"codename": "delete_resource", "name": "Can delete resource", "content_type": 88}, "model": "auth.permission", "pk": 268}, {"fields": {"codename": "add_consumer", "name": "Can add consumer", "content_type": 89}, "model": "auth.permission", "pk": 269}, {"fields": {"codename": "change_consumer", "name": "Can change consumer", "content_type": 89}, "model": "auth.permission", "pk": 270}, {"fields": {"codename": "delete_consumer", "name": "Can delete consumer", "content_type": 89}, "model": "auth.permission", "pk": 271}, {"fields": {"codename": "add_token", "name": "Can add token", "content_type": 90}, "model": "auth.permission", "pk": 272}, {"fields": {"codename": "change_token", "name": "Can change token", "content_type": 90}, "model": "auth.permission", "pk": 273}, {"fields": {"codename": "delete_token", "name": "Can delete token", "content_type": 90}, "model": "auth.permission", "pk": 274}, {"fields": {"codename": "add_article", "name": "Can add article", "content_type": 92}, "model": "auth.permission", "pk": 275}, {"fields": {"codename": "change_article", "name": "Can change article", "content_type": 92}, "model": "auth.permission", "pk": 276}, {"fields": {"codename": "delete_article", "name": "Can delete article", "content_type": 92}, "model": "auth.permission", "pk": 277}, {"fields": {"codename": "moderate", "name": "Can edit all articles and lock/unlock/restore", "content_type": 92}, "model": "auth.permission", "pk": 278}, {"fields": {"codename": "assign", "name": "Can change ownership of any article", "content_type": 92}, "model": "auth.permission", "pk": 279}, {"fields": {"codename": "grant", "name": "Can assign permissions to other users", "content_type": 92}, "model": "auth.permission", "pk": 280}, {"fields": {"codename": "add_articleforobject", "name": "Can add Article for object", "content_type": 93}, "model": "auth.permission", "pk": 281}, {"fields": {"codename": "change_articleforobject", "name": "Can change Article for object", "content_type": 93}, "model": "auth.permission", "pk": 282}, {"fields": {"codename": "delete_articleforobject", "name": "Can delete Article for object", "content_type": 93}, "model": "auth.permission", "pk": 283}, {"fields": {"codename": "add_articlerevision", "name": "Can add article revision", "content_type": 94}, "model": "auth.permission", "pk": 284}, {"fields": {"codename": "change_articlerevision", "name": "Can change article revision", "content_type": 94}, "model": "auth.permission", "pk": 285}, {"fields": {"codename": "delete_articlerevision", "name": "Can delete article revision", "content_type": 94}, "model": "auth.permission", "pk": 286}, {"fields": {"codename": "add_urlpath", "name": "Can add URL path", "content_type": 95}, "model": "auth.permission", "pk": 287}, {"fields": {"codename": "change_urlpath", "name": "Can change URL path", "content_type": 95}, "model": "auth.permission", "pk": 288}, {"fields": {"codename": "delete_urlpath", "name": "Can delete URL path", "content_type": 95}, "model": "auth.permission", "pk": 289}, {"fields": {"codename": "add_articleplugin", "name": "Can add article plugin", "content_type": 96}, "model": "auth.permission", "pk": 290}, {"fields": {"codename": "change_articleplugin", "name": "Can change article plugin", "content_type": 96}, "model": "auth.permission", "pk": 291}, {"fields": {"codename": "delete_articleplugin", "name": "Can delete article plugin", "content_type": 96}, "model": "auth.permission", "pk": 292}, {"fields": {"codename": "add_reusableplugin", "name": "Can add reusable plugin", "content_type": 97}, "model": "auth.permission", "pk": 293}, {"fields": {"codename": "change_reusableplugin", "name": "Can change reusable plugin", "content_type": 97}, "model": "auth.permission", "pk": 294}, {"fields": {"codename": "delete_reusableplugin", "name": "Can delete reusable plugin", "content_type": 97}, "model": "auth.permission", "pk": 295}, {"fields": {"codename": "add_simpleplugin", "name": "Can add simple plugin", "content_type": 98}, "model": "auth.permission", "pk": 296}, {"fields": {"codename": "change_simpleplugin", "name": "Can change simple plugin", "content_type": 98}, "model": "auth.permission", "pk": 297}, {"fields": {"codename": "delete_simpleplugin", "name": "Can delete simple plugin", "content_type": 98}, "model": "auth.permission", "pk": 298}, {"fields": {"codename": "add_revisionplugin", "name": "Can add revision plugin", "content_type": 99}, "model": "auth.permission", "pk": 299}, {"fields": {"codename": "change_revisionplugin", "name": "Can change revision plugin", "content_type": 99}, "model": "auth.permission", "pk": 300}, {"fields": {"codename": "delete_revisionplugin", "name": "Can delete revision plugin", "content_type": 99}, "model": "auth.permission", "pk": 301}, {"fields": {"codename": "add_revisionpluginrevision", "name": "Can add revision plugin revision", "content_type": 100}, "model": "auth.permission", "pk": 302}, {"fields": {"codename": "change_revisionpluginrevision", "name": "Can change revision plugin revision", "content_type": 100}, "model": "auth.permission", "pk": 303}, {"fields": {"codename": "delete_revisionpluginrevision", "name": "Can delete revision plugin revision", "content_type": 100}, "model": "auth.permission", "pk": 304}, {"fields": {"codename": "add_image", "name": "Can add image", "content_type": 101}, "model": "auth.permission", "pk": 305}, {"fields": {"codename": "change_image", "name": "Can change image", "content_type": 101}, "model": "auth.permission", "pk": 306}, {"fields": {"codename": "delete_image", "name": "Can delete image", "content_type": 101}, "model": "auth.permission", "pk": 307}, {"fields": {"codename": "add_imagerevision", "name": "Can add image revision", "content_type": 102}, "model": "auth.permission", "pk": 308}, {"fields": {"codename": "change_imagerevision", "name": "Can change image revision", "content_type": 102}, "model": "auth.permission", "pk": 309}, {"fields": {"codename": "delete_imagerevision", "name": "Can delete image revision", "content_type": 102}, "model": "auth.permission", "pk": 310}, {"fields": {"codename": "add_attachment", "name": "Can add attachment", "content_type": 103}, "model": "auth.permission", "pk": 311}, {"fields": {"codename": "change_attachment", "name": "Can change attachment", "content_type": 103}, "model": "auth.permission", "pk": 312}, {"fields": {"codename": "delete_attachment", "name": "Can delete attachment", "content_type": 103}, "model": "auth.permission", "pk": 313}, {"fields": {"codename": "add_attachmentrevision", "name": "Can add attachment revision", "content_type": 104}, "model": "auth.permission", "pk": 314}, {"fields": {"codename": "change_attachmentrevision", "name": "Can change attachment revision", "content_type": 104}, "model": "auth.permission", "pk": 315}, {"fields": {"codename": "delete_attachmentrevision", "name": "Can delete attachment revision", "content_type": 104}, "model": "auth.permission", "pk": 316}, {"fields": {"codename": "add_notificationtype", "name": "Can add type", "content_type": 105}, "model": "auth.permission", "pk": 317}, {"fields": {"codename": "change_notificationtype", "name": "Can change type", "content_type": 105}, "model": "auth.permission", "pk": 318}, {"fields": {"codename": "delete_notificationtype", "name": "Can delete type", "content_type": 105}, "model": "auth.permission", "pk": 319}, {"fields": {"codename": "add_settings", "name": "Can add settings", "content_type": 106}, "model": "auth.permission", "pk": 320}, {"fields": {"codename": "change_settings", "name": "Can change settings", "content_type": 106}, "model": "auth.permission", "pk": 321}, {"fields": {"codename": "delete_settings", "name": "Can delete settings", "content_type": 106}, "model": "auth.permission", "pk": 322}, {"fields": {"codename": "add_subscription", "name": "Can add subscription", "content_type": 107}, "model": "auth.permission", "pk": 323}, {"fields": {"codename": "change_subscription", "name": "Can change subscription", "content_type": 107}, "model": "auth.permission", "pk": 324}, {"fields": {"codename": "delete_subscription", "name": "Can delete subscription", "content_type": 107}, "model": "auth.permission", "pk": 325}, {"fields": {"codename": "add_notification", "name": "Can add notification", "content_type": 108}, "model": "auth.permission", "pk": 326}, {"fields": {"codename": "change_notification", "name": "Can change notification", "content_type": 108}, "model": "auth.permission", "pk": 327}, {"fields": {"codename": "delete_notification", "name": "Can delete notification", "content_type": 108}, "model": "auth.permission", "pk": 328}, {"fields": {"codename": "add_score", "name": "Can add score", "content_type": 109}, "model": "auth.permission", "pk": 329}, {"fields": {"codename": "change_score", "name": "Can change score", "content_type": 109}, "model": "auth.permission", "pk": 330}, {"fields": {"codename": "delete_score", "name": "Can delete score", "content_type": 109}, "model": "auth.permission", "pk": 331}, {"fields": {"codename": "add_puzzlecomplete", "name": "Can add puzzle complete", "content_type": 110}, "model": "auth.permission", "pk": 332}, {"fields": {"codename": "change_puzzlecomplete", "name": "Can change puzzle complete", "content_type": 110}, "model": "auth.permission", "pk": 333}, {"fields": {"codename": "delete_puzzlecomplete", "name": "Can delete puzzle complete", "content_type": 110}, "model": "auth.permission", "pk": 334}, {"fields": {"codename": "add_logentry", "name": "Can add log entry", "content_type": 111}, "model": "auth.permission", "pk": 335}, {"fields": {"codename": "change_logentry", "name": "Can change log entry", "content_type": 111}, "model": "auth.permission", "pk": 336}, {"fields": {"codename": "delete_logentry", "name": "Can delete log entry", "content_type": 111}, "model": "auth.permission", "pk": 337}, {"fields": {"codename": "add_role", "name": "Can add role", "content_type": 112}, "model": "auth.permission", "pk": 338}, {"fields": {"codename": "change_role", "name": "Can change role", "content_type": 112}, "model": "auth.permission", "pk": 339}, {"fields": {"codename": "delete_role", "name": "Can delete role", "content_type": 112}, "model": "auth.permission", "pk": 340}, {"fields": {"codename": "add_permission", "name": "Can add permission", "content_type": 113}, "model": "auth.permission", "pk": 341}, {"fields": {"codename": "change_permission", "name": "Can change permission", "content_type": 113}, "model": "auth.permission", "pk": 342}, {"fields": {"codename": "delete_permission", "name": "Can delete permission", "content_type": 113}, "model": "auth.permission", "pk": 343}, {"fields": {"codename": "add_note", "name": "Can add note", "content_type": 114}, "model": "auth.permission", "pk": 344}, {"fields": {"codename": "change_note", "name": "Can change note", "content_type": 114}, "model": "auth.permission", "pk": 345}, {"fields": {"codename": "delete_note", "name": "Can delete note", "content_type": 114}, "model": "auth.permission", "pk": 346}, {"fields": {"codename": "add_splashconfig", "name": "Can add splash config", "content_type": 115}, "model": "auth.permission", "pk": 347}, {"fields": {"codename": "change_splashconfig", "name": "Can change splash config", "content_type": 115}, "model": "auth.permission", "pk": 348}, {"fields": {"codename": "delete_splashconfig", "name": "Can delete splash config", "content_type": 115}, "model": "auth.permission", "pk": 349}, {"fields": {"codename": "add_userpreference", "name": "Can add user preference", "content_type": 116}, "model": "auth.permission", "pk": 350}, {"fields": {"codename": "change_userpreference", "name": "Can change user preference", "content_type": 116}, "model": "auth.permission", "pk": 351}, {"fields": {"codename": "delete_userpreference", "name": "Can delete user preference", "content_type": 116}, "model": "auth.permission", "pk": 352}, {"fields": {"codename": "add_usercoursetag", "name": "Can add user course tag", "content_type": 117}, "model": "auth.permission", "pk": 353}, {"fields": {"codename": "change_usercoursetag", "name": "Can change user course tag", "content_type": 117}, "model": "auth.permission", "pk": 354}, {"fields": {"codename": "delete_usercoursetag", "name": "Can delete user course tag", "content_type": 117}, "model": "auth.permission", "pk": 355}, {"fields": {"codename": "add_userorgtag", "name": "Can add user org tag", "content_type": 118}, "model": "auth.permission", "pk": 356}, {"fields": {"codename": "change_userorgtag", "name": "Can change user org tag", "content_type": 118}, "model": "auth.permission", "pk": 357}, {"fields": {"codename": "delete_userorgtag", "name": "Can delete user org tag", "content_type": 118}, "model": "auth.permission", "pk": 358}, {"fields": {"codename": "add_order", "name": "Can add order", "content_type": 119}, "model": "auth.permission", "pk": 359}, {"fields": {"codename": "change_order", "name": "Can change order", "content_type": 119}, "model": "auth.permission", "pk": 360}, {"fields": {"codename": "delete_order", "name": "Can delete order", "content_type": 119}, "model": "auth.permission", "pk": 361}, {"fields": {"codename": "add_orderitem", "name": "Can add order item", "content_type": 120}, "model": "auth.permission", "pk": 362}, {"fields": {"codename": "change_orderitem", "name": "Can change order item", "content_type": 120}, "model": "auth.permission", "pk": 363}, {"fields": {"codename": "delete_orderitem", "name": "Can delete order item", "content_type": 120}, "model": "auth.permission", "pk": 364}, {"fields": {"codename": "add_invoice", "name": "Can add invoice", "content_type": 121}, "model": "auth.permission", "pk": 365}, {"fields": {"codename": "change_invoice", "name": "Can change invoice", "content_type": 121}, "model": "auth.permission", "pk": 366}, {"fields": {"codename": "delete_invoice", "name": "Can delete invoice", "content_type": 121}, "model": "auth.permission", "pk": 367}, {"fields": {"codename": "add_invoicetransaction", "name": "Can add invoice transaction", "content_type": 122}, "model": "auth.permission", "pk": 368}, {"fields": {"codename": "change_invoicetransaction", "name": "Can change invoice transaction", "content_type": 122}, "model": "auth.permission", "pk": 369}, {"fields": {"codename": "delete_invoicetransaction", "name": "Can delete invoice transaction", "content_type": 122}, "model": "auth.permission", "pk": 370}, {"fields": {"codename": "add_invoiceitem", "name": "Can add invoice item", "content_type": 123}, "model": "auth.permission", "pk": 371}, {"fields": {"codename": "change_invoiceitem", "name": "Can change invoice item", "content_type": 123}, "model": "auth.permission", "pk": 372}, {"fields": {"codename": "delete_invoiceitem", "name": "Can delete invoice item", "content_type": 123}, "model": "auth.permission", "pk": 373}, {"fields": {"codename": "add_courseregistrationcodeinvoiceitem", "name": "Can add course registration code invoice item", "content_type": 124}, "model": "auth.permission", "pk": 374}, {"fields": {"codename": "change_courseregistrationcodeinvoiceitem", "name": "Can change course registration code invoice item", "content_type": 124}, "model": "auth.permission", "pk": 375}, {"fields": {"codename": "delete_courseregistrationcodeinvoiceitem", "name": "Can delete course registration code invoice item", "content_type": 124}, "model": "auth.permission", "pk": 376}, {"fields": {"codename": "add_invoicehistory", "name": "Can add invoice history", "content_type": 125}, "model": "auth.permission", "pk": 377}, {"fields": {"codename": "change_invoicehistory", "name": "Can change invoice history", "content_type": 125}, "model": "auth.permission", "pk": 378}, {"fields": {"codename": "delete_invoicehistory", "name": "Can delete invoice history", "content_type": 125}, "model": "auth.permission", "pk": 379}, {"fields": {"codename": "add_courseregistrationcode", "name": "Can add course registration code", "content_type": 126}, "model": "auth.permission", "pk": 380}, {"fields": {"codename": "change_courseregistrationcode", "name": "Can change course registration code", "content_type": 126}, "model": "auth.permission", "pk": 381}, {"fields": {"codename": "delete_courseregistrationcode", "name": "Can delete course registration code", "content_type": 126}, "model": "auth.permission", "pk": 382}, {"fields": {"codename": "add_registrationcoderedemption", "name": "Can add registration code redemption", "content_type": 127}, "model": "auth.permission", "pk": 383}, {"fields": {"codename": "change_registrationcoderedemption", "name": "Can change registration code redemption", "content_type": 127}, "model": "auth.permission", "pk": 384}, {"fields": {"codename": "delete_registrationcoderedemption", "name": "Can delete registration code redemption", "content_type": 127}, "model": "auth.permission", "pk": 385}, {"fields": {"codename": "add_coupon", "name": "Can add coupon", "content_type": 128}, "model": "auth.permission", "pk": 386}, {"fields": {"codename": "change_coupon", "name": "Can change coupon", "content_type": 128}, "model": "auth.permission", "pk": 387}, {"fields": {"codename": "delete_coupon", "name": "Can delete coupon", "content_type": 128}, "model": "auth.permission", "pk": 388}, {"fields": {"codename": "add_couponredemption", "name": "Can add coupon redemption", "content_type": 129}, "model": "auth.permission", "pk": 389}, {"fields": {"codename": "change_couponredemption", "name": "Can change coupon redemption", "content_type": 129}, "model": "auth.permission", "pk": 390}, {"fields": {"codename": "delete_couponredemption", "name": "Can delete coupon redemption", "content_type": 129}, "model": "auth.permission", "pk": 391}, {"fields": {"codename": "add_paidcourseregistration", "name": "Can add paid course registration", "content_type": 130}, "model": "auth.permission", "pk": 392}, {"fields": {"codename": "change_paidcourseregistration", "name": "Can change paid course registration", "content_type": 130}, "model": "auth.permission", "pk": 393}, {"fields": {"codename": "delete_paidcourseregistration", "name": "Can delete paid course registration", "content_type": 130}, "model": "auth.permission", "pk": 394}, {"fields": {"codename": "add_courseregcodeitem", "name": "Can add course reg code item", "content_type": 131}, "model": "auth.permission", "pk": 395}, {"fields": {"codename": "change_courseregcodeitem", "name": "Can change course reg code item", "content_type": 131}, "model": "auth.permission", "pk": 396}, {"fields": {"codename": "delete_courseregcodeitem", "name": "Can delete course reg code item", "content_type": 131}, "model": "auth.permission", "pk": 397}, {"fields": {"codename": "add_courseregcodeitemannotation", "name": "Can add course reg code item annotation", "content_type": 132}, "model": "auth.permission", "pk": 398}, {"fields": {"codename": "change_courseregcodeitemannotation", "name": "Can change course reg code item annotation", "content_type": 132}, "model": "auth.permission", "pk": 399}, {"fields": {"codename": "delete_courseregcodeitemannotation", "name": "Can delete course reg code item annotation", "content_type": 132}, "model": "auth.permission", "pk": 400}, {"fields": {"codename": "add_paidcourseregistrationannotation", "name": "Can add paid course registration annotation", "content_type": 133}, "model": "auth.permission", "pk": 401}, {"fields": {"codename": "change_paidcourseregistrationannotation", "name": "Can change paid course registration annotation", "content_type": 133}, "model": "auth.permission", "pk": 402}, {"fields": {"codename": "delete_paidcourseregistrationannotation", "name": "Can delete paid course registration annotation", "content_type": 133}, "model": "auth.permission", "pk": 403}, {"fields": {"codename": "add_certificateitem", "name": "Can add certificate item", "content_type": 134}, "model": "auth.permission", "pk": 404}, {"fields": {"codename": "change_certificateitem", "name": "Can change certificate item", "content_type": 134}, "model": "auth.permission", "pk": 405}, {"fields": {"codename": "delete_certificateitem", "name": "Can delete certificate item", "content_type": 134}, "model": "auth.permission", "pk": 406}, {"fields": {"codename": "add_donationconfiguration", "name": "Can add donation configuration", "content_type": 135}, "model": "auth.permission", "pk": 407}, {"fields": {"codename": "change_donationconfiguration", "name": "Can change donation configuration", "content_type": 135}, "model": "auth.permission", "pk": 408}, {"fields": {"codename": "delete_donationconfiguration", "name": "Can delete donation configuration", "content_type": 135}, "model": "auth.permission", "pk": 409}, {"fields": {"codename": "add_donation", "name": "Can add donation", "content_type": 136}, "model": "auth.permission", "pk": 410}, {"fields": {"codename": "change_donation", "name": "Can change donation", "content_type": 136}, "model": "auth.permission", "pk": 411}, {"fields": {"codename": "delete_donation", "name": "Can delete donation", "content_type": 136}, "model": "auth.permission", "pk": 412}, {"fields": {"codename": "add_coursemode", "name": "Can add course mode", "content_type": 137}, "model": "auth.permission", "pk": 413}, {"fields": {"codename": "change_coursemode", "name": "Can change course mode", "content_type": 137}, "model": "auth.permission", "pk": 414}, {"fields": {"codename": "delete_coursemode", "name": "Can delete course mode", "content_type": 137}, "model": "auth.permission", "pk": 415}, {"fields": {"codename": "add_coursemodesarchive", "name": "Can add course modes archive", "content_type": 138}, "model": "auth.permission", "pk": 416}, {"fields": {"codename": "change_coursemodesarchive", "name": "Can change course modes archive", "content_type": 138}, "model": "auth.permission", "pk": 417}, {"fields": {"codename": "delete_coursemodesarchive", "name": "Can delete course modes archive", "content_type": 138}, "model": "auth.permission", "pk": 418}, {"fields": {"codename": "add_softwaresecurephotoverification", "name": "Can add software secure photo verification", "content_type": 139}, "model": "auth.permission", "pk": 419}, {"fields": {"codename": "change_softwaresecurephotoverification", "name": "Can change software secure photo verification", "content_type": 139}, "model": "auth.permission", "pk": 420}, {"fields": {"codename": "delete_softwaresecurephotoverification", "name": "Can delete software secure photo verification", "content_type": 139}, "model": "auth.permission", "pk": 421}, {"fields": {"codename": "add_historicalverificationdeadline", "name": "Can add historical verification deadline", "content_type": 140}, "model": "auth.permission", "pk": 422}, {"fields": {"codename": "change_historicalverificationdeadline", "name": "Can change historical verification deadline", "content_type": 140}, "model": "auth.permission", "pk": 423}, {"fields": {"codename": "delete_historicalverificationdeadline", "name": "Can delete historical verification deadline", "content_type": 140}, "model": "auth.permission", "pk": 424}, {"fields": {"codename": "add_verificationdeadline", "name": "Can add verification deadline", "content_type": 141}, "model": "auth.permission", "pk": 425}, {"fields": {"codename": "change_verificationdeadline", "name": "Can change verification deadline", "content_type": 141}, "model": "auth.permission", "pk": 426}, {"fields": {"codename": "delete_verificationdeadline", "name": "Can delete verification deadline", "content_type": 141}, "model": "auth.permission", "pk": 427}, {"fields": {"codename": "add_verificationcheckpoint", "name": "Can add verification checkpoint", "content_type": 142}, "model": "auth.permission", "pk": 428}, {"fields": {"codename": "change_verificationcheckpoint", "name": "Can change verification checkpoint", "content_type": 142}, "model": "auth.permission", "pk": 429}, {"fields": {"codename": "delete_verificationcheckpoint", "name": "Can delete verification checkpoint", "content_type": 142}, "model": "auth.permission", "pk": 430}, {"fields": {"codename": "add_verificationstatus", "name": "Can add Verification Status", "content_type": 143}, "model": "auth.permission", "pk": 431}, {"fields": {"codename": "change_verificationstatus", "name": "Can change Verification Status", "content_type": 143}, "model": "auth.permission", "pk": 432}, {"fields": {"codename": "delete_verificationstatus", "name": "Can delete Verification Status", "content_type": 143}, "model": "auth.permission", "pk": 433}, {"fields": {"codename": "add_incoursereverificationconfiguration", "name": "Can add in course reverification configuration", "content_type": 144}, "model": "auth.permission", "pk": 434}, {"fields": {"codename": "change_incoursereverificationconfiguration", "name": "Can change in course reverification configuration", "content_type": 144}, "model": "auth.permission", "pk": 435}, {"fields": {"codename": "delete_incoursereverificationconfiguration", "name": "Can delete in course reverification configuration", "content_type": 144}, "model": "auth.permission", "pk": 436}, {"fields": {"codename": "add_icrvstatusemailsconfiguration", "name": "Can add icrv status emails configuration", "content_type": 145}, "model": "auth.permission", "pk": 437}, {"fields": {"codename": "change_icrvstatusemailsconfiguration", "name": "Can change icrv status emails configuration", "content_type": 145}, "model": "auth.permission", "pk": 438}, {"fields": {"codename": "delete_icrvstatusemailsconfiguration", "name": "Can delete icrv status emails configuration", "content_type": 145}, "model": "auth.permission", "pk": 439}, {"fields": {"codename": "add_skippedreverification", "name": "Can add skipped reverification", "content_type": 146}, "model": "auth.permission", "pk": 440}, {"fields": {"codename": "change_skippedreverification", "name": "Can change skipped reverification", "content_type": 146}, "model": "auth.permission", "pk": 441}, {"fields": {"codename": "delete_skippedreverification", "name": "Can delete skipped reverification", "content_type": 146}, "model": "auth.permission", "pk": 442}, {"fields": {"codename": "add_darklangconfig", "name": "Can add dark lang config", "content_type": 147}, "model": "auth.permission", "pk": 443}, {"fields": {"codename": "change_darklangconfig", "name": "Can change dark lang config", "content_type": 147}, "model": "auth.permission", "pk": 444}, {"fields": {"codename": "delete_darklangconfig", "name": "Can delete dark lang config", "content_type": 147}, "model": "auth.permission", "pk": 445}, {"fields": {"codename": "add_embargoedcourse", "name": "Can add embargoed course", "content_type": 148}, "model": "auth.permission", "pk": 446}, {"fields": {"codename": "change_embargoedcourse", "name": "Can change embargoed course", "content_type": 148}, "model": "auth.permission", "pk": 447}, {"fields": {"codename": "delete_embargoedcourse", "name": "Can delete embargoed course", "content_type": 148}, "model": "auth.permission", "pk": 448}, {"fields": {"codename": "add_embargoedstate", "name": "Can add embargoed state", "content_type": 149}, "model": "auth.permission", "pk": 449}, {"fields": {"codename": "change_embargoedstate", "name": "Can change embargoed state", "content_type": 149}, "model": "auth.permission", "pk": 450}, {"fields": {"codename": "delete_embargoedstate", "name": "Can delete embargoed state", "content_type": 149}, "model": "auth.permission", "pk": 451}, {"fields": {"codename": "add_restrictedcourse", "name": "Can add restricted course", "content_type": 150}, "model": "auth.permission", "pk": 452}, {"fields": {"codename": "change_restrictedcourse", "name": "Can change restricted course", "content_type": 150}, "model": "auth.permission", "pk": 453}, {"fields": {"codename": "delete_restrictedcourse", "name": "Can delete restricted course", "content_type": 150}, "model": "auth.permission", "pk": 454}, {"fields": {"codename": "add_country", "name": "Can add country", "content_type": 151}, "model": "auth.permission", "pk": 455}, {"fields": {"codename": "change_country", "name": "Can change country", "content_type": 151}, "model": "auth.permission", "pk": 456}, {"fields": {"codename": "delete_country", "name": "Can delete country", "content_type": 151}, "model": "auth.permission", "pk": 457}, {"fields": {"codename": "add_countryaccessrule", "name": "Can add country access rule", "content_type": 152}, "model": "auth.permission", "pk": 458}, {"fields": {"codename": "change_countryaccessrule", "name": "Can change country access rule", "content_type": 152}, "model": "auth.permission", "pk": 459}, {"fields": {"codename": "delete_countryaccessrule", "name": "Can delete country access rule", "content_type": 152}, "model": "auth.permission", "pk": 460}, {"fields": {"codename": "add_courseaccessrulehistory", "name": "Can add course access rule history", "content_type": 153}, "model": "auth.permission", "pk": 461}, {"fields": {"codename": "change_courseaccessrulehistory", "name": "Can change course access rule history", "content_type": 153}, "model": "auth.permission", "pk": 462}, {"fields": {"codename": "delete_courseaccessrulehistory", "name": "Can delete course access rule history", "content_type": 153}, "model": "auth.permission", "pk": 463}, {"fields": {"codename": "add_ipfilter", "name": "Can add ip filter", "content_type": 154}, "model": "auth.permission", "pk": 464}, {"fields": {"codename": "change_ipfilter", "name": "Can change ip filter", "content_type": 154}, "model": "auth.permission", "pk": 465}, {"fields": {"codename": "delete_ipfilter", "name": "Can delete ip filter", "content_type": 154}, "model": "auth.permission", "pk": 466}, {"fields": {"codename": "add_coursererunstate", "name": "Can add course rerun state", "content_type": 155}, "model": "auth.permission", "pk": 467}, {"fields": {"codename": "change_coursererunstate", "name": "Can change course rerun state", "content_type": 155}, "model": "auth.permission", "pk": 468}, {"fields": {"codename": "delete_coursererunstate", "name": "Can delete course rerun state", "content_type": 155}, "model": "auth.permission", "pk": 469}, {"fields": {"codename": "add_mobileapiconfig", "name": "Can add mobile api config", "content_type": 156}, "model": "auth.permission", "pk": 470}, {"fields": {"codename": "change_mobileapiconfig", "name": "Can change mobile api config", "content_type": 156}, "model": "auth.permission", "pk": 471}, {"fields": {"codename": "delete_mobileapiconfig", "name": "Can delete mobile api config", "content_type": 156}, "model": "auth.permission", "pk": 472}, {"fields": {"codename": "add_usersocialauth", "name": "Can add user social auth", "content_type": 157}, "model": "auth.permission", "pk": 473}, {"fields": {"codename": "change_usersocialauth", "name": "Can change user social auth", "content_type": 157}, "model": "auth.permission", "pk": 474}, {"fields": {"codename": "delete_usersocialauth", "name": "Can delete user social auth", "content_type": 157}, "model": "auth.permission", "pk": 475}, {"fields": {"codename": "add_nonce", "name": "Can add nonce", "content_type": 158}, "model": "auth.permission", "pk": 476}, {"fields": {"codename": "change_nonce", "name": "Can change nonce", "content_type": 158}, "model": "auth.permission", "pk": 477}, {"fields": {"codename": "delete_nonce", "name": "Can delete nonce", "content_type": 158}, "model": "auth.permission", "pk": 478}, {"fields": {"codename": "add_association", "name": "Can add association", "content_type": 159}, "model": "auth.permission", "pk": 479}, {"fields": {"codename": "change_association", "name": "Can change association", "content_type": 159}, "model": "auth.permission", "pk": 480}, {"fields": {"codename": "delete_association", "name": "Can delete association", "content_type": 159}, "model": "auth.permission", "pk": 481}, {"fields": {"codename": "add_code", "name": "Can add code", "content_type": 160}, "model": "auth.permission", "pk": 482}, {"fields": {"codename": "change_code", "name": "Can change code", "content_type": 160}, "model": "auth.permission", "pk": 483}, {"fields": {"codename": "delete_code", "name": "Can delete code", "content_type": 160}, "model": "auth.permission", "pk": 484}, {"fields": {"codename": "add_surveyform", "name": "Can add survey form", "content_type": 161}, "model": "auth.permission", "pk": 485}, {"fields": {"codename": "change_surveyform", "name": "Can change survey form", "content_type": 161}, "model": "auth.permission", "pk": 486}, {"fields": {"codename": "delete_surveyform", "name": "Can delete survey form", "content_type": 161}, "model": "auth.permission", "pk": 487}, {"fields": {"codename": "add_surveyanswer", "name": "Can add survey answer", "content_type": 162}, "model": "auth.permission", "pk": 488}, {"fields": {"codename": "change_surveyanswer", "name": "Can change survey answer", "content_type": 162}, "model": "auth.permission", "pk": 489}, {"fields": {"codename": "delete_surveyanswer", "name": "Can delete survey answer", "content_type": 162}, "model": "auth.permission", "pk": 490}, {"fields": {"codename": "add_xblockasidesconfig", "name": "Can add x block asides config", "content_type": 163}, "model": "auth.permission", "pk": 491}, {"fields": {"codename": "change_xblockasidesconfig", "name": "Can change x block asides config", "content_type": 163}, "model": "auth.permission", "pk": 492}, {"fields": {"codename": "delete_xblockasidesconfig", "name": "Can delete x block asides config", "content_type": 163}, "model": "auth.permission", "pk": 493}, {"fields": {"codename": "add_courseoverview", "name": "Can add course overview", "content_type": 164}, "model": "auth.permission", "pk": 494}, {"fields": {"codename": "change_courseoverview", "name": "Can change course overview", "content_type": 164}, "model": "auth.permission", "pk": 495}, {"fields": {"codename": "delete_courseoverview", "name": "Can delete course overview", "content_type": 164}, "model": "auth.permission", "pk": 496}, {"fields": {"codename": "add_courseoverviewtab", "name": "Can add course overview tab", "content_type": 165}, "model": "auth.permission", "pk": 497}, {"fields": {"codename": "change_courseoverviewtab", "name": "Can change course overview tab", "content_type": 165}, "model": "auth.permission", "pk": 498}, {"fields": {"codename": "delete_courseoverviewtab", "name": "Can delete course overview tab", "content_type": 165}, "model": "auth.permission", "pk": 499}, {"fields": {"codename": "add_coursestructure", "name": "Can add course structure", "content_type": 166}, "model": "auth.permission", "pk": 500}, {"fields": {"codename": "change_coursestructure", "name": "Can change course structure", "content_type": 166}, "model": "auth.permission", "pk": 501}, {"fields": {"codename": "delete_coursestructure", "name": "Can delete course structure", "content_type": 166}, "model": "auth.permission", "pk": 502}, {"fields": {"codename": "add_corsmodel", "name": "Can add cors model", "content_type": 167}, "model": "auth.permission", "pk": 503}, {"fields": {"codename": "change_corsmodel", "name": "Can change cors model", "content_type": 167}, "model": "auth.permission", "pk": 504}, {"fields": {"codename": "delete_corsmodel", "name": "Can delete cors model", "content_type": 167}, "model": "auth.permission", "pk": 505}, {"fields": {"codename": "add_xdomainproxyconfiguration", "name": "Can add x domain proxy configuration", "content_type": 168}, "model": "auth.permission", "pk": 506}, {"fields": {"codename": "change_xdomainproxyconfiguration", "name": "Can change x domain proxy configuration", "content_type": 168}, "model": "auth.permission", "pk": 507}, {"fields": {"codename": "delete_xdomainproxyconfiguration", "name": "Can delete x domain proxy configuration", "content_type": 168}, "model": "auth.permission", "pk": 508}, {"fields": {"codename": "add_creditprovider", "name": "Can add credit provider", "content_type": 169}, "model": "auth.permission", "pk": 509}, {"fields": {"codename": "change_creditprovider", "name": "Can change credit provider", "content_type": 169}, "model": "auth.permission", "pk": 510}, {"fields": {"codename": "delete_creditprovider", "name": "Can delete credit provider", "content_type": 169}, "model": "auth.permission", "pk": 511}, {"fields": {"codename": "add_creditcourse", "name": "Can add credit course", "content_type": 170}, "model": "auth.permission", "pk": 512}, {"fields": {"codename": "change_creditcourse", "name": "Can change credit course", "content_type": 170}, "model": "auth.permission", "pk": 513}, {"fields": {"codename": "delete_creditcourse", "name": "Can delete credit course", "content_type": 170}, "model": "auth.permission", "pk": 514}, {"fields": {"codename": "add_creditrequirement", "name": "Can add credit requirement", "content_type": 171}, "model": "auth.permission", "pk": 515}, {"fields": {"codename": "change_creditrequirement", "name": "Can change credit requirement", "content_type": 171}, "model": "auth.permission", "pk": 516}, {"fields": {"codename": "delete_creditrequirement", "name": "Can delete credit requirement", "content_type": 171}, "model": "auth.permission", "pk": 517}, {"fields": {"codename": "add_historicalcreditrequirementstatus", "name": "Can add historical credit requirement status", "content_type": 172}, "model": "auth.permission", "pk": 518}, {"fields": {"codename": "change_historicalcreditrequirementstatus", "name": "Can change historical credit requirement status", "content_type": 172}, "model": "auth.permission", "pk": 519}, {"fields": {"codename": "delete_historicalcreditrequirementstatus", "name": "Can delete historical credit requirement status", "content_type": 172}, "model": "auth.permission", "pk": 520}, {"fields": {"codename": "add_creditrequirementstatus", "name": "Can add credit requirement status", "content_type": 173}, "model": "auth.permission", "pk": 521}, {"fields": {"codename": "change_creditrequirementstatus", "name": "Can change credit requirement status", "content_type": 173}, "model": "auth.permission", "pk": 522}, {"fields": {"codename": "delete_creditrequirementstatus", "name": "Can delete credit requirement status", "content_type": 173}, "model": "auth.permission", "pk": 523}, {"fields": {"codename": "add_crediteligibility", "name": "Can add credit eligibility", "content_type": 174}, "model": "auth.permission", "pk": 524}, {"fields": {"codename": "change_crediteligibility", "name": "Can change credit eligibility", "content_type": 174}, "model": "auth.permission", "pk": 525}, {"fields": {"codename": "delete_crediteligibility", "name": "Can delete credit eligibility", "content_type": 174}, "model": "auth.permission", "pk": 526}, {"fields": {"codename": "add_historicalcreditrequest", "name": "Can add historical credit request", "content_type": 175}, "model": "auth.permission", "pk": 527}, {"fields": {"codename": "change_historicalcreditrequest", "name": "Can change historical credit request", "content_type": 175}, "model": "auth.permission", "pk": 528}, {"fields": {"codename": "delete_historicalcreditrequest", "name": "Can delete historical credit request", "content_type": 175}, "model": "auth.permission", "pk": 529}, {"fields": {"codename": "add_creditrequest", "name": "Can add credit request", "content_type": 176}, "model": "auth.permission", "pk": 530}, {"fields": {"codename": "change_creditrequest", "name": "Can change credit request", "content_type": 176}, "model": "auth.permission", "pk": 531}, {"fields": {"codename": "delete_creditrequest", "name": "Can delete credit request", "content_type": 176}, "model": "auth.permission", "pk": 532}, {"fields": {"codename": "add_courseteam", "name": "Can add course team", "content_type": 177}, "model": "auth.permission", "pk": 533}, {"fields": {"codename": "change_courseteam", "name": "Can change course team", "content_type": 177}, "model": "auth.permission", "pk": 534}, {"fields": {"codename": "delete_courseteam", "name": "Can delete course team", "content_type": 177}, "model": "auth.permission", "pk": 535}, {"fields": {"codename": "add_courseteammembership", "name": "Can add course team membership", "content_type": 178}, "model": "auth.permission", "pk": 536}, {"fields": {"codename": "change_courseteammembership", "name": "Can change course team membership", "content_type": 178}, "model": "auth.permission", "pk": 537}, {"fields": {"codename": "delete_courseteammembership", "name": "Can delete course team membership", "content_type": 178}, "model": "auth.permission", "pk": 538}, {"fields": {"codename": "add_xblockdisableconfig", "name": "Can add x block disable config", "content_type": 179}, "model": "auth.permission", "pk": 539}, {"fields": {"codename": "change_xblockdisableconfig", "name": "Can change x block disable config", "content_type": 179}, "model": "auth.permission", "pk": 540}, {"fields": {"codename": "delete_xblockdisableconfig", "name": "Can delete x block disable config", "content_type": 179}, "model": "auth.permission", "pk": 541}, {"fields": {"codename": "add_programsapiconfig", "name": "Can add programs api config", "content_type": 180}, "model": "auth.permission", "pk": 542}, {"fields": {"codename": "change_programsapiconfig", "name": "Can change programs api config", "content_type": 180}, "model": "auth.permission", "pk": 543}, {"fields": {"codename": "delete_programsapiconfig", "name": "Can delete programs api config", "content_type": 180}, "model": "auth.permission", "pk": 544}, {"fields": {"codename": "add_selfpacedconfiguration", "name": "Can add self paced configuration", "content_type": 181}, "model": "auth.permission", "pk": 545}, {"fields": {"codename": "change_selfpacedconfiguration", "name": "Can change self paced configuration", "content_type": 181}, "model": "auth.permission", "pk": 546}, {"fields": {"codename": "delete_selfpacedconfiguration", "name": "Can delete self paced configuration", "content_type": 181}, "model": "auth.permission", "pk": 547}, {"fields": {"codename": "add_kvstore", "name": "Can add kv store", "content_type": 182}, "model": "auth.permission", "pk": 548}, {"fields": {"codename": "change_kvstore", "name": "Can change kv store", "content_type": 182}, "model": "auth.permission", "pk": 549}, {"fields": {"codename": "delete_kvstore", "name": "Can delete kv store", "content_type": 182}, "model": "auth.permission", "pk": 550}, {"fields": {"codename": "add_badgeclass", "name": "Can add badge class", "content_type": 183}, "model": "auth.permission", "pk": 551}, {"fields": {"codename": "change_badgeclass", "name": "Can change badge class", "content_type": 183}, "model": "auth.permission", "pk": 552}, {"fields": {"codename": "delete_badgeclass", "name": "Can delete badge class", "content_type": 183}, "model": "auth.permission", "pk": 553}, {"fields": {"codename": "add_badgeassertion", "name": "Can add badge assertion", "content_type": 184}, "model": "auth.permission", "pk": 554}, {"fields": {"codename": "change_badgeassertion", "name": "Can change badge assertion", "content_type": 184}, "model": "auth.permission", "pk": 555}, {"fields": {"codename": "delete_badgeassertion", "name": "Can delete badge assertion", "content_type": 184}, "model": "auth.permission", "pk": 556}, {"fields": {"codename": "add_coursecompleteimageconfiguration", "name": "Can add course complete image configuration", "content_type": 185}, "model": "auth.permission", "pk": 557}, {"fields": {"codename": "change_coursecompleteimageconfiguration", "name": "Can change course complete image configuration", "content_type": 185}, "model": "auth.permission", "pk": 558}, {"fields": {"codename": "delete_coursecompleteimageconfiguration", "name": "Can delete course complete image configuration", "content_type": 185}, "model": "auth.permission", "pk": 559}, {"fields": {"codename": "add_studentitem", "name": "Can add student item", "content_type": 186}, "model": "auth.permission", "pk": 560}, {"fields": {"codename": "change_studentitem", "name": "Can change student item", "content_type": 186}, "model": "auth.permission", "pk": 561}, {"fields": {"codename": "delete_studentitem", "name": "Can delete student item", "content_type": 186}, "model": "auth.permission", "pk": 562}, {"fields": {"codename": "add_submission", "name": "Can add submission", "content_type": 187}, "model": "auth.permission", "pk": 563}, {"fields": {"codename": "change_submission", "name": "Can change submission", "content_type": 187}, "model": "auth.permission", "pk": 564}, {"fields": {"codename": "delete_submission", "name": "Can delete submission", "content_type": 187}, "model": "auth.permission", "pk": 565}, {"fields": {"codename": "add_score", "name": "Can add score", "content_type": 188}, "model": "auth.permission", "pk": 566}, {"fields": {"codename": "change_score", "name": "Can change score", "content_type": 188}, "model": "auth.permission", "pk": 567}, {"fields": {"codename": "delete_score", "name": "Can delete score", "content_type": 188}, "model": "auth.permission", "pk": 568}, {"fields": {"codename": "add_scoresummary", "name": "Can add score summary", "content_type": 189}, "model": "auth.permission", "pk": 569}, {"fields": {"codename": "change_scoresummary", "name": "Can change score summary", "content_type": 189}, "model": "auth.permission", "pk": 570}, {"fields": {"codename": "delete_scoresummary", "name": "Can delete score summary", "content_type": 189}, "model": "auth.permission", "pk": 571}, {"fields": {"codename": "add_rubric", "name": "Can add rubric", "content_type": 190}, "model": "auth.permission", "pk": 572}, {"fields": {"codename": "change_rubric", "name": "Can change rubric", "content_type": 190}, "model": "auth.permission", "pk": 573}, {"fields": {"codename": "delete_rubric", "name": "Can delete rubric", "content_type": 190}, "model": "auth.permission", "pk": 574}, {"fields": {"codename": "add_criterion", "name": "Can add criterion", "content_type": 191}, "model": "auth.permission", "pk": 575}, {"fields": {"codename": "change_criterion", "name": "Can change criterion", "content_type": 191}, "model": "auth.permission", "pk": 576}, {"fields": {"codename": "delete_criterion", "name": "Can delete criterion", "content_type": 191}, "model": "auth.permission", "pk": 577}, {"fields": {"codename": "add_criterionoption", "name": "Can add criterion option", "content_type": 192}, "model": "auth.permission", "pk": 578}, {"fields": {"codename": "change_criterionoption", "name": "Can change criterion option", "content_type": 192}, "model": "auth.permission", "pk": 579}, {"fields": {"codename": "delete_criterionoption", "name": "Can delete criterion option", "content_type": 192}, "model": "auth.permission", "pk": 580}, {"fields": {"codename": "add_assessment", "name": "Can add assessment", "content_type": 193}, "model": "auth.permission", "pk": 581}, {"fields": {"codename": "change_assessment", "name": "Can change assessment", "content_type": 193}, "model": "auth.permission", "pk": 582}, {"fields": {"codename": "delete_assessment", "name": "Can delete assessment", "content_type": 193}, "model": "auth.permission", "pk": 583}, {"fields": {"codename": "add_assessmentpart", "name": "Can add assessment part", "content_type": 194}, "model": "auth.permission", "pk": 584}, {"fields": {"codename": "change_assessmentpart", "name": "Can change assessment part", "content_type": 194}, "model": "auth.permission", "pk": 585}, {"fields": {"codename": "delete_assessmentpart", "name": "Can delete assessment part", "content_type": 194}, "model": "auth.permission", "pk": 586}, {"fields": {"codename": "add_assessmentfeedbackoption", "name": "Can add assessment feedback option", "content_type": 195}, "model": "auth.permission", "pk": 587}, {"fields": {"codename": "change_assessmentfeedbackoption", "name": "Can change assessment feedback option", "content_type": 195}, "model": "auth.permission", "pk": 588}, {"fields": {"codename": "delete_assessmentfeedbackoption", "name": "Can delete assessment feedback option", "content_type": 195}, "model": "auth.permission", "pk": 589}, {"fields": {"codename": "add_assessmentfeedback", "name": "Can add assessment feedback", "content_type": 196}, "model": "auth.permission", "pk": 590}, {"fields": {"codename": "change_assessmentfeedback", "name": "Can change assessment feedback", "content_type": 196}, "model": "auth.permission", "pk": 591}, {"fields": {"codename": "delete_assessmentfeedback", "name": "Can delete assessment feedback", "content_type": 196}, "model": "auth.permission", "pk": 592}, {"fields": {"codename": "add_peerworkflow", "name": "Can add peer workflow", "content_type": 197}, "model": "auth.permission", "pk": 593}, {"fields": {"codename": "change_peerworkflow", "name": "Can change peer workflow", "content_type": 197}, "model": "auth.permission", "pk": 594}, {"fields": {"codename": "delete_peerworkflow", "name": "Can delete peer workflow", "content_type": 197}, "model": "auth.permission", "pk": 595}, {"fields": {"codename": "add_peerworkflowitem", "name": "Can add peer workflow item", "content_type": 198}, "model": "auth.permission", "pk": 596}, {"fields": {"codename": "change_peerworkflowitem", "name": "Can change peer workflow item", "content_type": 198}, "model": "auth.permission", "pk": 597}, {"fields": {"codename": "delete_peerworkflowitem", "name": "Can delete peer workflow item", "content_type": 198}, "model": "auth.permission", "pk": 598}, {"fields": {"codename": "add_trainingexample", "name": "Can add training example", "content_type": 199}, "model": "auth.permission", "pk": 599}, {"fields": {"codename": "change_trainingexample", "name": "Can change training example", "content_type": 199}, "model": "auth.permission", "pk": 600}, {"fields": {"codename": "delete_trainingexample", "name": "Can delete training example", "content_type": 199}, "model": "auth.permission", "pk": 601}, {"fields": {"codename": "add_studenttrainingworkflow", "name": "Can add student training workflow", "content_type": 200}, "model": "auth.permission", "pk": 602}, {"fields": {"codename": "change_studenttrainingworkflow", "name": "Can change student training workflow", "content_type": 200}, "model": "auth.permission", "pk": 603}, {"fields": {"codename": "delete_studenttrainingworkflow", "name": "Can delete student training workflow", "content_type": 200}, "model": "auth.permission", "pk": 604}, {"fields": {"codename": "add_studenttrainingworkflowitem", "name": "Can add student training workflow item", "content_type": 201}, "model": "auth.permission", "pk": 605}, {"fields": {"codename": "change_studenttrainingworkflowitem", "name": "Can change student training workflow item", "content_type": 201}, "model": "auth.permission", "pk": 606}, {"fields": {"codename": "delete_studenttrainingworkflowitem", "name": "Can delete student training workflow item", "content_type": 201}, "model": "auth.permission", "pk": 607}, {"fields": {"codename": "add_aiclassifierset", "name": "Can add ai classifier set", "content_type": 202}, "model": "auth.permission", "pk": 608}, {"fields": {"codename": "change_aiclassifierset", "name": "Can change ai classifier set", "content_type": 202}, "model": "auth.permission", "pk": 609}, {"fields": {"codename": "delete_aiclassifierset", "name": "Can delete ai classifier set", "content_type": 202}, "model": "auth.permission", "pk": 610}, {"fields": {"codename": "add_aiclassifier", "name": "Can add ai classifier", "content_type": 203}, "model": "auth.permission", "pk": 611}, {"fields": {"codename": "change_aiclassifier", "name": "Can change ai classifier", "content_type": 203}, "model": "auth.permission", "pk": 612}, {"fields": {"codename": "delete_aiclassifier", "name": "Can delete ai classifier", "content_type": 203}, "model": "auth.permission", "pk": 613}, {"fields": {"codename": "add_aitrainingworkflow", "name": "Can add ai training workflow", "content_type": 204}, "model": "auth.permission", "pk": 614}, {"fields": {"codename": "change_aitrainingworkflow", "name": "Can change ai training workflow", "content_type": 204}, "model": "auth.permission", "pk": 615}, {"fields": {"codename": "delete_aitrainingworkflow", "name": "Can delete ai training workflow", "content_type": 204}, "model": "auth.permission", "pk": 616}, {"fields": {"codename": "add_aigradingworkflow", "name": "Can add ai grading workflow", "content_type": 205}, "model": "auth.permission", "pk": 617}, {"fields": {"codename": "change_aigradingworkflow", "name": "Can change ai grading workflow", "content_type": 205}, "model": "auth.permission", "pk": 618}, {"fields": {"codename": "delete_aigradingworkflow", "name": "Can delete ai grading workflow", "content_type": 205}, "model": "auth.permission", "pk": 619}, {"fields": {"codename": "add_assessmentworkflow", "name": "Can add assessment workflow", "content_type": 206}, "model": "auth.permission", "pk": 620}, {"fields": {"codename": "change_assessmentworkflow", "name": "Can change assessment workflow", "content_type": 206}, "model": "auth.permission", "pk": 621}, {"fields": {"codename": "delete_assessmentworkflow", "name": "Can delete assessment workflow", "content_type": 206}, "model": "auth.permission", "pk": 622}, {"fields": {"codename": "add_assessmentworkflowstep", "name": "Can add assessment workflow step", "content_type": 207}, "model": "auth.permission", "pk": 623}, {"fields": {"codename": "change_assessmentworkflowstep", "name": "Can change assessment workflow step", "content_type": 207}, "model": "auth.permission", "pk": 624}, {"fields": {"codename": "delete_assessmentworkflowstep", "name": "Can delete assessment workflow step", "content_type": 207}, "model": "auth.permission", "pk": 625}, {"fields": {"codename": "add_assessmentworkflowcancellation", "name": "Can add assessment workflow cancellation", "content_type": 208}, "model": "auth.permission", "pk": 626}, {"fields": {"codename": "change_assessmentworkflowcancellation", "name": "Can change assessment workflow cancellation", "content_type": 208}, "model": "auth.permission", "pk": 627}, {"fields": {"codename": "delete_assessmentworkflowcancellation", "name": "Can delete assessment workflow cancellation", "content_type": 208}, "model": "auth.permission", "pk": 628}, {"fields": {"codename": "add_profile", "name": "Can add profile", "content_type": 209}, "model": "auth.permission", "pk": 629}, {"fields": {"codename": "change_profile", "name": "Can change profile", "content_type": 209}, "model": "auth.permission", "pk": 630}, {"fields": {"codename": "delete_profile", "name": "Can delete profile", "content_type": 209}, "model": "auth.permission", "pk": 631}, {"fields": {"codename": "add_video", "name": "Can add video", "content_type": 210}, "model": "auth.permission", "pk": 632}, {"fields": {"codename": "change_video", "name": "Can change video", "content_type": 210}, "model": "auth.permission", "pk": 633}, {"fields": {"codename": "delete_video", "name": "Can delete video", "content_type": 210}, "model": "auth.permission", "pk": 634}, {"fields": {"codename": "add_coursevideo", "name": "Can add course video", "content_type": 211}, "model": "auth.permission", "pk": 635}, {"fields": {"codename": "change_coursevideo", "name": "Can change course video", "content_type": 211}, "model": "auth.permission", "pk": 636}, {"fields": {"codename": "delete_coursevideo", "name": "Can delete course video", "content_type": 211}, "model": "auth.permission", "pk": 637}, {"fields": {"codename": "add_encodedvideo", "name": "Can add encoded video", "content_type": 212}, "model": "auth.permission", "pk": 638}, {"fields": {"codename": "change_encodedvideo", "name": "Can change encoded video", "content_type": 212}, "model": "auth.permission", "pk": 639}, {"fields": {"codename": "delete_encodedvideo", "name": "Can delete encoded video", "content_type": 212}, "model": "auth.permission", "pk": 640}, {"fields": {"codename": "add_subtitle", "name": "Can add subtitle", "content_type": 213}, "model": "auth.permission", "pk": 641}, {"fields": {"codename": "change_subtitle", "name": "Can change subtitle", "content_type": 213}, "model": "auth.permission", "pk": 642}, {"fields": {"codename": "delete_subtitle", "name": "Can delete subtitle", "content_type": 213}, "model": "auth.permission", "pk": 643}, {"fields": {"codename": "add_milestone", "name": "Can add milestone", "content_type": 214}, "model": "auth.permission", "pk": 644}, {"fields": {"codename": "change_milestone", "name": "Can change milestone", "content_type": 214}, "model": "auth.permission", "pk": 645}, {"fields": {"codename": "delete_milestone", "name": "Can delete milestone", "content_type": 214}, "model": "auth.permission", "pk": 646}, {"fields": {"codename": "add_milestonerelationshiptype", "name": "Can add milestone relationship type", "content_type": 215}, "model": "auth.permission", "pk": 647}, {"fields": {"codename": "change_milestonerelationshiptype", "name": "Can change milestone relationship type", "content_type": 215}, "model": "auth.permission", "pk": 648}, {"fields": {"codename": "delete_milestonerelationshiptype", "name": "Can delete milestone relationship type", "content_type": 215}, "model": "auth.permission", "pk": 649}, {"fields": {"codename": "add_coursemilestone", "name": "Can add course milestone", "content_type": 216}, "model": "auth.permission", "pk": 650}, {"fields": {"codename": "change_coursemilestone", "name": "Can change course milestone", "content_type": 216}, "model": "auth.permission", "pk": 651}, {"fields": {"codename": "delete_coursemilestone", "name": "Can delete course milestone", "content_type": 216}, "model": "auth.permission", "pk": 652}, {"fields": {"codename": "add_coursecontentmilestone", "name": "Can add course content milestone", "content_type": 217}, "model": "auth.permission", "pk": 653}, {"fields": {"codename": "change_coursecontentmilestone", "name": "Can change course content milestone", "content_type": 217}, "model": "auth.permission", "pk": 654}, {"fields": {"codename": "delete_coursecontentmilestone", "name": "Can delete course content milestone", "content_type": 217}, "model": "auth.permission", "pk": 655}, {"fields": {"codename": "add_usermilestone", "name": "Can add user milestone", "content_type": 218}, "model": "auth.permission", "pk": 656}, {"fields": {"codename": "change_usermilestone", "name": "Can change user milestone", "content_type": 218}, "model": "auth.permission", "pk": 657}, {"fields": {"codename": "delete_usermilestone", "name": "Can delete user milestone", "content_type": 218}, "model": "auth.permission", "pk": 658}, {"fields": {"codename": "add_proctoredexam", "name": "Can add proctored exam", "content_type": 219}, "model": "auth.permission", "pk": 659}, {"fields": {"codename": "change_proctoredexam", "name": "Can change proctored exam", "content_type": 219}, "model": "auth.permission", "pk": 660}, {"fields": {"codename": "delete_proctoredexam", "name": "Can delete proctored exam", "content_type": 219}, "model": "auth.permission", "pk": 661}, {"fields": {"codename": "add_proctoredexamreviewpolicy", "name": "Can add Proctored exam review policy", "content_type": 220}, "model": "auth.permission", "pk": 662}, {"fields": {"codename": "change_proctoredexamreviewpolicy", "name": "Can change Proctored exam review policy", "content_type": 220}, "model": "auth.permission", "pk": 663}, {"fields": {"codename": "delete_proctoredexamreviewpolicy", "name": "Can delete Proctored exam review policy", "content_type": 220}, "model": "auth.permission", "pk": 664}, {"fields": {"codename": "add_proctoredexamreviewpolicyhistory", "name": "Can add proctored exam review policy history", "content_type": 221}, "model": "auth.permission", "pk": 665}, {"fields": {"codename": "change_proctoredexamreviewpolicyhistory", "name": "Can change proctored exam review policy history", "content_type": 221}, "model": "auth.permission", "pk": 666}, {"fields": {"codename": "delete_proctoredexamreviewpolicyhistory", "name": "Can delete proctored exam review policy history", "content_type": 221}, "model": "auth.permission", "pk": 667}, {"fields": {"codename": "add_proctoredexamstudentattempt", "name": "Can add proctored exam attempt", "content_type": 222}, "model": "auth.permission", "pk": 668}, {"fields": {"codename": "change_proctoredexamstudentattempt", "name": "Can change proctored exam attempt", "content_type": 222}, "model": "auth.permission", "pk": 669}, {"fields": {"codename": "delete_proctoredexamstudentattempt", "name": "Can delete proctored exam attempt", "content_type": 222}, "model": "auth.permission", "pk": 670}, {"fields": {"codename": "add_proctoredexamstudentattempthistory", "name": "Can add proctored exam attempt history", "content_type": 223}, "model": "auth.permission", "pk": 671}, {"fields": {"codename": "change_proctoredexamstudentattempthistory", "name": "Can change proctored exam attempt history", "content_type": 223}, "model": "auth.permission", "pk": 672}, {"fields": {"codename": "delete_proctoredexamstudentattempthistory", "name": "Can delete proctored exam attempt history", "content_type": 223}, "model": "auth.permission", "pk": 673}, {"fields": {"codename": "add_proctoredexamstudentallowance", "name": "Can add proctored allowance", "content_type": 224}, "model": "auth.permission", "pk": 674}, {"fields": {"codename": "change_proctoredexamstudentallowance", "name": "Can change proctored allowance", "content_type": 224}, "model": "auth.permission", "pk": 675}, {"fields": {"codename": "delete_proctoredexamstudentallowance", "name": "Can delete proctored allowance", "content_type": 224}, "model": "auth.permission", "pk": 676}, {"fields": {"codename": "add_proctoredexamstudentallowancehistory", "name": "Can add proctored allowance history", "content_type": 225}, "model": "auth.permission", "pk": 677}, {"fields": {"codename": "change_proctoredexamstudentallowancehistory", "name": "Can change proctored allowance history", "content_type": 225}, "model": "auth.permission", "pk": 678}, {"fields": {"codename": "delete_proctoredexamstudentallowancehistory", "name": "Can delete proctored allowance history", "content_type": 225}, "model": "auth.permission", "pk": 679}, {"fields": {"codename": "add_proctoredexamsoftwaresecurereview", "name": "Can add Proctored exam software secure review", "content_type": 226}, "model": "auth.permission", "pk": 680}, {"fields": {"codename": "change_proctoredexamsoftwaresecurereview", "name": "Can change Proctored exam software secure review", "content_type": 226}, "model": "auth.permission", "pk": 681}, {"fields": {"codename": "delete_proctoredexamsoftwaresecurereview", "name": "Can delete Proctored exam software secure review", "content_type": 226}, "model": "auth.permission", "pk": 682}, {"fields": {"codename": "add_proctoredexamsoftwaresecurereviewhistory", "name": "Can add Proctored exam review archive", "content_type": 227}, "model": "auth.permission", "pk": 683}, {"fields": {"codename": "change_proctoredexamsoftwaresecurereviewhistory", "name": "Can change Proctored exam review archive", "content_type": 227}, "model": "auth.permission", "pk": 684}, {"fields": {"codename": "delete_proctoredexamsoftwaresecurereviewhistory", "name": "Can delete Proctored exam review archive", "content_type": 227}, "model": "auth.permission", "pk": 685}, {"fields": {"codename": "add_proctoredexamsoftwaresecurecomment", "name": "Can add proctored exam software secure comment", "content_type": 228}, "model": "auth.permission", "pk": 686}, {"fields": {"codename": "change_proctoredexamsoftwaresecurecomment", "name": "Can change proctored exam software secure comment", "content_type": 228}, "model": "auth.permission", "pk": 687}, {"fields": {"codename": "delete_proctoredexamsoftwaresecurecomment", "name": "Can delete proctored exam software secure comment", "content_type": 228}, "model": "auth.permission", "pk": 688}, {"fields": {"codename": "add_organization", "name": "Can add organization", "content_type": 229}, "model": "auth.permission", "pk": 689}, {"fields": {"codename": "change_organization", "name": "Can change organization", "content_type": 229}, "model": "auth.permission", "pk": 690}, {"fields": {"codename": "delete_organization", "name": "Can delete organization", "content_type": 229}, "model": "auth.permission", "pk": 691}, {"fields": {"codename": "add_organizationcourse", "name": "Can add Link Course", "content_type": 230}, "model": "auth.permission", "pk": 692}, {"fields": {"codename": "change_organizationcourse", "name": "Can change Link Course", "content_type": 230}, "model": "auth.permission", "pk": 693}, {"fields": {"codename": "delete_organizationcourse", "name": "Can delete Link Course", "content_type": 230}, "model": "auth.permission", "pk": 694}, {"fields": {"username": "ecommerce_worker", "first_name": "", "last_name": "", "is_active": true, "is_superuser": false, "is_staff": false, "last_login": null, "groups": [], "user_permissions": [], "password": "!ojnVYsHXFDlwnoQ4vPsX8OlY8fbCIDyZGMjPMsXD", "email": "ecommerce_worker@fake.email", "date_joined": "2015-11-20T03:58:15.621Z"}, "model": "auth.user", "pk": 1}, {"fields": {"change_date": "2015-11-20T03:59:22.004Z", "changed_by": null, "enabled": true}, "model": "util.ratelimitconfiguration", "pk": 1}, {"fields": {"change_date": "2015-11-20T03:58:14.306Z", "changed_by": null, "configuration": "{\"default\": {\"accomplishment_class_append\": \"accomplishment-certificate\", \"platform_name\": \"Your Platform Name Here\", \"logo_src\": \"/static/certificates/images/logo.png\", \"logo_url\": \"http://www.example.com\", \"company_verified_certificate_url\": \"http://www.example.com/verified-certificate\", \"company_privacy_url\": \"http://www.example.com/privacy-policy\", \"company_tos_url\": \"http://www.example.com/terms-service\", \"company_about_url\": \"http://www.example.com/about-us\"}, \"verified\": {\"certificate_type\": \"Verified\", \"certificate_title\": \"Verified Certificate of Achievement\"}, \"honor\": {\"certificate_type\": \"Honor Code\", \"certificate_title\": \"Certificate of Achievement\"}}", "enabled": false}, "model": "certificates.certificatehtmlviewconfiguration", "pk": 1}, {"fields": {"change_date": "2015-11-20T03:58:21.575Z", "changed_by": null, "enabled": true, "released_languages": ""}, "model": "dark_lang.darklangconfig", "pk": 1}] \ No newline at end of file diff --git a/common/test/db_cache/bok_choy_migrations_data.sql b/common/test/db_cache/bok_choy_migrations_data.sql index 12826204fcee..0d4db2d66cbe 100644 --- a/common/test/db_cache/bok_choy_migrations_data.sql +++ b/common/test/db_cache/bok_choy_migrations_data.sql @@ -21,7 +21,7 @@ LOCK TABLES `django_migrations` WRITE; /*!40000 ALTER TABLE `django_migrations` DISABLE KEYS */; -INSERT INTO `django_migrations` VALUES (1,'contenttypes','0001_initial','2015-11-18 15:37:03.679215'),(2,'auth','0001_initial','2015-11-18 15:37:04.239453'),(3,'admin','0001_initial','2015-11-18 15:37:04.375156'),(4,'assessment','0001_initial','2015-11-18 15:37:09.037208'),(5,'contenttypes','0002_remove_content_type_name','2015-11-18 15:37:09.345424'),(6,'auth','0002_alter_permission_name_max_length','2015-11-18 15:37:09.479742'),(7,'auth','0003_alter_user_email_max_length','2015-11-18 15:37:09.677049'),(8,'auth','0004_alter_user_username_opts','2015-11-18 15:37:09.805606'),(9,'auth','0005_alter_user_last_login_null','2015-11-18 15:37:09.949394'),(10,'auth','0006_require_contenttypes_0002','2015-11-18 15:37:09.978283'),(11,'branding','0001_initial','2015-11-18 15:37:10.295010'),(12,'bulk_email','0001_initial','2015-11-18 15:37:10.849873'),(13,'bulk_email','0002_data__load_course_email_template','2015-11-18 15:37:10.939652'),(14,'certificates','0001_initial','2015-11-18 15:37:12.698538'),(15,'certificates','0002_data__certificatehtmlviewconfiguration_data','2015-11-18 15:37:12.746221'),(16,'certificates','0003_data__default_modes','2015-11-18 15:37:13.182516'),(17,'commerce','0001_data__add_ecommerce_service_user','2015-11-18 15:37:13.269990'),(18,'cors_csrf','0001_initial','2015-11-18 15:37:13.459604'),(19,'course_action_state','0001_initial','2015-11-18 15:37:14.011267'),(20,'course_groups','0001_initial','2015-11-18 15:37:15.487063'),(21,'course_modes','0001_initial','2015-11-18 15:37:15.719347'),(22,'course_overviews','0001_initial','2015-11-18 15:37:15.932886'),(23,'course_structures','0001_initial','2015-11-18 15:37:16.000954'),(24,'courseware','0001_initial','2015-11-18 15:37:18.771429'),(25,'credit','0001_initial','2015-11-18 15:37:21.519361'),(26,'dark_lang','0001_initial','2015-11-18 15:37:21.846133'),(27,'dark_lang','0002_data__enable_on_install','2015-11-18 15:37:21.995633'),(28,'default','0001_initial','2015-11-18 15:37:23.147337'),(29,'default','0002_add_related_name','2015-11-18 15:37:23.421429'),(30,'default','0003_alter_email_max_length','2015-11-18 15:37:23.512312'),(31,'django_comment_common','0001_initial','2015-11-18 15:37:24.320730'),(32,'django_notify','0001_initial','2015-11-18 15:37:25.685195'),(33,'django_openid_auth','0001_initial','2015-11-18 15:37:26.276837'),(34,'edx_proctoring','0001_initial','2015-11-18 15:37:30.965630'),(35,'edxval','0001_initial','2015-11-18 15:37:32.899299'),(36,'edxval','0002_data__default_profiles','2015-11-18 15:37:32.962490'),(37,'embargo','0001_initial','2015-11-18 15:37:34.781531'),(38,'embargo','0002_data__add_countries','2015-11-18 15:37:36.006428'),(39,'external_auth','0001_initial','2015-11-18 15:37:36.857447'),(40,'foldit','0001_initial','2015-11-18 15:37:38.106002'),(41,'instructor_task','0001_initial','2015-11-18 15:37:38.670378'),(42,'licenses','0001_initial','2015-11-18 15:37:39.225872'),(43,'lms_xblock','0001_initial','2015-11-18 15:37:39.674372'),(44,'milestones','0001_initial','2015-11-18 15:37:41.240336'),(45,'milestones','0002_data__seed_relationship_types','2015-11-18 15:37:41.287383'),(46,'mobile_api','0001_initial','2015-11-18 15:37:41.822343'),(47,'notes','0001_initial','2015-11-18 15:37:42.381389'),(48,'oauth2','0001_initial','2015-11-18 15:37:45.638217'),(49,'oauth2_provider','0001_initial','2015-11-18 15:37:46.173938'),(50,'oauth_provider','0001_initial','2015-11-18 15:37:47.398936'),(51,'organizations','0001_initial','2015-11-18 15:37:47.863329'),(52,'programs','0001_initial','2015-11-18 15:37:48.427080'),(53,'psychometrics','0001_initial','2015-11-18 15:37:48.987109'),(54,'self_paced','0001_initial','2015-11-18 15:37:49.523078'),(55,'sessions','0001_initial','2015-11-18 15:37:49.646106'),(56,'student','0001_initial','2015-11-18 15:38:05.543390'),(57,'shoppingcart','0001_initial','2015-11-18 15:38:21.727512'),(58,'sites','0001_initial','2015-11-18 15:38:21.837391'),(59,'splash','0001_initial','2015-11-18 15:38:23.244678'),(60,'status','0001_initial','2015-11-18 15:38:24.981737'),(61,'submissions','0001_initial','2015-11-18 15:38:26.499689'),(62,'survey','0001_initial','2015-11-18 15:38:28.962457'),(63,'teams','0001_initial','2015-11-18 15:38:31.641489'),(64,'third_party_auth','0001_initial','2015-11-18 15:38:35.861826'),(65,'track','0001_initial','2015-11-18 15:38:35.952939'),(66,'user_api','0001_initial','2015-11-18 15:38:42.846323'),(67,'util','0001_initial','2015-11-18 15:38:43.780691'),(68,'util','0002_data__default_rate_limit_config','2015-11-18 15:38:43.844470'),(69,'verify_student','0001_initial','2015-11-18 15:39:02.098134'),(70,'wiki','0001_initial','2015-11-18 15:39:50.801336'),(71,'workflow','0001_initial','2015-11-18 15:39:51.336698'),(72,'xblock_django','0001_initial','2015-11-18 15:39:52.487567'),(73,'contentstore','0001_initial','2015-11-18 15:40:36.154872'),(74,'course_creators','0001_initial','2015-11-18 15:40:36.715711'),(75,'xblock_config','0001_initial','2015-11-18 15:40:38.167185'); +INSERT INTO `django_migrations` VALUES (1,'contenttypes','0001_initial','2015-11-20 03:58:09.368524'),(2,'auth','0001_initial','2015-11-20 03:58:09.659738'),(3,'admin','0001_initial','2015-11-20 03:58:09.746550'),(4,'assessment','0001_initial','2015-11-20 03:58:13.071977'),(5,'contenttypes','0002_remove_content_type_name','2015-11-20 03:58:13.229291'),(6,'auth','0002_alter_permission_name_max_length','2015-11-20 03:58:13.285517'),(7,'auth','0003_alter_user_email_max_length','2015-11-20 03:58:13.335628'),(8,'auth','0004_alter_user_username_opts','2015-11-20 03:58:13.365042'),(9,'auth','0005_alter_user_last_login_null','2015-11-20 03:58:13.431692'),(10,'auth','0006_require_contenttypes_0002','2015-11-20 03:58:13.438038'),(11,'certificates','0001_initial','2015-11-20 03:58:14.292352'),(12,'certificates','0002_data__certificatehtmlviewconfiguration_data','2015-11-20 03:58:14.312191'),(13,'certificates','0003_data__default_modes','2015-11-20 03:58:14.386829'),(14,'badges','0001_initial','2015-11-20 03:58:14.727409'),(15,'badges','0002_data__migrate_assertions','2015-11-20 03:58:14.775762'),(16,'branding','0001_initial','2015-11-20 03:58:14.940215'),(17,'bulk_email','0001_initial','2015-11-20 03:58:15.337493'),(18,'bulk_email','0002_data__load_course_email_template','2015-11-20 03:58:15.401633'),(19,'certificates','0004_schema__remove_badges','2015-11-20 03:58:15.606317'),(20,'commerce','0001_data__add_ecommerce_service_user','2015-11-20 03:58:15.634087'),(21,'cors_csrf','0001_initial','2015-11-20 03:58:15.731634'),(22,'course_action_state','0001_initial','2015-11-20 03:58:16.019106'),(23,'course_groups','0001_initial','2015-11-20 03:58:17.057577'),(24,'course_modes','0001_initial','2015-11-20 03:58:17.201537'),(25,'course_overviews','0001_initial','2015-11-20 03:58:17.298037'),(26,'course_structures','0001_initial','2015-11-20 03:58:17.337568'),(27,'courseware','0001_initial','2015-11-20 03:58:19.359709'),(28,'credit','0001_initial','2015-11-20 03:58:21.398987'),(29,'dark_lang','0001_initial','2015-11-20 03:58:21.556640'),(30,'dark_lang','0002_data__enable_on_install','2015-11-20 03:58:21.585328'),(31,'default','0001_initial','2015-11-20 03:58:22.089053'),(32,'default','0002_add_related_name','2015-11-20 03:58:22.254370'),(33,'default','0003_alter_email_max_length','2015-11-20 03:58:22.328842'),(34,'django_comment_common','0001_initial','2015-11-20 03:58:22.790885'),(35,'django_notify','0001_initial','2015-11-20 03:58:23.645875'),(36,'django_openid_auth','0001_initial','2015-11-20 03:58:23.959222'),(37,'edx_proctoring','0001_initial','2015-11-20 03:58:27.615700'),(38,'edxval','0001_initial','2015-11-20 03:58:29.003257'),(39,'edxval','0002_data__default_profiles','2015-11-20 03:58:29.044698'),(40,'embargo','0001_initial','2015-11-20 03:58:29.992344'),(41,'embargo','0002_data__add_countries','2015-11-20 03:58:30.502644'),(42,'external_auth','0001_initial','2015-11-20 03:58:31.124291'),(43,'foldit','0001_initial','2015-11-20 03:58:32.069377'),(44,'instructor_task','0001_initial','2015-11-20 03:58:32.452785'),(45,'licenses','0001_initial','2015-11-20 03:58:32.807565'),(46,'lms_xblock','0001_initial','2015-11-20 03:58:33.111775'),(47,'milestones','0001_initial','2015-11-20 03:58:34.203476'),(48,'milestones','0002_data__seed_relationship_types','2015-11-20 03:58:34.241704'),(49,'mobile_api','0001_initial','2015-11-20 03:58:34.558943'),(50,'notes','0001_initial','2015-11-20 03:58:34.970037'),(51,'oauth2','0001_initial','2015-11-20 03:58:37.693187'),(52,'oauth2_provider','0001_initial','2015-11-20 03:58:38.010637'),(53,'oauth_provider','0001_initial','2015-11-20 03:58:38.888032'),(54,'organizations','0001_initial','2015-11-20 03:58:39.133025'),(55,'organizations','0002_auto_20151119_2048','2015-11-20 03:58:39.178554'),(56,'programs','0001_initial','2015-11-20 03:58:39.552352'),(57,'programs','0002_programsapiconfig_cache_ttl','2015-11-20 03:58:39.945670'),(58,'psychometrics','0001_initial','2015-11-20 03:58:40.408258'),(59,'self_paced','0001_initial','2015-11-20 03:58:40.887405'),(60,'sessions','0001_initial','2015-11-20 03:58:40.961522'),(61,'student','0001_initial','2015-11-20 03:58:53.330542'),(62,'shoppingcart','0001_initial','2015-11-20 03:59:06.105155'),(63,'sites','0001_initial','2015-11-20 03:59:06.170737'),(64,'splash','0001_initial','2015-11-20 03:59:06.979616'),(65,'status','0001_initial','2015-11-20 03:59:08.403415'),(66,'submissions','0001_initial','2015-11-20 03:59:09.307549'),(67,'survey','0001_initial','2015-11-20 03:59:11.005609'),(68,'teams','0001_initial','2015-11-20 03:59:12.867020'),(69,'third_party_auth','0001_initial','2015-11-20 03:59:16.173372'),(70,'track','0001_initial','2015-11-20 03:59:16.246684'),(71,'user_api','0001_initial','2015-11-20 03:59:21.308311'),(72,'util','0001_initial','2015-11-20 03:59:21.958312'),(73,'util','0002_data__default_rate_limit_config','2015-11-20 03:59:22.022093'),(74,'verify_student','0001_initial','2015-11-20 03:59:31.063750'),(75,'wiki','0001_initial','2015-11-20 03:59:55.197507'),(76,'workflow','0001_initial','2015-11-20 03:59:55.550654'),(77,'xblock_django','0001_initial','2015-11-20 03:59:56.349274'); /*!40000 ALTER TABLE `django_migrations` ENABLE KEYS */; UNLOCK TABLES; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; @@ -34,4 +34,4 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2015-11-18 15:40:53 +-- Dump completed on 2015-11-20 4:00:07 diff --git a/common/test/db_cache/bok_choy_schema.sql b/common/test/db_cache/bok_choy_schema.sql index 2c83c1836c9a..783d7d2f27fd 100644 --- a/common/test/db_cache/bok_choy_schema.sql +++ b/common/test/db_cache/bok_choy_schema.sql @@ -386,7 +386,7 @@ CREATE TABLE `auth_permission` ( PRIMARY KEY (`id`), UNIQUE KEY `content_type_id` (`content_type_id`,`codename`), CONSTRAINT `auth__content_type_id_508cf46651277a81_fk_django_content_type_id` FOREIGN KEY (`content_type_id`) REFERENCES `django_content_type` (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=704 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=695 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `auth_registration`; /*!40101 SET @saved_cs_client = @@character_set_client */; @@ -480,6 +480,54 @@ CREATE TABLE `auth_userprofile` ( CONSTRAINT `auth_userprofile_user_id_4c194f9b5650ad70_fk_auth_user_id` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `badges_badgeassertion`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `badges_badgeassertion` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `data` longtext NOT NULL, + `backend` varchar(50) NOT NULL, + `image_url` varchar(200) NOT NULL, + `assertion_url` varchar(200) NOT NULL, + `badge_class_id` int(11) NOT NULL, + `user_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `badges_badgeassertion_c389e456` (`badge_class_id`), + KEY `badges_badgeassertion_e8701ad4` (`user_id`), + CONSTRAINT `badges_b_badge_class_id_3a4a16cb833201e8_fk_badges_badgeclass_id` FOREIGN KEY (`badge_class_id`) REFERENCES `badges_badgeclass` (`id`), + CONSTRAINT `badges_badgeassertion_user_id_14233cdefee1055a_fk_auth_user_id` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `badges_badgeclass`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `badges_badgeclass` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `slug` varchar(255) NOT NULL, + `issuing_component` varchar(50) NOT NULL, + `display_name` varchar(255) NOT NULL, + `course_id` varchar(255) NOT NULL, + `description` longtext NOT NULL, + `criteria` longtext NOT NULL, + `mode` varchar(100) NOT NULL, + `image` varchar(100) NOT NULL, + PRIMARY KEY (`id`), + KEY `badges_badgeclass_2dbcba41` (`slug`), + KEY `badges_badgeclass_a57403f2` (`issuing_component`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `badges_coursecompleteimageconfiguration`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `badges_coursecompleteimageconfiguration` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `mode` varchar(125) NOT NULL, + `icon` varchar(100) NOT NULL, + `default` tinyint(1) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `mode` (`mode`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `branding_brandingapiconfig`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; @@ -597,33 +645,6 @@ CREATE TABLE `celery_tasksetmeta` ( KEY `celery_tasksetmeta_662f707d` (`hidden`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -DROP TABLE IF EXISTS `certificates_badgeassertion`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `certificates_badgeassertion` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `course_id` varchar(255) NOT NULL, - `mode` varchar(100) NOT NULL, - `data` longtext NOT NULL, - `user_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `certificates_badgeassertion_course_id_4dc2a23e1c0cd3ff_uniq` (`course_id`,`user_id`,`mode`), - KEY `certificates_badgeassert_user_id_65bbbec450cd344_fk_auth_user_id` (`user_id`), - CONSTRAINT `certificates_badgeassert_user_id_65bbbec450cd344_fk_auth_user_id` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; -DROP TABLE IF EXISTS `certificates_badgeimageconfiguration`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `certificates_badgeimageconfiguration` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `mode` varchar(125) NOT NULL, - `icon` varchar(100) NOT NULL, - `default` tinyint(1) NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `mode` (`mode`) -) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `certificates_certificategenerationconfiguration`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; @@ -770,33 +791,6 @@ CREATE TABLE `certificates_generatedcertificate` ( CONSTRAINT `certificates_generatedc_user_id_77ed5f7a53121815_fk_auth_user_id` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -DROP TABLE IF EXISTS `contentstore_pushnotificationconfig`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `contentstore_pushnotificationconfig` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `change_date` datetime(6) NOT NULL, - `enabled` tinyint(1) NOT NULL, - `changed_by_id` int(11) DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `contentstore_push_changed_by_id_72c47af098f7f8b1_fk_auth_user_id` (`changed_by_id`), - CONSTRAINT `contentstore_push_changed_by_id_72c47af098f7f8b1_fk_auth_user_id` FOREIGN KEY (`changed_by_id`) REFERENCES `auth_user` (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; -DROP TABLE IF EXISTS `contentstore_videouploadconfig`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `contentstore_videouploadconfig` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `change_date` datetime(6) NOT NULL, - `enabled` tinyint(1) NOT NULL, - `profile_whitelist` longtext NOT NULL, - `changed_by_id` int(11) DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `contentstore_vide_changed_by_id_17a489d0a46d9a4b_fk_auth_user_id` (`changed_by_id`), - CONSTRAINT `contentstore_vide_changed_by_id_17a489d0a46d9a4b_fk_auth_user_id` FOREIGN KEY (`changed_by_id`) REFERENCES `auth_user` (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `cors_csrf_xdomainproxyconfiguration`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; @@ -847,20 +841,6 @@ CREATE TABLE `course_action_state_coursererunstate` ( CONSTRAINT `course_action_s_updated_user_id_4fab18012332c9a4_fk_auth_user_id` FOREIGN KEY (`updated_user_id`) REFERENCES `auth_user` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -DROP TABLE IF EXISTS `course_creators_coursecreator`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `course_creators_coursecreator` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `state_changed` datetime(6) NOT NULL, - `state` varchar(24) NOT NULL, - `note` varchar(512) NOT NULL, - `user_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `user_id` (`user_id`), - CONSTRAINT `course_creators_coursec_user_id_46ea06ad28f0be3b_fk_auth_user_id` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `course_groups_cohortmembership`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; @@ -1445,7 +1425,7 @@ CREATE TABLE `django_content_type` ( `model` varchar(100) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `django_content_type_app_label_45f3b1d93ec8c61c_uniq` (`app_label`,`model`) -) ENGINE=InnoDB AUTO_INCREMENT=234 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=231 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `django_migrations`; /*!40101 SET @saved_cs_client = @@character_set_client */; @@ -1456,7 +1436,7 @@ CREATE TABLE `django_migrations` ( `name` varchar(255) NOT NULL, `applied` datetime(6) NOT NULL, PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=76 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=78 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `django_openid_auth_association`; /*!40101 SET @saved_cs_client = @@character_set_client */; @@ -2523,6 +2503,7 @@ CREATE TABLE `programs_programsapiconfig` ( `api_version_number` int(11) NOT NULL, `enable_student_dashboard` tinyint(1) DEFAULT NULL, `changed_by_id` int(11) DEFAULT NULL, + `cache_ttl` int(10) unsigned NOT NULL, PRIMARY KEY (`id`), KEY `programs_programsa_changed_by_id_b7c3b49d5c0dcd3_fk_auth_user_id` (`changed_by_id`), CONSTRAINT `programs_programsa_changed_by_id_b7c3b49d5c0dcd3_fk_auth_user_id` FOREIGN KEY (`changed_by_id`) REFERENCES `auth_user` (`id`) @@ -4107,20 +4088,6 @@ CREATE TABLE `workflow_assessmentworkflowstep` ( CONSTRAINT `w_workflow_id_4939c36cf6220ba3_fk_workflow_assessmentworkflow_id` FOREIGN KEY (`workflow_id`) REFERENCES `workflow_assessmentworkflow` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -DROP TABLE IF EXISTS `xblock_config_studioconfig`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `xblock_config_studioconfig` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `change_date` datetime(6) NOT NULL, - `enabled` tinyint(1) NOT NULL, - `disabled_blocks` longtext NOT NULL, - `changed_by_id` int(11) DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `xblock_config_stu_changed_by_id_58f0a899052499fd_fk_auth_user_id` (`changed_by_id`), - CONSTRAINT `xblock_config_stu_changed_by_id_58f0a899052499fd_fk_auth_user_id` FOREIGN KEY (`changed_by_id`) REFERENCES `auth_user` (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `xblock_django_xblockdisableconfig`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; diff --git a/lms/djangoapps/badges/__init__.py b/lms/djangoapps/badges/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/lms/djangoapps/badges/admin.py b/lms/djangoapps/badges/admin.py new file mode 100644 index 000000000000..a30eaf4f9c36 --- /dev/null +++ b/lms/djangoapps/badges/admin.py @@ -0,0 +1,7 @@ +""" +Admin registration for Badge Models +""" +from django.contrib import admin +from badges.models import CourseCompleteImageConfiguration + +admin.site.register(CourseCompleteImageConfiguration) diff --git a/lms/djangoapps/badges/backends/__init__.py b/lms/djangoapps/badges/backends/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/lms/djangoapps/badges/backends/badgr.py b/lms/djangoapps/badges/backends/badgr.py new file mode 100644 index 000000000000..265b524c517a --- /dev/null +++ b/lms/djangoapps/badges/backends/badgr.py @@ -0,0 +1,179 @@ +""" +Badge Awarding backend for Badgr-Server. +""" +import hashlib +import logging +import mimetypes + +import requests +from django.conf import settings +from django.core.exceptions import ImproperlyConfigured +from lazy import lazy +from requests.packages.urllib3.exceptions import HTTPError + +from badges.backends.base import BadgeBackend +from eventtracking import tracker + +from badges.models import BadgeAssertion + +MAX_SLUG_LENGTH = 255 +LOGGER = logging.getLogger(__name__) + + +class BadgrBackend(BadgeBackend): + """ + Backend for Badgr-Server by Concentric Sky. http://info.badgr.io/ + """ + badges = [] + + def __init__(self): + super(BadgrBackend, self).__init__() + if not settings.BADGR_API_TOKEN: + raise ImproperlyConfigured("BADGR_API_TOKEN not set.") + + @lazy + def _base_url(self): + """ + Base URL for all API requests. + """ + return "{}/v1/issuer/issuers/{}".format(settings.BADGR_BASE_URL, settings.BADGR_ISSUER_SLUG) + + @lazy + def _badge_create_url(self): + """ + URL for generating a new Badge specification + """ + return "{}/badges".format(self._base_url) + + def _badge_url(self, slug): + """ + Get the URL for a course's badge in a given mode. + """ + return "{}/{}".format(self._badge_create_url, slug) + + def _assertion_url(self, slug): + """ + URL for generating a new assertion. + """ + return "{}/assertions".format(self._badge_url(slug)) + + def _slugify(self, badge_class): + """ + Get a compatible badge slug from the specification. + """ + slug = badge_class.issuing_component + badge_class.slug + if badge_class.issuing_component and badge_class.course_id: + # Make this unique to the course, and down to 64 characters. + # We don't do this to badges without issuing_component set for backwards compatibility. + slug = hashlib.sha256(slug + unicode(badge_class.course_id)).hexdigest() + if len(slug) > MAX_SLUG_LENGTH: + # Will be 64 characters. + slug = hashlib.sha256(slug).hexdigest() + return slug + + def _log_if_raised(self, response, data): + """ + Log server response if there was an error. + """ + try: + response.raise_for_status() + except HTTPError: + LOGGER.error( + u"Encountered an error when contacting the Badgr-Server. Request sent to %r with headers %r.\n" + u"and data values %r\n" + u"Response status was %s.\n%s", + response.request.url, response.request.headers, + data, + response.status_code, response.content + ) + raise + + def _create_badge(self, badge_class): + """ + Create the badge class on Badgr. + """ + image = badge_class.image + # We don't want to bother validating the file any further than making sure we can detect its MIME type, + # for HTTP. The Badgr-Server should tell us if there's anything in particular wrong with it. + content_type, __ = mimetypes.guess_type(image.name) + if not content_type: + raise ValueError( + u"Could not determine content-type of image! Make sure it is a properly named .png file. " + u"Filename was: {}".format(image.name) + ) + files = {'image': (image.name, image, content_type)} + data = { + 'name': badge_class.display_name, + 'criteria': badge_class.criteria, + 'slug': self._slugify(badge_class), + 'description': badge_class.description, + } + result = requests.post( + self._badge_create_url, headers=self._get_headers(), data=data, files=files, + timeout=settings.BADGR_TIMEOUT + ) + self._log_if_raised(result, data) + + def _send_assertion_created_event(self, user, assertion): + """ + Send an analytics event to record the creation of a badge assertion. + """ + tracker.emit( + 'edx.badge.assertion.created', { + 'user_id': user.id, + 'badge_slug': assertion.badge_class.slug, + 'badge_name': assertion.badge_class.display_name, + 'issuing_component': assertion.badge_class.issuing_component, + 'course_id': unicode(assertion.badge_class.course_id), + 'enrollment_mode': assertion.badge_class.mode, + 'assertion_id': assertion.id, + 'assertion_image_url': assertion.image_url, + 'assertion_json_url': assertion.assertion_url, + 'issuer': assertion.data.get('issuer'), + } + ) + + def _create_assertion(self, badge_class, user, evidence_url): + """ + Register an assertion with the Badgr server for a particular user for a specific class. + """ + data = { + 'email': user.email, + 'evidence': evidence_url, + } + response = requests.post( + self._assertion_url(self._slugify(badge_class)), headers=self._get_headers(), data=data, + timeout=settings.BADGR_TIMEOUT + ) + self._log_if_raised(response, data) + assertion, __ = BadgeAssertion.objects.get_or_create(user=user, badge_class=badge_class) + assertion.data = response.json() + assertion.backend = 'BadgrBackend' + assertion.image_url = assertion.data['image'] + assertion.assertion_url = assertion.data['json']['id'] + assertion.save() + self._send_assertion_created_event(user, assertion) + return assertion + + @staticmethod + def _get_headers(): + """ + Headers to send along with the request-- used for authentication. + """ + return {'Authorization': 'Token {}'.format(settings.BADGR_API_TOKEN)} + + def _ensure_badge_created(self, badge_class): + """ + Verify a badge has been created for this badge class, and create it if not. + """ + slug = self._slugify(badge_class) + if slug in BadgrBackend.badges: + return + response = requests.get(self._badge_url(slug), headers=self._get_headers(), timeout=settings.BADGR_TIMEOUT) + if response.status_code != 200: + self._create_badge(badge_class) + BadgrBackend.badges.append(slug) + + def award(self, badge_class, user, evidence_url=None): + self._ensure_badge_created(badge_class) + return self._create_assertion(badge_class, user, evidence_url) diff --git a/lms/djangoapps/badges/backends/base.py b/lms/djangoapps/badges/backends/base.py new file mode 100644 index 000000000000..7abcce2f74d0 --- /dev/null +++ b/lms/djangoapps/badges/backends/base.py @@ -0,0 +1,17 @@ +""" +Base class for badge backends. +""" +from abc import ABCMeta, abstractmethod + + +class BadgeBackend(object): + """ + Defines the interface for badging backends. + """ + __metaclass__ = ABCMeta + + @abstractmethod + def award(self, badge_class, user, evidence_url=None): + """ + Create a badge assertion for the user using this backend. + """ diff --git a/lms/djangoapps/badges/backends/tests/__init__.py b/lms/djangoapps/badges/backends/tests/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/lms/djangoapps/certificates/tests/test_badge_handler.py b/lms/djangoapps/badges/backends/tests/test_badgr_backend.py similarity index 57% rename from lms/djangoapps/certificates/tests/test_badge_handler.py rename to lms/djangoapps/badges/backends/tests/test_badgr_backend.py index e894102c0953..455a0faeeba3 100644 --- a/lms/djangoapps/certificates/tests/test_badge_handler.py +++ b/lms/djangoapps/badges/backends/tests/test_badgr_backend.py @@ -1,19 +1,22 @@ """ -Tests for the BadgeHandler, which communicates with the Badgr Server. +Tests for BadgrBackend """ from datetime import datetime -from django.test.utils import override_settings + +import ddt from django.db.models.fields.files import ImageFieldFile +from django.test.utils import override_settings from lazy.lazy import lazy from mock import patch, Mock, call -from certificates.models import BadgeAssertion, BadgeImageConfiguration + +from badges.backends.badgr import BadgrBackend +from badges.models import BadgeAssertion +from badges.tests.factories import BadgeClassFactory from openedx.core.lib.tests.assertions.events import assert_event_matches -from track.tests import EventTrackingTestCase -from xmodule.modulestore.tests.factories import CourseFactory -from certificates.badge_handler import BadgeHandler -from certificates.tests.factories import BadgeImageConfigurationFactory from student.tests.factories import UserFactory, CourseEnrollmentFactory +from track.tests import EventTrackingTestCase from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase +from xmodule.modulestore.tests.factories import CourseFactory BADGR_SETTINGS = { 'BADGR_API_TOKEN': '12345', @@ -22,8 +25,10 @@ } +# pylint: disable=protected-access +@ddt.ddt @override_settings(**BADGR_SETTINGS) -class BadgeHandlerTestCase(ModuleStoreTestCase, EventTrackingTestCase): +class BadgrBackendTestCase(ModuleStoreTestCase, EventTrackingTestCase): """ Tests the BadgeHandler object """ @@ -31,7 +36,7 @@ def setUp(self): """ Create a course and user to test with. """ - super(BadgeHandlerTestCase, self).setUp() + super(BadgrBackendTestCase, self).setUp() # Need key to be deterministic to test slugs. self.course = CourseFactory.create( org='edX', course='course_test', run='test_run', display_name='Badged', @@ -40,9 +45,13 @@ def setUp(self): ) self.user = UserFactory.create(email='example@example.com') CourseEnrollmentFactory.create(user=self.user, course_id=self.course.location.course_key, mode='honor') - # Need for force empty this dict on each run. - BadgeHandler.badges = {} - BadgeImageConfigurationFactory() + # Need to empty this on each run. + BadgrBackend.badges = [] + self.badge_class = BadgeClassFactory.create(course_id=self.course.location.course_key) + self.legacy_badge_class = BadgeClassFactory.create( + course_id=self.course.location.course_key, issuing_component='' + ) + self.no_course_badge_class = BadgeClassFactory.create() @lazy def handler(self): @@ -50,21 +59,21 @@ def handler(self): Lazily loads a BadgeHandler object for the current course. Can't do this on setUp because the settings overrides aren't in place. """ - return BadgeHandler(self.course.location.course_key) + return BadgrBackend() def test_urls(self): """ Make sure the handler generates the correct URLs for different API tasks. """ - self.assertEqual(self.handler.base_url, 'https://example.com/v1/issuer/issuers/test-issuer') - self.assertEqual(self.handler.badge_create_url, 'https://example.com/v1/issuer/issuers/test-issuer/badges') + self.assertEqual(self.handler._base_url, 'https://example.com/v1/issuer/issuers/test-issuer') + self.assertEqual(self.handler._badge_create_url, 'https://example.com/v1/issuer/issuers/test-issuer/badges') self.assertEqual( - self.handler.badge_url('honor'), - 'https://example.com/v1/issuer/issuers/test-issuer/badges/edxcourse_testtest_run_honor_fc5519b' + self.handler._badge_url('test_slug_here'), + 'https://example.com/v1/issuer/issuers/test-issuer/badges/test_slug_here' ) self.assertEqual( - self.handler.assertion_url('honor'), - 'https://example.com/v1/issuer/issuers/test-issuer/badges/edxcourse_testtest_run_honor_fc5519b/assertions' + self.handler._assertion_url('another_test_slug'), + 'https://example.com/v1/issuer/issuers/test-issuer/badges/another_test_slug/assertions' ) def check_headers(self, headers): @@ -73,121 +82,110 @@ def check_headers(self, headers): """ self.assertEqual(headers, {'Authorization': 'Token 12345'}) - def test_slug(self): - """ - Verify slug generation is working as expected. If this test fails, the algorithm has changed, and it will cause - the handler to lose track of all badges it made in the past. - """ - self.assertEqual( - self.handler.course_slug('honor'), - 'edxcourse_testtest_run_honor_fc5519b' - ) - self.assertEqual( - self.handler.course_slug('verified'), - 'edxcourse_testtest_run_verified_a199ec0' - ) - def test_get_headers(self): """ Check to make sure the handler generates appropriate HTTP headers. """ - self.check_headers(self.handler.get_headers()) + self.check_headers(self.handler._get_headers()) @patch('requests.post') def test_create_badge(self, post): """ Verify badge spec creation works. """ - self.handler.create_badge('honor') + self.handler._create_badge(self.badge_class) args, kwargs = post.call_args self.assertEqual(args[0], 'https://example.com/v1/issuer/issuers/test-issuer/badges') - self.assertEqual(kwargs['files']['image'][0], BadgeImageConfiguration.objects.get(mode='honor').icon.name) + self.assertEqual(kwargs['files']['image'][0], self.badge_class.image.name) self.assertIsInstance(kwargs['files']['image'][1], ImageFieldFile) self.assertEqual(kwargs['files']['image'][2], 'image/png') self.check_headers(kwargs['headers']) self.assertEqual( kwargs['data'], { - 'name': 'Badged', - 'slug': 'edxcourse_testtest_run_honor_fc5519b', - 'criteria': 'https://edx.org/courses/edX/course_test/test_run/about', - 'description': 'Completed the course "Badged" (honor, 2015-05-19 - 2015-05-20)', + 'name': 'Test Badge', + 'slug': '15bb687e0c59ef2f0a49f6838f511bf4ca6c566dd45da6293cabbd9369390e1a', + 'criteria': 'https://example.com/syllabus', + 'description': "Yay! It's a test badge.", } ) - def test_self_paced_description(self): - """ - Verify that a badge created for a course with no end date gets a different description. - """ - self.course.end = None - self.assertEqual(BadgeHandler.badge_description(self.course, 'honor'), 'Completed the course "Badged" (honor)') - def test_ensure_badge_created_cache(self): """ Make sure ensure_badge_created doesn't call create_badge if we know the badge is already there. """ - BadgeHandler.badges['edxcourse_testtest_run_honor_fc5519b'] = True - self.handler.create_badge = Mock() - self.handler.ensure_badge_created('honor') - self.assertFalse(self.handler.create_badge.called) + BadgrBackend.badges.append('15bb687e0c59ef2f0a49f6838f511bf4ca6c566dd45da6293cabbd9369390e1a') + self.handler._create_badge = Mock() + self.handler._ensure_badge_created(self.badge_class) + self.assertFalse(self.handler._create_badge.called) + + @ddt.unpack + @ddt.data( + ('badge_class', '15bb687e0c59ef2f0a49f6838f511bf4ca6c566dd45da6293cabbd9369390e1a'), + ('legacy_badge_class', 'test_slug'), + ('no_course_badge_class', 'test_componenttest_slug') + ) + def test_slugs(self, badge_class_type, slug): + self.assertEqual(self.handler._slugify(getattr(self, badge_class_type)), slug) @patch('requests.get') def test_ensure_badge_created_checks(self, get): response = Mock() response.status_code = 200 get.return_value = response - self.assertNotIn('edxcourse_testtest_run_honor_fc5519b', BadgeHandler.badges) - self.handler.create_badge = Mock() - self.handler.ensure_badge_created('honor') + self.assertNotIn('test_componenttest_slug', BadgrBackend.badges) + self.handler._create_badge = Mock() + self.handler._ensure_badge_created(self.badge_class) self.assertTrue(get.called) args, kwargs = get.call_args self.assertEqual( args[0], 'https://example.com/v1/issuer/issuers/test-issuer/badges/' - 'edxcourse_testtest_run_honor_fc5519b' + '15bb687e0c59ef2f0a49f6838f511bf4ca6c566dd45da6293cabbd9369390e1a' ) self.check_headers(kwargs['headers']) - self.assertTrue(BadgeHandler.badges['edxcourse_testtest_run_honor_fc5519b']) - self.assertFalse(self.handler.create_badge.called) + self.assertIn('15bb687e0c59ef2f0a49f6838f511bf4ca6c566dd45da6293cabbd9369390e1a', BadgrBackend.badges) + self.assertFalse(self.handler._create_badge.called) @patch('requests.get') def test_ensure_badge_created_creates(self, get): response = Mock() response.status_code = 404 get.return_value = response - self.assertNotIn('edxcourse_testtest_run_honor_fc5519b', BadgeHandler.badges) - self.handler.create_badge = Mock() - self.handler.ensure_badge_created('honor') - self.assertTrue(self.handler.create_badge.called) - self.assertEqual(self.handler.create_badge.call_args, call('honor')) - self.assertTrue(BadgeHandler.badges['edxcourse_testtest_run_honor_fc5519b']) + self.assertNotIn('15bb687e0c59ef2f0a49f6838f511bf4ca6c566dd45da6293cabbd9369390e1a', BadgrBackend.badges) + self.handler._create_badge = Mock() + self.handler._ensure_badge_created(self.badge_class) + self.assertTrue(self.handler._create_badge.called) + self.assertEqual(self.handler._create_badge.call_args, call(self.badge_class)) + self.assertIn('15bb687e0c59ef2f0a49f6838f511bf4ca6c566dd45da6293cabbd9369390e1a', BadgrBackend.badges) @patch('requests.post') def test_badge_creation_event(self, post): result = { 'json': {'id': 'http://www.example.com/example'}, 'image': 'http://www.example.com/example.png', - 'slug': 'test_assertion_slug', + 'badge': 'test_assertion_slug', 'issuer': 'https://example.com/v1/issuer/issuers/test-issuer', } response = Mock() response.json.return_value = result post.return_value = response self.recreate_tracker() - self.handler.create_assertion(self.user, 'honor') + self.handler._create_assertion(self.badge_class, self.user, 'https://example.com/irrefutable_proof') args, kwargs = post.call_args self.assertEqual( args[0], 'https://example.com/v1/issuer/issuers/test-issuer/badges/' - 'edxcourse_testtest_run_honor_fc5519b/assertions' + '15bb687e0c59ef2f0a49f6838f511bf4ca6c566dd45da6293cabbd9369390e1a/assertions' ) self.check_headers(kwargs['headers']) - assertion = BadgeAssertion.objects.get(user=self.user, course_id=self.course.location.course_key) + assertion = BadgeAssertion.objects.get(user=self.user, badge_class__course_id=self.course.location.course_key) self.assertEqual(assertion.data, result) self.assertEqual(assertion.image_url, 'http://www.example.com/example.png') + self.assertEqual(assertion.assertion_url, 'http://www.example.com/example') self.assertEqual(kwargs['data'], { 'email': 'example@example.com', - 'evidence': 'https://edx.org/certificates/user/2/course/edX/course_test/test_run?evidence_visit=1' + 'evidence': 'https://example.com/irrefutable_proof' }) assert_event_matches({ 'name': 'edx.badge.assertion.created', @@ -196,6 +194,9 @@ def test_badge_creation_event(self, post): 'course_id': unicode(self.course.location.course_key), 'enrollment_mode': 'honor', 'assertion_id': assertion.id, + 'badge_name': 'Test Badge', + 'badge_slug': 'test_slug', + 'issuing_component': 'test_component', 'assertion_image_url': 'http://www.example.com/example.png', 'assertion_json_url': 'http://www.example.com/example', 'issuer': 'https://example.com/v1/issuer/issuers/test-issuer', diff --git a/lms/djangoapps/badges/events/__init__.py b/lms/djangoapps/badges/events/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/lms/djangoapps/badges/events/course_complete.py b/lms/djangoapps/badges/events/course_complete.py new file mode 100644 index 000000000000..1c9fd22fad8c --- /dev/null +++ b/lms/djangoapps/badges/events/course_complete.py @@ -0,0 +1,63 @@ +""" +Helper functions for the course complete event that was originally included with the Badging MVP. +""" +import hashlib + +from django.core.urlresolvers import reverse +from django.template.defaultfilters import slugify +from django.utils.translation import ugettext_lazy as _ + +from badges.utils import site_prefix + + +# NOTE: As these functions are carry-overs from the initial badging implementation, they are used in +# migrations. Please check the badge migrations when changing any of these functions. + +def course_slug(course_key, mode): + """ + Legacy: Not to be used as a model for constructing badge slugs. Included for compatibility with the original badge + type, awarded on course completion. + + Slug ought to be deterministic and limited in size so it's not too big for Badgr. + + Badgr's max slug length is 255. + """ + # Seven digits should be enough to realistically avoid collisions. That's what git services use. + digest = hashlib.sha256(u"{}{}".format(unicode(course_key), unicode(mode))).hexdigest()[:7] + base_slug = slugify(unicode(course_key) + u'_{}_'.format(mode))[:248] + return base_slug + digest + + +def badge_description(course, mode): + """ + Returns a description for the earned badge. + """ + if course.end: + return _(u'Completed the course "{course_name}" ({course_mode}, {start_date} - {end_date})').format( + start_date=course.start.date(), + end_date=course.end.date(), + course_name=course.display_name, + course_mode=mode, + ) + else: + return _(u'Completed the course "{course_name}" ({course_mode})').format( + course_name=course.display_name, + course_mode=mode, + ) + + +def evidence_url(user_id, course_key): + """ + Generates a URL to the user's Certificate HTML view, along with a GET variable that will signal the evidence visit + event. + """ + return site_prefix() + reverse( + 'certificates:html_view', kwargs={'user_id': user_id, 'course_id': unicode(course_key)}) + '?evidence_visit=1' + + +def criteria(course_key): + """ + Constructs the 'criteria' URL from the course about page. + """ + about_path = reverse('about_course', kwargs={'course_id': unicode(course_key)}) + return u'{}{}'.format(site_prefix(), about_path) diff --git a/lms/djangoapps/badges/events/tests/__init__.py b/lms/djangoapps/badges/events/tests/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/lms/djangoapps/badges/events/tests/test_course_complete.py b/lms/djangoapps/badges/events/tests/test_course_complete.py new file mode 100644 index 000000000000..0fb072ee804f --- /dev/null +++ b/lms/djangoapps/badges/events/tests/test_course_complete.py @@ -0,0 +1,70 @@ +""" +Tests for the course completion helper functions. +""" +from datetime import datetime + +from student.tests.factories import UserFactory +from xmodule.modulestore.tests.factories import CourseFactory +from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase + +from badges.events import course_complete + + +class CourseCompleteTestCase(ModuleStoreTestCase): + """ + Tests for the course completion helper functions. + """ + def setUp(self, **kwargs): + super(CourseCompleteTestCase, self).setUp() + # Need key to be deterministic to test slugs. + self.course = CourseFactory.create( + org='edX', course='course_test', run='test_run', display_name='Badged', + start=datetime(year=2015, month=5, day=19), + end=datetime(year=2015, month=5, day=20) + ) + self.course_key = self.course.location.course_key + + def test_slug(self): + """ + Verify slug generation is working as expected. If this test fails, the algorithm has changed, and it will cause + the handler to lose track of all badges it made in the past. + """ + self.assertEqual( + course_complete.course_slug(self.course_key, 'honor'), + 'edxcourse_testtest_run_honor_fc5519b' + ) + self.assertEqual( + course_complete.course_slug(self.course_key, 'verified'), + 'edxcourse_testtest_run_verified_a199ec0' + ) + + def test_dated_description(self): + """ + Verify that a course with start/end dates contains a description with them. + """ + self.assertEqual( + course_complete.badge_description(self.course, 'honor'), + 'Completed the course "Badged" (honor, 2015-05-19 - 2015-05-20)' + ) + + def test_self_paced_description(self): + """ + Verify that a badge created for a course with no end date gets a different description. + """ + self.course.end = None + self.assertEqual( + course_complete.badge_description(self.course, 'honor'), + 'Completed the course "Badged" (honor)' + ) + + def test_evidence_url(self): + """ + Make sure the evidence URL points to the right place. + """ + user = UserFactory.create() + self.assertEqual( + 'https://edx.org/certificates/user/{user_id}/course/{course_key}?evidence_visit=1'.format( + user_id=user.id, course_key=self.course_key + ), + course_complete.evidence_url(user.id, self.course_key) + ) diff --git a/lms/djangoapps/badges/migrations/0001_initial.py b/lms/djangoapps/badges/migrations/0001_initial.py new file mode 100644 index 000000000000..000d2308ecd5 --- /dev/null +++ b/lms/djangoapps/badges/migrations/0001_initial.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models +import jsonfield.fields +import badges.models +from django.conf import settings +import xmodule_django.models + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='BadgeAssertion', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('data', jsonfield.fields.JSONField()), + ('backend', models.CharField(max_length=50)), + ('image_url', models.URLField()), + ('assertion_url', models.URLField()), + ], + ), + migrations.CreateModel( + name='BadgeClass', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('slug', models.SlugField(max_length=255)), + ('issuing_component', models.SlugField(default=b'', blank=True)), + ('display_name', models.CharField(max_length=255)), + ('course_id', xmodule_django.models.CourseKeyField(default=None, max_length=255, blank=True)), + ('description', models.TextField()), + ('criteria', models.TextField()), + ('mode', models.CharField(default=b'', max_length=100, blank=True)), + ('image', models.ImageField(upload_to=b'badge_classes', validators=[badges.models.validate_badge_image])), + ], + ), + migrations.CreateModel( + name='CourseCompleteImageConfiguration', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('mode', models.CharField(help_text='The course mode for this badge image. For example, "verified" or "honor".', unique=True, max_length=125)), + ('icon', models.ImageField(help_text='Badge images must be square PNG files. The file size should be under 250KB.', upload_to=b'course_complete_badges', validators=[badges.models.validate_badge_image])), + ('default', models.BooleanField(default=False, help_text='Set this value to True if you want this image to be the default image for any course modes that do not have a specified badge image. You can have only one default image.')), + ], + ), + migrations.AlterUniqueTogether( + name='badgeclass', + unique_together=set([('slug', 'issuing_component', 'course_id')]), + ), + migrations.AddField( + model_name='badgeassertion', + name='badge_class', + field=models.ForeignKey(to='badges.BadgeClass'), + ), + migrations.AddField( + model_name='badgeassertion', + name='user', + field=models.ForeignKey(to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/lms/djangoapps/badges/migrations/0002_data__migrate_assertions.py b/lms/djangoapps/badges/migrations/0002_data__migrate_assertions.py new file mode 100644 index 000000000000..f7343ad90112 --- /dev/null +++ b/lms/djangoapps/badges/migrations/0002_data__migrate_assertions.py @@ -0,0 +1,105 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +import json + +import os +from django.db import migrations, models + + +def forwards(apps, schema_editor): + """ + Migrate the initial badge classes, assertions, and course image configurations from certificates. + """ + from django.core.files.base import ContentFile + from xmodule.modulestore.django import modulestore + from badges.events import course_complete + classes = {} + OldBadgeAssertion = apps.get_model("certificates", "BadgeAssertion") + BadgeImageConfiguration = apps.get_model("certificates", "BadgeImageConfiguration") + BadgeAssertion = apps.get_model("badges", "BadgeAssertion") + BadgeClass = apps.get_model("badges", "BadgeClass") + CourseCompleteImageConfiguration = apps.get_model("badges", "CourseCompleteImageConfiguration") + for badge in OldBadgeAssertion.objects.all(): + if (badge.course_id, badge.mode) not in classes: + course = modulestore().get_course(badge.course_id) + image_config = BadgeImageConfiguration.objects.get(mode=badge.mode) + icon = image_config.icon + badge_class = BadgeClass( + display_name=course.display_name, + criteria=course_complete.evidence_url(badge.user_id, badge.course_id), + description=course_complete.badge_description(course, badge.mode), + slug=course_complete.course_slug(badge.course_id, badge.mode), + mode=image_config.mode, + course_id=badge.course_id, + ) + file_content = ContentFile(icon.read()) + badge_class._meta.get_field('image').generate_filename = \ + lambda inst, fn: os.path.join('badge_classes', fn) + badge_class.image.save(icon.name, file_content) + badge_class.save() + classes[(badge.course_id, badge.mode)] = badge_class + if isinstance(badge.data, basestring): + data = badge.data + else: + data = json.dumps(badge.data) + BadgeAssertion( + user_id=badge.user_id, + badge_class=classes[(badge.course_id, badge.mode)], + data=data, + backend='BadgrBackend', + image_url=badge.data['image'], + assertion_url=badge.data['json']['id'], + ).save() + + for configuration in BadgeImageConfiguration.objects.all(): + file_content = ContentFile(configuration.icon.read()) + new_conf = CourseCompleteImageConfiguration( + default=configuration.default, + mode=configuration.mode, + ) + new_conf.icon.save(configuration.icon.name, file_content) + new_conf.save() + + +def backwards(apps, schema_editor): + from django.core.files.base import ContentFile + OldBadgeAssertion = apps.get_model("certificates", "BadgeAssertion") + BadgeAssertion = apps.get_model("badges", "BadgeAssertion") + BadgeImageConfiguration = apps.get_model("certificates", "BadgeImageConfiguration") + CourseCompleteImageConfiguration = apps.get_model("badges", "CourseCompleteImageConfiguration") + for badge in BadgeAssertion.objects.all(): + if not badge.badge_class.mode: + # Can't preserve old badges without modes. + continue + if isinstance(badge.data, basestring): + data = badge.data + else: + data = json.dumps(badge.data) + OldBadgeAssertion( + user_id=badge.user_id, + course_id=badge.badge_class.course_id, + mode=badge.badge_class.mode, + data=data, + ).save() + + for configuration in CourseCompleteImageConfiguration.objects.all(): + file_content = ContentFile(configuration.icon.read()) + new_conf = BadgeImageConfiguration( + default=configuration.default, + mode=configuration.mode, + ) + new_conf.icon.save(configuration.icon.name, file_content) + new_conf.save() + + +class Migration(migrations.Migration): + + dependencies = [ + ('badges', '0001_initial'), + ('certificates', '0003_data__default_modes') + ] + + operations = [ + migrations.RunPython(forwards, backwards) + ] diff --git a/lms/djangoapps/badges/migrations/__init__.py b/lms/djangoapps/badges/migrations/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/lms/djangoapps/badges/models.py b/lms/djangoapps/badges/models.py new file mode 100644 index 000000000000..909ccaec1eb7 --- /dev/null +++ b/lms/djangoapps/badges/models.py @@ -0,0 +1,201 @@ +""" +Database models for the badges app +""" +from importlib import import_module + +from django.conf import settings +from django.contrib.auth.models import User +from django.core.exceptions import ValidationError +from django.db import models +from django.utils.translation import ugettext_lazy as _ +from lazy import lazy + +from xmodule_django.models import CourseKeyField +from jsonfield import JSONField + + +def validate_badge_image(image): + """ + Validates that a particular image is small enough, of the right type, and square to be a badge. + """ + if image.width != image.height: + raise ValidationError(_(u"The badge image must be square.")) + if not image.size < (250 * 1024): + raise ValidationError(_(u"The badge image file size must be less than 250KB.")) + + +def validate_lowercase(string): + """ + Validates that a string is lowercase. + """ + if not string == string.lower(): + raise ValidationError(_(u"This value must be all lowercase.")) + + +class BadgeClass(models.Model): + """ + Specifies a badge class to be registered with a backend. + """ + slug = models.SlugField(max_length=255, validators=[validate_lowercase]) + issuing_component = models.SlugField(max_length=50, default='', blank=True, validators=[validate_lowercase]) + display_name = models.CharField(max_length=255) + course_id = CourseKeyField(max_length=255, blank=True, default=None) + description = models.TextField() + criteria = models.TextField() + # Mode a badge was awarded for. Included for legacy/migration purposes. + mode = models.CharField(max_length=100, default='', blank=True) + image = models.ImageField(upload_to='badge_classes', validators=[validate_badge_image]) + + def __unicode__(self): + return u"".format( + slug=self.slug, issuing_component=self.issuing_component + ) + + @classmethod + def get_badge_class( + cls, slug, issuing_component, display_name, description, criteria, image_file_handle, + mode='', course_id=None, create=True + ): + """ + Looks up a badge class by its slug, issuing component, and course_id and returns it should it exist. + If it does not exist, and create is True, creates it according to the arguments. Otherwise, returns None. + """ + slug = slug.lower() + issuing_component = issuing_component.lower() + if not course_id: + course_id = CourseKeyField.Empty + try: + return cls.objects.get(slug=slug, issuing_component=issuing_component, course_id=course_id) + except cls.DoesNotExist: + if not create: + return None + badge_class = cls( + slug=slug, + issuing_component=issuing_component, + display_name=display_name, + course_id=course_id, + mode=mode, + description=description, + criteria=criteria, + ) + badge_class.image.save(image_file_handle.name, image_file_handle) + badge_class.full_clean() + badge_class.save() + return badge_class + + @lazy + def backend(self): + """ + Loads the badging backend. + """ + module, klass = settings.BADGING_BACKEND.rsplit('.', 1) + module = import_module(module) + return getattr(module, klass)() + + def get_for_user(self, user): + """ + Get the assertion for this badge class for this user, if it has been awarded. + """ + return self.badgeassertion_set.filter(user=user) + + def award(self, user, evidence_url=None): + """ + Contacts the backend to have a badge assertion created for this badge class for this user. + """ + return self.backend.award(self, user, evidence_url=evidence_url) + + def save(self, **kwargs): + """ + Slugs must always be lowercase. + """ + self.slug = self.slug and self.slug.lower() + self.issuing_component = self.issuing_component and self.issuing_component.lower() + super(BadgeClass, self).save(**kwargs) + + class Meta(object): + app_label = "badges" + unique_together = (('slug', 'issuing_component', 'course_id'),) + + +class BadgeAssertion(models.Model): + """ + Tracks badges on our side of the badge baking transaction + """ + user = models.ForeignKey(User) + badge_class = models.ForeignKey(BadgeClass) + data = JSONField() + backend = models.CharField(max_length=50) + image_url = models.URLField() + assertion_url = models.URLField() + + def __unicode__(self): + return u"<{username} Badge Assertion for {slug} for {issuing_component}".format( + username=self.user.username, slug=self.badge_class.slug, + issuing_component=self.badge_class.issuing_component, + ) + + @classmethod + def assertions_for_user(cls, user, course_id=None): + """ + Get all assertions for a user, optionally constrained to a course. + """ + if course_id: + return cls.objects.filter(user=user, badge_class__course_id=course_id) + return cls.objects.filter(user=user) + + class Meta(object): + app_label = "badges" + + +class CourseCompleteImageConfiguration(models.Model): + """ + Contains the icon configuration for badges for a specific course mode. + """ + mode = models.CharField( + max_length=125, + help_text=_(u'The course mode for this badge image. For example, "verified" or "honor".'), + unique=True, + ) + icon = models.ImageField( + # Actual max is 256KB, but need overhead for badge baking. This should be more than enough. + help_text=_( + u"Badge images must be square PNG files. The file size should be under 250KB." + ), + upload_to='course_complete_badges', + validators=[validate_badge_image] + ) + default = models.BooleanField( + help_text=_( + u"Set this value to True if you want this image to be the default image for any course modes " + u"that do not have a specified badge image. You can have only one default image." + ), + default=False, + ) + + def __unicode__(self): + return u"".format( + mode=self.mode, + default=u" (default)" if self.default else u'' + ) + + def clean(self): + """ + Make sure there's not more than one default. + """ + # pylint: disable=no-member + if self.default and CourseCompleteImageConfiguration.objects.filter(default=True).exclude(id=self.id): + raise ValidationError(_(u"There can be only one default image.")) + + @classmethod + def image_for_mode(cls, mode): + """ + Get the image for a particular mode. + """ + try: + return cls.objects.get(mode=mode).icon + except cls.DoesNotExist: + # Fall back to default, if there is one. + return cls.objects.get(default=True).icon + + class Meta(object): + app_label = "badges" diff --git a/lms/djangoapps/badges/tests/__init__.py b/lms/djangoapps/badges/tests/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/lms/djangoapps/badges/tests/factories.py b/lms/djangoapps/badges/tests/factories.py new file mode 100644 index 000000000000..dfb60544df79 --- /dev/null +++ b/lms/djangoapps/badges/tests/factories.py @@ -0,0 +1,71 @@ +""" +Factories for Badge tests +""" +from random import random + +import factory +from django.core.files.base import ContentFile +from factory import DjangoModelFactory +from factory.django import ImageField + +from badges.models import BadgeAssertion, CourseCompleteImageConfiguration, BadgeClass +from student.tests.factories import UserFactory + + +def generate_dummy_image(_unused): + """ + Used for image fields to create a sane default. + """ + return ContentFile( + ImageField()._make_data( # pylint: disable=protected-access + {'color': 'blue', 'width': 50, 'height': 50, 'format': 'PNG'} + ), 'test.png' + ) + + +class CourseCompleteImageConfigurationFactory(DjangoModelFactory): + """ + Factory for BadgeImageConfigurations + """ + class Meta(object): + model = CourseCompleteImageConfiguration + + mode = 'honor' + icon = factory.LazyAttribute(generate_dummy_image) + + +class BadgeClassFactory(DjangoModelFactory): + """ + Factory for BadgeClass + """ + class Meta(object): + model = BadgeClass + + slug = 'test_slug' + issuing_component = 'test_component' + display_name = 'Test Badge' + description = "Yay! It's a test badge." + criteria = 'https://example.com/syllabus' + mode = 'honor' + image = factory.LazyAttribute(generate_dummy_image) + + +class RandomBadgeClassFactory(BadgeClassFactory): + """ + Same as BadgeClassFactory, but randomize the slug. + """ + slug = factory.lazy_attribute(lambda _: 'test_slug_' + str(random())) + + +class BadgeAssertionFactory(DjangoModelFactory): + """ + Factory for BadgeAssertions + """ + class Meta(object): + model = BadgeAssertion + + user = factory.SubFactory(UserFactory) + badge_class = factory.SubFactory(RandomBadgeClassFactory) + data = {} + assertion_url = 'http://example.com/example.json' + image_url = 'http://example.com/image.png' diff --git a/lms/djangoapps/badges/tests/test_models.py b/lms/djangoapps/badges/tests/test_models.py new file mode 100644 index 000000000000..0a17c92b53a1 --- /dev/null +++ b/lms/djangoapps/badges/tests/test_models.py @@ -0,0 +1,246 @@ +""" +Tests for the Badges app models. +""" +from django.core.exceptions import ValidationError +from django.core.files.images import ImageFile +from django.test import TestCase +from django.test.utils import override_settings +from mock import patch +from nose.plugins.attrib import attr +from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase + +from xmodule.modulestore.tests.factories import CourseFactory + +from badges.models import CourseCompleteImageConfiguration, validate_badge_image, BadgeClass, BadgeAssertion +from badges.tests.factories import BadgeClassFactory, BadgeAssertionFactory, RandomBadgeClassFactory +from certificates.tests.test_models import TEST_DATA_ROOT +from student.tests.factories import UserFactory + + +class ImageFetchingMixin(object): + """ + Provides the ability to grab a badge image from the test data root. + """ + def get_image(self, name): + """ + Get one of the test images from the test data directory. + """ + return ImageFile(open(TEST_DATA_ROOT / 'badges' / name + '.png')) + + +@attr('shard_1') +class BadgeImageConfigurationTest(TestCase, ImageFetchingMixin): + """ + Test the validation features of BadgeImageConfiguration. + """ + + def test_no_double_default(self): + """ + Verify that creating two configurations as default is not permitted. + """ + CourseCompleteImageConfiguration(mode='test', icon=self.get_image('good'), default=True).save() + self.assertRaises( + ValidationError, + CourseCompleteImageConfiguration(mode='test2', icon=self.get_image('good'), default=True).full_clean + ) + + def test_runs_validator(self): + """ + Verify that the image validator is triggered when cleaning the model. + """ + self.assertRaises( + ValidationError, + CourseCompleteImageConfiguration(mode='test2', icon=self.get_image('unbalanced')).full_clean + ) + + +class DummyBackend(object): + """ + Dummy badge backend, used for testing. + """ + + +class BadgeClassTest(ModuleStoreTestCase, ImageFetchingMixin): + """ + Test BadgeClass functionality + """ + # Need full path to make sure class names line up. + @override_settings(BADGING_BACKEND='lms.djangoapps.badges.tests.test_models.DummyBackend') + def test_backend(self): + """ + Verify the BadgeClass fetches the backend properly. + """ + self.assertIsInstance(BadgeClass().backend, DummyBackend) + + def test_get_badge_class_preexisting(self): + """ + Verify fetching a badge first grabs existing badges. + """ + premade_badge_class = BadgeClassFactory.create() + # Ignore additional parameters. This class already exists. + badge_class = BadgeClass.get_badge_class( + slug='test_slug', issuing_component='test_component', description='Attempted override', + criteria='test', display_name='Testola', image_file_handle=self.get_image('good') + ) + # These defaults are set on the factory. + self.assertEqual(badge_class.criteria, 'https://example.com/syllabus') + self.assertEqual(badge_class.display_name, 'Test Badge') + self.assertEqual(badge_class.description, "Yay! It's a test badge.") + # File name won't always be the same. + self.assertEqual(badge_class.image.path, premade_badge_class.image.path) + + def test_unique_for_course(self): + """ + Verify that the course_id is used in fetching existing badges or creating new ones. + """ + course_key = CourseFactory.create().location.course_key + premade_badge_class = BadgeClassFactory.create(course_id=course_key) + badge_class = BadgeClass.get_badge_class( + slug='test_slug', issuing_component='test_component', description='Attempted override', + criteria='test', display_name='Testola', image_file_handle=self.get_image('good') + ) + course_badge_class = BadgeClass.get_badge_class( + slug='test_slug', issuing_component='test_component', description='Attempted override', + criteria='test', display_name='Testola', image_file_handle=self.get_image('good'), + course_id=course_key, + ) + self.assertNotEqual(badge_class.id, course_badge_class.id) + self.assertEqual(course_badge_class.id, premade_badge_class.id) + + def test_get_badge_class_create(self): + """ + Verify fetching a badge creates it if it doesn't yet exist. + """ + badge_class = BadgeClass.get_badge_class( + slug='new_slug', issuing_component='new_component', description='This is a test', + criteria='https://example.com/test_criteria', display_name='Super Badge', + image_file_handle=self.get_image('good') + ) + # This should have been saved before being passed back. + self.assertTrue(badge_class.id) + self.assertEqual(badge_class.slug, 'new_slug') + self.assertEqual(badge_class.issuing_component, 'new_component') + self.assertEqual(badge_class.description, 'This is a test') + self.assertEqual(badge_class.criteria, 'https://example.com/test_criteria') + self.assertEqual(badge_class.display_name, 'Super Badge') + self.assertEqual(badge_class.image.name.rsplit('/', 1)[-1], 'good.png') + + def test_get_badge_class_nocreate(self): + """ + Test returns None if the badge class does not exist. + """ + badge_class = BadgeClass.get_badge_class( + slug='new_slug', issuing_component='new_component', description=None, + criteria=None, display_name=None, + image_file_handle=None, create=False + ) + self.assertIsNone(badge_class) + # Run this twice to verify there wasn't a background creation of the badge. + badge_class = BadgeClass.get_badge_class( + slug='new_slug', issuing_component='new_component', description=None, + criteria=None, display_name=None, + image_file_handle=None, create=False + ) + self.assertIsNone(badge_class) + + def test_get_badge_class_validate(self): + """ + Verify handing a broken image to get_badge_class raises a validation error upon creation. + """ + self.assertRaises( + ValidationError, + BadgeClass.get_badge_class, + slug='new_slug', issuing_component='new_component', description='This is a test', + criteria='https://example.com/test_criteria', display_name='Super Badge', + image_file_handle=self.get_image('unbalanced') + ) + + def test_get_for_user(self): + """ + Make sure we can get an assertion for a user if there is one. + """ + user = UserFactory.create() + badge_class = BadgeClassFactory.create() + self.assertFalse(badge_class.get_for_user(user)) + assertion = BadgeAssertionFactory.create(badge_class=badge_class, user=user) + self.assertEqual(list(badge_class.get_for_user(user)), [assertion]) + + @override_settings(BADGING_BACKEND='lms.djangoapps.badges.backends.badgr.BadgrBackend', BADGR_API_TOKEN='test') + @patch('lms.djangoapps.badges.backends.badgr.BadgrBackend.award') + def test_award(self, mock_award): + """ + Verify that the award command calls the award function on the backend with the right parameters. + """ + user = UserFactory.create() + badge_class = BadgeClassFactory.create() + badge_class.award(user, evidence_url='http://example.com/evidence') + self.assertTrue(mock_award.called) + mock_award.assert_called_with(badge_class, user, evidence_url='http://example.com/evidence') + + def test_runs_validator(self): + """ + Verify that the image validator is triggered when cleaning the model. + """ + self.assertRaises( + ValidationError, + BadgeClass( + slug='test', issuing_component='test2', criteria='test3', + description='test4', image=self.get_image('unbalanced') + ).full_clean + ) + + +class BadgeAssertionTest(ModuleStoreTestCase): + """ + Tests for the BadgeAssertion model + """ + def test_assertions_for_user(self): + """ + Verify that grabbing all assertions for a user behaves as expected. + + This function uses object IDs because for some reason Jenkins trips up + on its assertItemsEqual check here despite the items being equal. + """ + user = UserFactory() + assertions = [BadgeAssertionFactory.create(user=user).id for _i in range(3)] + course = CourseFactory.create() + course_key = course.location.course_key + course_badges = [RandomBadgeClassFactory(course_id=course_key) for _i in range(3)] + course_assertions = [ + BadgeAssertionFactory.create(user=user, badge_class=badge_class).id for badge_class in course_badges + ] + assertions.extend(course_assertions) + assertions.sort() + assertions_for_user = [badge.id for badge in BadgeAssertion.assertions_for_user(user)] + assertions_for_user.sort() + self.assertEqual(assertions_for_user, assertions) + course_scoped_assertions = [ + badge.id for badge in BadgeAssertion.assertions_for_user(user, course_id=course_key) + ] + course_scoped_assertions.sort() + self.assertEqual(course_scoped_assertions, course_assertions) + + +class ValidBadgeImageTest(TestCase, ImageFetchingMixin): + """ + Tests the badge image field validator. + """ + def test_good_image(self): + """ + Verify that saving a valid badge image is no problem. + """ + validate_badge_image(self.get_image('good')) + + def test_unbalanced_image(self): + """ + Verify that setting an image with an uneven width and height raises an error. + """ + unbalanced = ImageFile(self.get_image('unbalanced')) + self.assertRaises(ValidationError, validate_badge_image, unbalanced) + + def test_large_image(self): + """ + Verify that setting an image that is too big raises an error. + """ + large = self.get_image('large') + self.assertRaises(ValidationError, validate_badge_image, large) diff --git a/lms/djangoapps/badges/utils.py b/lms/djangoapps/badges/utils.py new file mode 100644 index 000000000000..9e2d98f3043d --- /dev/null +++ b/lms/djangoapps/badges/utils.py @@ -0,0 +1,12 @@ +""" +Utility functions used by the badging app. +""" +from django.conf import settings + + +def site_prefix(): + """ + Get the prefix for the site URL-- protocol and server name. + """ + scheme = u"https" if settings.HTTPS == "on" else u"http" + return u'{}://{}'.format(scheme, settings.SITE_NAME) diff --git a/lms/djangoapps/certificates/admin.py b/lms/djangoapps/certificates/admin.py index 54eccb0ac8c8..e590ecd9b254 100644 --- a/lms/djangoapps/certificates/admin.py +++ b/lms/djangoapps/certificates/admin.py @@ -8,7 +8,6 @@ from certificates.models import ( CertificateGenerationConfiguration, CertificateHtmlViewConfiguration, - BadgeImageConfiguration, CertificateTemplate, CertificateTemplateAsset, GeneratedCertificate, @@ -58,7 +57,6 @@ class GeneratedCertificateAdmin(admin.ModelAdmin): admin.site.register(CertificateGenerationConfiguration) admin.site.register(CertificateHtmlViewConfiguration, ConfigurationModelAdmin) -admin.site.register(BadgeImageConfiguration) admin.site.register(CertificateTemplate, CertificateTemplateAdmin) admin.site.register(CertificateTemplateAsset, CertificateTemplateAssetAdmin) admin.site.register(GeneratedCertificate, GeneratedCertificateAdmin) diff --git a/lms/djangoapps/certificates/badge_handler.py b/lms/djangoapps/certificates/badge_handler.py deleted file mode 100644 index 2b12a2bea40b..000000000000 --- a/lms/djangoapps/certificates/badge_handler.py +++ /dev/null @@ -1,195 +0,0 @@ -""" -BadgeHandler object-- used to award Badges to users who have completed courses. -""" -import hashlib -import logging -import mimetypes -from eventtracking import tracker -import requests -from django.template.defaultfilters import slugify -from django.utils.translation import ugettext as _ - -from django.conf import settings -from django.core.urlresolvers import reverse -from lazy import lazy -from requests.packages.urllib3.exceptions import HTTPError -from certificates.models import BadgeAssertion, BadgeImageConfiguration -from student.models import CourseEnrollment -from xmodule.modulestore.django import modulestore - -LOGGER = logging.getLogger(__name__) - - -class BadgeHandler(object): - """ - The only properly public method of this class is 'award'. If an alternative object is created for a different - badging service, the other methods don't need to be reproduced. - """ - # Global caching dict - badges = {} - - def __init__(self, course_key): - self.course_key = course_key - assert settings.BADGR_API_TOKEN - - @lazy - def base_url(self): - """ - Base URL for all API requests. - """ - return "{}/v1/issuer/issuers/{}".format(settings.BADGR_BASE_URL, settings.BADGR_ISSUER_SLUG) - - @lazy - def badge_create_url(self): - """ - URL for generating a new Badge specification - """ - return "{}/badges".format(self.base_url) - - def badge_url(self, mode): - """ - Get the URL for a course's badge in a given mode. - """ - return "{}/{}".format(self.badge_create_url, self.course_slug(mode)) - - def assertion_url(self, mode): - """ - URL for generating a new assertion. - """ - return "{}/assertions".format(self.badge_url(mode)) - - def course_slug(self, mode): - """ - Slug ought to be deterministic and limited in size so it's not too big for Badgr. - - Badgr's max slug length is 255. - """ - # Seven digits should be enough to realistically avoid collisions. That's what git services use. - digest = hashlib.sha256(u"{}{}".format(unicode(self.course_key), unicode(mode))).hexdigest()[:7] - base_slug = slugify(unicode(self.course_key) + u'_{}_'.format(mode))[:248] - return base_slug + digest - - def log_if_raised(self, response, data): - """ - Log server response if there was an error. - """ - try: - response.raise_for_status() - except HTTPError: - LOGGER.error( - u"Encountered an error when contacting the Badgr-Server. Request sent to %s with headers %s.\n" - u"and data values %s\n" - u"Response status was %s.\n%s", - repr(response.request.url), repr(response.request.headers), - repr(data), - response.status_code, response.body - ) - raise - - def get_headers(self): - """ - Headers to send along with the request-- used for authentication. - """ - return {'Authorization': 'Token {}'.format(settings.BADGR_API_TOKEN)} - - def ensure_badge_created(self, mode): - """ - Verify a badge has been created for this mode of the course, and, if not, create it - """ - if self.course_slug(mode) in BadgeHandler.badges: - return - response = requests.get(self.badge_url(mode), headers=self.get_headers()) - if response.status_code != 200: - self.create_badge(mode) - BadgeHandler.badges[self.course_slug(mode)] = True - - @staticmethod - def badge_description(course, mode): - """ - Returns a description for the earned badge. - """ - if course.end: - return _(u'Completed the course "{course_name}" ({course_mode}, {start_date} - {end_date})').format( - start_date=course.start.date(), - end_date=course.end.date(), - course_name=course.display_name, - course_mode=mode, - ) - else: - return _(u'Completed the course "{course_name}" ({course_mode})').format( - course_name=course.display_name, - course_mode=mode, - ) - - def site_prefix(self): - """ - Get the prefix for the site URL-- protocol and server name. - """ - scheme = u"https" if settings.HTTPS == "on" else u"http" - return u'{}://{}'.format(scheme, settings.SITE_NAME) - - def create_badge(self, mode): - """ - Create the badge spec for a course's mode. - """ - course = modulestore().get_course(self.course_key) - image = BadgeImageConfiguration.image_for_mode(mode) - # We don't want to bother validating the file any further than making sure we can detect its MIME type, - # for HTTP. The Badgr-Server should tell us if there's anything in particular wrong with it. - content_type, __ = mimetypes.guess_type(image.name) - if not content_type: - raise ValueError( - "Could not determine content-type of image! Make sure it is a properly named .png file." - ) - files = {'image': (image.name, image, content_type)} - about_path = reverse('about_course', kwargs={'course_id': unicode(self.course_key)}) - data = { - 'name': course.display_name, - 'criteria': u'{}{}'.format(self.site_prefix(), about_path), - 'slug': self.course_slug(mode), - 'description': self.badge_description(course, mode) - } - result = requests.post(self.badge_create_url, headers=self.get_headers(), data=data, files=files) - self.log_if_raised(result, data) - - def send_assertion_created_event(self, user, assertion): - """ - Send an analytics event to record the creation of a badge assertion. - """ - tracker.emit( - 'edx.badge.assertion.created', { - 'user_id': user.id, - 'course_id': unicode(self.course_key), - 'enrollment_mode': assertion.mode, - 'assertion_id': assertion.id, - 'assertion_image_url': assertion.data['image'], - 'assertion_json_url': assertion.data['json']['id'], - 'issuer': assertion.data['issuer'], - } - ) - - def create_assertion(self, user, mode): - """ - Register an assertion with the Badgr server for a particular user in a particular course mode for - this course. - """ - data = { - 'email': user.email, - 'evidence': self.site_prefix() + reverse( - 'certificates:html_view', kwargs={'user_id': user.id, 'course_id': unicode(self.course_key)} - ) + '?evidence_visit=1' - } - response = requests.post(self.assertion_url(mode), headers=self.get_headers(), data=data) - self.log_if_raised(response, data) - assertion, __ = BadgeAssertion.objects.get_or_create(course_id=self.course_key, user=user, mode=mode) - assertion.data = response.json() - assertion.save() - self.send_assertion_created_event(user, assertion) - - def award(self, user): - """ - Award a user a badge for their work on the course. - """ - mode = CourseEnrollment.objects.get(user=user, course_id=self.course_key).mode - self.ensure_badge_created(mode) - self.create_assertion(user, mode) diff --git a/lms/djangoapps/certificates/management/commands/regenerate_user.py b/lms/djangoapps/certificates/management/commands/regenerate_user.py index 0a9aa01d29a6..7461a9654bf0 100644 --- a/lms/djangoapps/certificates/management/commands/regenerate_user.py +++ b/lms/djangoapps/certificates/management/commands/regenerate_user.py @@ -8,8 +8,9 @@ from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey from opaque_keys.edx.locations import SlashSeparatedCourseKey + +from certificates.models import get_completion_badge from xmodule.modulestore.django import modulestore -from certificates.models import BadgeAssertion from certificates.api import regenerate_user_certificates LOGGER = logging.getLogger(__name__) @@ -110,6 +111,12 @@ def handle(self, *args, **options): course_id ) + badge_class = get_completion_badge(course_id, student) + badge = badge_class.get_for_user(student) + if badge: + badge.delete() + LOGGER.info(u"Cleared badge for student %s.", student.id) + # Add the certificate request to the queue ret = regenerate_user_certificates( student, course_id, course=course, @@ -118,13 +125,6 @@ def handle(self, *args, **options): insecure=options['insecure'] ) - try: - badge = BadgeAssertion.objects.get(user=student, course_id=course_id) - badge.delete() - LOGGER.info(u"Cleared badge for student %s.", student.id) - except BadgeAssertion.DoesNotExist: - pass - LOGGER.info( ( u"Added a certificate regeneration task to the XQueue " diff --git a/lms/djangoapps/certificates/migrations/0001_initial.py b/lms/djangoapps/certificates/migrations/0001_initial.py index 79801ff8b98a..4584d6eb8ece 100644 --- a/lms/djangoapps/certificates/migrations/0001_initial.py +++ b/lms/djangoapps/certificates/migrations/0001_initial.py @@ -9,6 +9,7 @@ import django_extensions.db.fields.json import django.db.models.deletion import django.utils.timezone +from badges.models import validate_badge_image from django.conf import settings @@ -34,7 +35,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('mode', models.CharField(help_text='The course mode for this badge image. For example, "verified" or "honor".', unique=True, max_length=125)), - ('icon', models.ImageField(help_text='Badge images must be square PNG files. The file size should be under 250KB.', upload_to=b'badges', validators=[certificates.models.validate_badge_image])), + ('icon', models.ImageField(help_text='Badge images must be square PNG files. The file size should be under 250KB.', upload_to=b'badges', validators=[validate_badge_image])), ('default', models.BooleanField(default=False, help_text='Set this value to True if you want this image to be the default image for any course modes that do not have a specified badge image. You can have only one default image.')), ], ), diff --git a/lms/djangoapps/certificates/migrations/0004_schema__remove_badges.py b/lms/djangoapps/certificates/migrations/0004_schema__remove_badges.py new file mode 100644 index 000000000000..880e5d9f0520 --- /dev/null +++ b/lms/djangoapps/certificates/migrations/0004_schema__remove_badges.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('certificates', '0003_data__default_modes'), + ('badges', '0002_data__migrate_assertions'), + ] + + operations = [ + migrations.AlterUniqueTogether( + name='badgeassertion', + unique_together=set([]), + ), + migrations.RemoveField( + model_name='badgeassertion', + name='user', + ), + migrations.DeleteModel( + name='BadgeImageConfiguration', + ), + migrations.DeleteModel( + name='BadgeAssertion', + ), + ] diff --git a/lms/djangoapps/certificates/models.py b/lms/djangoapps/certificates/models.py index 7bc60957420c..08c0205b494e 100644 --- a/lms/djangoapps/certificates/models.py +++ b/lms/djangoapps/certificates/models.py @@ -45,29 +45,30 @@ then the student will be issued a certificate regardless of his grade, unless he has allow_certificate set to False. """ -from datetime import datetime import json import logging import uuid -import os +import os +from django.conf import settings from django.contrib.auth.models import User from django.core.exceptions import ValidationError from django.db import models, transaction from django.db.models import Count from django.db.models.signals import post_save from django.dispatch import receiver -from django.conf import settings from django.utils.translation import ugettext_lazy as _ from django_extensions.db.fields import CreationDateTimeField -from django_extensions.db.fields.json import JSONField from model_utils import Choices from model_utils.models import TimeStampedModel -from xmodule.modulestore.django import modulestore + +from badges.events import course_complete +from badges.models import BadgeAssertion, CourseCompleteImageConfiguration, BadgeClass from config_models.models import ConfigurationModel -from xmodule_django.models import CourseKeyField, NoneToEmptyManager -from util.milestones_helpers import fulfill_course_milestone, is_prerequisite_courses_enabled from course_modes.models import CourseMode +from util.milestones_helpers import fulfill_course_milestone, is_prerequisite_courses_enabled +from xmodule.modulestore.django import modulestore +from xmodule_django.models import CourseKeyField, NoneToEmptyManager LOGGER = logging.getLogger(__name__) @@ -670,94 +671,6 @@ def get_config(cls): return json_data -class BadgeAssertion(models.Model): - """ - Tracks badges on our side of the badge baking transaction - """ - user = models.ForeignKey(User) - course_id = CourseKeyField(max_length=255, blank=True, default=None) - # Mode a badge was awarded for. - mode = models.CharField(max_length=100) - data = JSONField() - - @property - def image_url(self): - """ - Get the image for this assertion. - """ - - return self.data['image'] - - @property - def assertion_url(self): - """ - Get the public URL for the assertion. - """ - return self.data['json']['id'] - - class Meta(object): - unique_together = (('course_id', 'user', 'mode'),) - app_label = "certificates" - - -def validate_badge_image(image): - """ - Validates that a particular image is small enough, of the right type, and square to be a badge. - """ - if image.width != image.height: - raise ValidationError(_(u"The badge image must be square.")) - if not image.size < (250 * 1024): - raise ValidationError(_(u"The badge image file size must be less than 250KB.")) - - -class BadgeImageConfiguration(models.Model): - """ - Contains the configuration for badges for a specific mode. The mode - """ - class Meta(object): - app_label = "certificates" - - mode = models.CharField( - max_length=125, - help_text=_(u'The course mode for this badge image. For example, "verified" or "honor".'), - unique=True, - ) - icon = models.ImageField( - # Actual max is 256KB, but need overhead for badge baking. This should be more than enough. - help_text=_( - u"Badge images must be square PNG files. The file size should be under 250KB." - ), - upload_to='badges', - validators=[validate_badge_image] - ) - default = models.BooleanField( - default=False, - help_text=_( - u"Set this value to True if you want this image to be the default image for any course modes " - u"that do not have a specified badge image. You can have only one default image." - ) - ) - - def clean(self): - """ - Make sure there's not more than one default. - """ - # pylint: disable=no-member - if self.default and BadgeImageConfiguration.objects.filter(default=True).exclude(id=self.id): - raise ValidationError(_(u"There can be only one default image.")) - - @classmethod - def image_for_mode(cls, mode): - """ - Get the image for a particular mode. - """ - try: - return cls.objects.get(mode=mode).icon - except cls.DoesNotExist: - # Fall back to default, if there is one. - return cls.objects.get(default=True).icon - - class CertificateTemplate(TimeStampedModel): """A set of custom web certificate templates. @@ -867,6 +780,28 @@ class Meta(object): app_label = "certificates" +def get_completion_badge(course_id, user): + """ + Given a course key and a user, find the user's enrollment mode + and get the Course Completion badge. + """ + from student.models import CourseEnrollment + mode = CourseEnrollment.objects.filter( + user=user, course_id=course_id + ).order_by('-is_active')[0].mode + course = modulestore().get_course(course_id) + return BadgeClass.get_badge_class( + slug=course_complete.course_slug(course_id, mode), + issuing_component='', + criteria=course_complete.criteria(course_id), + description=course_complete.badge_description(course, mode), + course_id=course_id, + mode=mode, + display_name=course.display_name, + image_file_handle=CourseCompleteImageConfiguration.image_for_mode(mode) + ) + + @receiver(post_save, sender=GeneratedCertificate) #pylint: disable=unused-argument def create_badge(sender, instance, **kwargs): @@ -878,14 +813,14 @@ def create_badge(sender, instance, **kwargs): if not modulestore().get_course(instance.course_id).issue_badges: LOGGER.info("Course is not configured to issue badges.") return - if BadgeAssertion.objects.filter(user=instance.user, course_id=instance.course_id): - LOGGER.info("Badge already exists for this user on this course.") + badge_class = get_completion_badge(instance.course_id, instance.user) + if BadgeAssertion.objects.filter(user=instance.user, badge_class=badge_class): + LOGGER.info("Completion badge already exists for this user on this course.") # Badge already exists. Skip. return # Don't bake a badge until the certificate is available. Prevents user-facing requests from being paused for this # by making sure it only gets run on the callback during normal workflow. if not instance.status == CertificateStatuses.downloadable: return - from .badge_handler import BadgeHandler - handler = BadgeHandler(instance.course_id) - handler.award(instance.user) + evidence = course_complete.evidence_url(instance.user.id, instance.course_id) + badge_class.award(instance.user, evidence_url=evidence) diff --git a/lms/djangoapps/certificates/tests/factories.py b/lms/djangoapps/certificates/tests/factories.py index eb185c50e450..a082d7cf4e31 100644 --- a/lms/djangoapps/certificates/tests/factories.py +++ b/lms/djangoapps/certificates/tests/factories.py @@ -1,15 +1,11 @@ # Factories are self documenting # pylint: disable=missing-docstring -import factory -from django.core.files.base import ContentFile -from factory.django import DjangoModelFactory, ImageField - -from student.models import LinkedInAddToProfileConfiguration +from factory.django import DjangoModelFactory from certificates.models import ( - GeneratedCertificate, CertificateStatuses, CertificateHtmlViewConfiguration, CertificateWhitelist, BadgeAssertion, - BadgeImageConfiguration, + GeneratedCertificate, CertificateStatuses, CertificateHtmlViewConfiguration, CertificateWhitelist, ) +from student.models import LinkedInAddToProfileConfiguration class GeneratedCertificateFactory(DjangoModelFactory): @@ -33,33 +29,6 @@ class Meta(object): notes = None -class BadgeAssertionFactory(DjangoModelFactory): - class Meta(object): - model = BadgeAssertion - - mode = 'honor' - data = { - 'image': 'http://www.example.com/image.png', - 'json': {'id': 'http://www.example.com/assertion.json'}, - 'issuer': 'http://www.example.com/issuer.json', - } - - -class BadgeImageConfigurationFactory(DjangoModelFactory): - - class Meta(object): - model = BadgeImageConfiguration - - mode = 'honor' - icon = factory.LazyAttribute( - lambda _: ContentFile( - ImageField()._make_data( # pylint: disable=protected-access - {'color': 'blue', 'width': 50, 'height': 50, 'format': 'PNG'} - ), 'test.png' - ) - ) - - class CertificateHtmlViewConfigurationFactory(DjangoModelFactory): class Meta(object): diff --git a/lms/djangoapps/certificates/tests/test_cert_management.py b/lms/djangoapps/certificates/tests/test_cert_management.py index 4e025266f59b..cc7087c39ec3 100644 --- a/lms/djangoapps/certificates/tests/test_cert_management.py +++ b/lms/djangoapps/certificates/tests/test_cert_management.py @@ -7,12 +7,14 @@ from mock import patch from opaque_keys.edx.locator import CourseLocator -from certificates.tests.factories import BadgeAssertionFactory + +from badges.models import BadgeAssertion +from badges.tests.factories import BadgeAssertionFactory, CourseCompleteImageConfigurationFactory from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory, check_mongo_calls from student.tests.factories import UserFactory, CourseEnrollmentFactory from certificates.management.commands import resubmit_error_certificates, regenerate_user, ungenerated_certs -from certificates.models import GeneratedCertificate, CertificateStatuses, BadgeAssertion +from certificates.models import GeneratedCertificate, CertificateStatuses, get_completion_badge class CertificateManagementTest(ModuleStoreTestCase): @@ -29,6 +31,7 @@ def setUp(self): CourseFactory.create() for __ in range(3) ] + CourseCompleteImageConfigurationFactory.create() def _create_cert(self, course_key, user, status): """Create a certificate entry. """ @@ -167,9 +170,10 @@ def test_clear_badge(self, xqueue): And the badge will be deleted """ key = self.course.location.course_key - BadgeAssertionFactory(user=self.user, course_id=key, data={}) self._create_cert(key, self.user, CertificateStatuses.downloadable) - self.assertTrue(BadgeAssertion.objects.filter(user=self.user, course_id=key)) + badge_class = get_completion_badge(key, self.user) + BadgeAssertionFactory(badge_class=badge_class, user=self.user) + self.assertTrue(BadgeAssertion.objects.filter(user=self.user, badge_class=badge_class)) self._run_command( username=self.user.email, course=unicode(key), noop=False, insecure=False, template_file=None, grade_value=None @@ -182,7 +186,7 @@ def test_clear_badge(self, xqueue): template_file=None, generate_pdf=True ) - self.assertFalse(BadgeAssertion.objects.filter(user=self.user, course_id=key)) + self.assertFalse(BadgeAssertion.objects.filter(user=self.user, badge_class=badge_class)) @override_settings(CERT_QUEUE='test-queue') @patch('capa.xqueue_interface.XQueueInterface.send_to_queue', spec=True) diff --git a/lms/djangoapps/certificates/tests/test_models.py b/lms/djangoapps/certificates/tests/test_models.py index 41d38d26e266..24dbf701acfd 100644 --- a/lms/djangoapps/certificates/tests/test_models.py +++ b/lms/djangoapps/certificates/tests/test_models.py @@ -1,20 +1,18 @@ """Tests for certificate Django models. """ from django.conf import settings from django.core.exceptions import ValidationError -from django.core.files.images import ImageFile from django.core.files.uploadedfile import SimpleUploadedFile from django.test import TestCase from django.test.utils import override_settings from nose.plugins.attrib import attr +from opaque_keys.edx.locator import CourseLocator from path import Path as path -from opaque_keys.edx.locator import CourseLocator from certificates.models import ( ExampleCertificate, ExampleCertificateSet, CertificateHtmlViewConfiguration, - CertificateTemplateAsset, - BadgeImageConfiguration) + CertificateTemplateAsset) FEATURES_INVALID_FILE_PATH = settings.FEATURES.copy() FEATURES_INVALID_FILE_PATH['CERTS_HTML_VIEW_CONFIG_PATH'] = 'invalid/path/to/config.json' @@ -159,55 +157,6 @@ def test_get_no_database_no_file(self): self.assertEquals(self.config.get_config(), {}) -@attr('shard_1') -class BadgeImageConfigurationTest(TestCase): - """ - Test the validation features of BadgeImageConfiguration. - """ - def get_image(self, name): - """ - Get one of the test images from the test data directory. - """ - return ImageFile(open(TEST_DATA_ROOT / 'badges' / name + '.png')) - - def create_clean(self, file_obj): - """ - Shortcut to create a BadgeImageConfiguration with a specific file. - """ - BadgeImageConfiguration(mode='honor', icon=file_obj).full_clean() - - def test_good_image(self): - """ - Verify that saving a valid badge image is no problem. - """ - good = self.get_image('good') - BadgeImageConfiguration(mode='honor', icon=good).full_clean() - - def test_unbalanced_image(self): - """ - Verify that setting an image with an uneven width and height raises an error. - """ - unbalanced = ImageFile(self.get_image('unbalanced')) - self.assertRaises(ValidationError, self.create_clean, unbalanced) - - def test_large_image(self): - """ - Verify that setting an image that is too big raises an error. - """ - large = self.get_image('large') - self.assertRaises(ValidationError, self.create_clean, large) - - def test_no_double_default(self): - """ - Verify that creating two configurations as default is not permitted. - """ - BadgeImageConfiguration(mode='test', icon=self.get_image('good'), default=True).save() - self.assertRaises( - ValidationError, - BadgeImageConfiguration(mode='test2', icon=self.get_image('good'), default=True).full_clean - ) - - @attr('shard_1') class CertificateTemplateAssetTest(TestCase): """ diff --git a/lms/djangoapps/certificates/tests/test_views.py b/lms/djangoapps/certificates/tests/test_views.py index 7c1c73f11808..ee936faa19c5 100644 --- a/lms/djangoapps/certificates/tests/test_views.py +++ b/lms/djangoapps/certificates/tests/test_views.py @@ -1,25 +1,17 @@ """Tests for certificates views. """ import json -import ddt from uuid import uuid4 -from nose.plugins.attrib import attr -from mock import patch +import ddt from django.conf import settings from django.core.cache import cache from django.core.urlresolvers import reverse from django.test import TestCase from django.test.client import Client from django.test.utils import override_settings - +from nose.plugins.attrib import attr from opaque_keys.edx.locator import CourseLocator -from openedx.core.lib.tests.assertions.events import assert_event_matches -from student.tests.factories import UserFactory -from track.tests import EventTrackingTestCase -from xmodule.modulestore.tests.factories import CourseFactory -from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase -from util.testing import UrlResetMixin from certificates.api import get_certificate_url from certificates.models import ( @@ -28,10 +20,9 @@ GeneratedCertificate, CertificateHtmlViewConfiguration, ) - -from certificates.tests.factories import ( - BadgeAssertionFactory, -) +from student.tests.factories import UserFactory +from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase +from xmodule.modulestore.tests.factories import CourseFactory FEATURES_WITH_CERTS_ENABLED = settings.FEATURES.copy() FEATURES_WITH_CERTS_ENABLED['CERTIFICATES_HTML_VIEW'] = True @@ -338,51 +329,3 @@ def test_html_view_microsite_configuration_missing(self): self.assertNotIn('platform_microsite', response.content) self.assertNotIn('http://www.microsite.org', response.content) self.assertNotIn('This should not survive being overwritten by static content', response.content) - - -class TrackShareRedirectTest(UrlResetMixin, ModuleStoreTestCase, EventTrackingTestCase): - """ - Verifies the badge image share event is sent out. - """ - - @patch.dict(settings.FEATURES, {"ENABLE_OPENBADGES": True}) - def setUp(self): - super(TrackShareRedirectTest, self).setUp('certificates.urls') - self.client = Client() - self.course = CourseFactory.create( - org='testorg', number='run1', display_name='trackable course' - ) - self.assertion = BadgeAssertionFactory( - user=self.user, course_id=self.course.id, data={ - 'image': 'http://www.example.com/image.png', - 'json': {'id': 'http://www.example.com/assertion.json'}, - 'issuer': 'http://www.example.com/issuer.json' - }, - ) - - def test_social_event_sent(self): - test_url = '/certificates/badge_share_tracker/{}/social_network/{}/'.format( - unicode(self.course.id), - self.user.username, - ) - self.recreate_tracker() - response = self.client.get(test_url) - self.assertEqual(response.status_code, 302) - self.assertEqual(response['Location'], 'http://www.example.com/image.png') - assert_event_matches( - { - 'name': 'edx.badge.assertion.shared', - 'data': { - 'course_id': 'testorg/run1/trackable_course', - 'social_network': 'social_network', - # pylint: disable=no-member - 'assertion_id': self.assertion.id, - 'assertion_json_url': 'http://www.example.com/assertion.json', - 'assertion_image_url': 'http://www.example.com/image.png', - 'user_id': self.user.id, - 'issuer': 'http://www.example.com/issuer.json', - 'enrollment_mode': 'honor' - }, - }, - self.get_event() - ) diff --git a/lms/djangoapps/certificates/tests/test_webview_views.py b/lms/djangoapps/certificates/tests/test_webview_views.py index 76d799cbecd8..9a33ccf3e8e9 100644 --- a/lms/djangoapps/certificates/tests/test_webview_views.py +++ b/lms/djangoapps/certificates/tests/test_webview_views.py @@ -13,6 +13,7 @@ from django.test.client import Client from django.test.utils import override_settings +from badges.tests.factories import BadgeAssertionFactory, CourseCompleteImageConfigurationFactory from openedx.core.lib.tests.assertions.events import assert_event_matches from student.tests.factories import UserFactory, CourseEnrollmentFactory from student.roles import CourseStaffRole @@ -26,13 +27,12 @@ CertificateStatuses, CertificateSocialNetworks, CertificateTemplate, - CertificateHtmlViewConfiguration -) + CertificateHtmlViewConfiguration, + get_completion_badge) from certificates.tests.factories import ( CertificateHtmlViewConfigurationFactory, LinkedInAddToProfileConfigurationFactory, - BadgeAssertionFactory, ) from util import organizations_helpers as organizations_api from django.test.client import RequestFactory @@ -40,6 +40,8 @@ FEATURES_WITH_CERTS_ENABLED = settings.FEATURES.copy() FEATURES_WITH_CERTS_ENABLED['CERTIFICATES_HTML_VIEW'] = True +FEATURES_WITH_BADGES_ENABLED = FEATURES_WITH_CERTS_ENABLED.copy() +FEATURES_WITH_BADGES_ENABLED['ENABLE_OPENBADGES'] = True FEATURES_WITH_CERTS_DISABLED = settings.FEATURES.copy() FEATURES_WITH_CERTS_DISABLED['CERTIFICATES_HTML_VIEW'] = False @@ -95,10 +97,11 @@ def setUp(self): ) CourseEnrollmentFactory.create( user=self.user, - course_id=self.course_id + course_id=self.course_id, ) CertificateHtmlViewConfigurationFactory.create() LinkedInAddToProfileConfigurationFactory.create() + CourseCompleteImageConfigurationFactory.create() def _add_course_certificates(self, count=1, signatory_count=0, is_active=True): """ @@ -221,7 +224,7 @@ def test_rendering_course_organization_data(self): ) self.assertIn('logo_test1.png', response.content) - @override_settings(FEATURES=FEATURES_WITH_CERTS_ENABLED) + @override_settings(FEATURES=FEATURES_WITH_BADGES_ENABLED) @patch.dict("django.conf.settings.SOCIAL_SHARING_SETTINGS", { "CERTIFICATE_TWITTER": True, "CERTIFICATE_FACEBOOK": True, @@ -243,8 +246,9 @@ def test_rendering_maximum_data(self): test_org = organizations_api.add_organization(organization_data=test_organization_data) organizations_api.add_organization_course(organization_data=test_org, course_id=unicode(self.course.id)) self._add_course_certificates(count=1, signatory_count=1, is_active=True) + badge_class = get_completion_badge(course_id=self.course_id, user=self.user) BadgeAssertionFactory.create( - user=self.user, course_id=self.course_id, + user=self.user, badge_class=badge_class, ) self.course.cert_html_view_overrides = { "logo_src": "/static/certificates/images/course_override_logo.png" @@ -593,8 +597,15 @@ def test_evidence_event_sent(self): test_url = '{}?evidence_visit=1'.format(cert_url) self._add_course_certificates(count=1, signatory_count=2) self.recreate_tracker() + badge_class = get_completion_badge(self.course_id, self.user) assertion = BadgeAssertionFactory.create( - user=self.user, course_id=self.course_id, + user=self.user, badge_class=badge_class, + backend='DummyBackend', + image_url='http://www.example.com/image.png', + assertion_url='http://www.example.com/assertion.json', + data={ + 'issuer': 'http://www.example.com/issuer.json', + } ) response = self.client.get(test_url) self.assertEqual(response.status_code, 200) @@ -605,6 +616,10 @@ def test_evidence_event_sent(self): 'course_id': 'testorg/run1/refundable_course', # pylint: disable=no-member 'assertion_id': assertion.id, + 'badge_generator': u'DummyBackend', + 'badge_name': u'refundable course', + 'issuing_component': u'', + 'badge_slug': u'testorgrun1refundable_course_honor_432f164', 'assertion_json_url': 'http://www.example.com/assertion.json', 'assertion_image_url': 'http://www.example.com/image.png', 'user_id': self.user.id, diff --git a/lms/djangoapps/certificates/tests/tests.py b/lms/djangoapps/certificates/tests/tests.py index a3e06855b278..be00d407e899 100644 --- a/lms/djangoapps/certificates/tests/tests.py +++ b/lms/djangoapps/certificates/tests/tests.py @@ -6,10 +6,11 @@ from django.conf import settings from nose.plugins.attrib import attr +from badges.tests.factories import CourseCompleteImageConfigurationFactory from xmodule.modulestore.tests.factories import CourseFactory from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase -from student.tests.factories import UserFactory +from student.tests.factories import UserFactory, CourseEnrollmentFactory from certificates.models import ( CertificateStatuses, GeneratedCertificate, @@ -84,10 +85,12 @@ def test_course_milestone_collected(self): self.assertEqual(completed_milestones[0]['namespace'], unicode(pre_requisite_course.id)) @patch.dict(settings.FEATURES, {'ENABLE_OPENBADGES': True}) - @patch('certificates.badge_handler.BadgeHandler', spec=True) + @patch('badges.backends.badgr.BadgrBackend', spec=True) def test_badge_callback(self, handler): student = UserFactory() course = CourseFactory.create(org='edx', number='998', display_name='Test Course', issue_badges=True) + CourseCompleteImageConfigurationFactory() + CourseEnrollmentFactory(user=student, course_id=course.location.course_key, mode='honor') cert = GeneratedCertificateFactory.create( user=student, course_id=course.id, diff --git a/lms/djangoapps/certificates/urls.py b/lms/djangoapps/certificates/urls.py index 73865ed091ab..6cff00b48d2c 100644 --- a/lms/djangoapps/certificates/urls.py +++ b/lms/djangoapps/certificates/urls.py @@ -23,15 +23,3 @@ url(r'search', views.search_by_user, name="search"), url(r'regenerate', views.regenerate_certificate_for_user, name="regenerate_certificate_for_user"), ) - - -if settings.FEATURES.get("ENABLE_OPENBADGES", False): - urlpatterns += ( - url( - r'^badge_share_tracker/{}/(?P[^/]+)/(?P[^/]+)/$'.format( - settings.COURSE_ID_PATTERN - ), - views.track_share_redirect, - name='badge_share_tracker' - ), - ) diff --git a/lms/djangoapps/certificates/views/__init__.py b/lms/djangoapps/certificates/views/__init__.py index 3b65c22ceeb7..1b4b8cd4ae58 100644 --- a/lms/djangoapps/certificates/views/__init__.py +++ b/lms/djangoapps/certificates/views/__init__.py @@ -5,4 +5,3 @@ from .xqueue import * from .support import * from .webview import * -from .badges import * diff --git a/lms/djangoapps/certificates/views/badges.py b/lms/djangoapps/certificates/views/badges.py deleted file mode 100644 index db9ebceed759..000000000000 --- a/lms/djangoapps/certificates/views/badges.py +++ /dev/null @@ -1,31 +0,0 @@ -""" -Certificate views for open badges. -""" -from django.shortcuts import redirect, get_object_or_404 - -from opaque_keys.edx.locator import CourseLocator -from util.views import ensure_valid_course_key -from eventtracking import tracker -from certificates.models import BadgeAssertion - - -@ensure_valid_course_key -def track_share_redirect(request__unused, course_id, network, student_username): - """ - Tracks when a user downloads a badge for sharing. - """ - course_id = CourseLocator.from_string(course_id) - assertion = get_object_or_404(BadgeAssertion, user__username=student_username, course_id=course_id) - tracker.emit( - 'edx.badge.assertion.shared', { - 'course_id': unicode(course_id), - 'social_network': network, - 'assertion_id': assertion.id, - 'assertion_json_url': assertion.data['json']['id'], - 'assertion_image_url': assertion.image_url, - 'user_id': assertion.user.id, - 'enrollment_mode': assertion.mode, - 'issuer': assertion.data['issuer'], - } - ) - return redirect(assertion.image_url) diff --git a/lms/djangoapps/certificates/views/webview.py b/lms/djangoapps/certificates/views/webview.py index cf819d91c0fb..c4701b6cf29d 100644 --- a/lms/djangoapps/certificates/views/webview.py +++ b/lms/djangoapps/certificates/views/webview.py @@ -15,8 +15,8 @@ from django.utils.encoding import smart_str from django.core.urlresolvers import reverse -from courseware.courses import course_image_url from courseware.access import has_access +from courseware.courses import course_image_url from edxmako.shortcuts import render_to_response from edxmako.template import Template from eventtracking import tracker @@ -40,8 +40,8 @@ GeneratedCertificate, CertificateHtmlViewConfiguration, CertificateSocialNetworks, - BadgeAssertion -) + get_completion_badge) + log = logging.getLogger(__name__) @@ -375,21 +375,37 @@ def _track_certificate_events(request, context, course, user, user_certificate): """ Tracks web certificate view related events. """ - badge = context['badge'] # Badge Request Event Tracking Logic - if 'evidence_visit' in request.GET and badge: - tracker.emit( - 'edx.badge.assertion.evidence_visited', - { - 'user_id': user.id, - 'course_id': unicode(course.id), - 'enrollment_mode': badge.mode, - 'assertion_id': badge.id, - 'assertion_image_url': badge.data['image'], - 'assertion_json_url': badge.data['json']['id'], - 'issuer': badge.data['issuer'], - } - ) + course_key = course.location.course_key + + if 'evidence_visit' in request.GET: + badge_class = get_completion_badge(course_key, user) + badges = badge_class.get_for_user(user) + if badges: + # There should only ever be one of these. + badge = badges[0] + tracker.emit( + 'edx.badge.assertion.evidence_visited', + { + 'badge_name': badge.badge_class.display_name, + 'badge_slug': badge.badge_class.slug, + 'badge_generator': badge.backend, + 'issuing_component': badge.badge_class.issuing_component, + 'user_id': user.id, + 'course_id': unicode(course_key), + 'enrollment_mode': badge.badge_class.mode, + 'assertion_id': badge.id, + 'assertion_image_url': badge.image_url, + 'assertion_json_url': badge.assertion_url, + 'issuer': badge.data.get('issuer'), + } + ) + else: + log.warn( + "Could not find badge for %s on course %s.", + user.id, + course_key, + ) # track certificate evidence_visited event for analytics when certificate_user and accessing_user are different if request.user and request.user.id != user.id: @@ -446,10 +462,11 @@ def _update_badge_context(context, course, user): """ Updates context with badge info. """ - try: - badge = BadgeAssertion.objects.get(user=user, course_id=course.location.course_key) - except BadgeAssertion.DoesNotExist: - badge = None + badge = None + if settings.FEATURES.get('ENABLE_OPENBADGES'): + badges = get_completion_badge(course.location.course_key, user).get_for_user(user) + if badges: + badge = badges[0] context['badge'] = badge diff --git a/lms/envs/aws.py b/lms/envs/aws.py index 92a629fe2ffc..0bbfc2db71c7 100644 --- a/lms/envs/aws.py +++ b/lms/envs/aws.py @@ -287,6 +287,7 @@ BADGR_API_TOKEN = ENV_TOKENS.get('BADGR_API_TOKEN', BADGR_API_TOKEN) BADGR_BASE_URL = ENV_TOKENS.get('BADGR_BASE_URL', BADGR_BASE_URL) BADGR_ISSUER_SLUG = ENV_TOKENS.get('BADGR_ISSUER_SLUG', BADGR_ISSUER_SLUG) +BADGR_TIMEOUT = ENV_TOKENS.get('BADGR_TIMEOUT', BADGR_TIMEOUT) # git repo loading environment GIT_REPO_DIR = ENV_TOKENS.get('GIT_REPO_DIR', '/edx/var/edxapp/course_repos') diff --git a/lms/envs/common.py b/lms/envs/common.py index 69763872c73c..15787218c766 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -2004,6 +2004,9 @@ 'openedx.core.djangoapps.self_paced', 'sorl.thumbnail', + + # Needed whether or not enabled, due to migrations + 'badges', ) # Migrations which are not in the standard module "migrations" @@ -2218,12 +2221,17 @@ CERT_NAME_SHORT = "Certificate" CERT_NAME_LONG = "Certificate of Achievement" -#################### Badgr OpenBadges generation ####################### +#################### OpenBadges Settings ####################### + +BADGING_BACKEND = 'badges.backends.badgr.BadgrBackend' + # Be sure to set up images for course modes using the BadgeImageConfiguration model in the certificates app. BADGR_API_TOKEN = None # Do not add the trailing slash here. BADGR_BASE_URL = "http://localhost:8005" BADGR_ISSUER_SLUG = "example-issuer" +# Number of seconds to wait on the badging server when contacting it before giving up. +BADGR_TIMEOUT = 10 ###################### Grade Downloads ###################### GRADES_DOWNLOAD_ROUTING_KEY = HIGH_MEM_QUEUE