Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
f8f23240
Commit
f8f23240
authored
Aug 13, 2015
by
Matt Drayer
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #8996 from edx/ziafazal/SOL-1044
ziafazal/SOL-1044: Custom Web Certificates
parents
c197e725
2467d697
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
639 additions
and
10 deletions
+639
-10
common/djangoapps/util/organizations_helpers.py
+10
-1
lms/djangoapps/certificates/admin.py
+38
-1
lms/djangoapps/certificates/api.py
+43
-1
lms/djangoapps/certificates/migrations/0023_auto__del_unique_badgeassertion_course_id_user__add_unique_badgeassert.py
+151
-0
lms/djangoapps/certificates/migrations/0024_auto__add_certificatetemplate__add_unique_certificatetemplate_organiza.py
+198
-0
lms/djangoapps/certificates/models.py
+82
-0
lms/djangoapps/certificates/tests/test_views.py
+99
-0
lms/djangoapps/certificates/views/webview.py
+18
-7
No files found.
common/djangoapps/util/organizations_helpers.py
View file @
f8f23240
...
...
@@ -4,6 +4,7 @@ Utility library for working with the edx-organizations app
"""
from
django.conf
import
settings
from
django.db.utils
import
DatabaseError
def
add_organization
(
organization_data
):
...
...
@@ -43,7 +44,15 @@ def get_organizations():
if
not
settings
.
FEATURES
.
get
(
'ORGANIZATIONS_APP'
,
False
):
return
[]
from
organizations
import
api
as
organizations_api
return
organizations_api
.
get_organizations
()
# Due to the way unit tests run for edx-platform, models are not yet available at the time
# of Django admin form instantiation. This unfortunately results in an invocation of the following
# workflow, because the test configuration is (correctly) configured to exercise the application
# The good news is that this case does not manifest in the Real World, because migrations have
# been run ahead of application instantiation and the flag set only when that is truly the case.
try
:
return
organizations_api
.
get_organizations
()
except
DatabaseError
:
return
[]
def
get_organization_courses
(
organization_id
):
...
...
lms/djangoapps/certificates/admin.py
View file @
f8f23240
...
...
@@ -2,12 +2,49 @@
django admin pages for certificates models
"""
from
django.contrib
import
admin
from
django
import
forms
from
config_models.admin
import
ConfigurationModelAdmin
from
util.organizations_helpers
import
get_organizations
from
certificates.models
import
(
CertificateGenerationConfiguration
,
CertificateHtmlViewConfiguration
,
BadgeImageConfiguration
CertificateGenerationConfiguration
,
CertificateHtmlViewConfiguration
,
BadgeImageConfiguration
,
CertificateTemplate
,
CertificateTemplateAsset
,
)
class
CertificateTemplateForm
(
forms
.
ModelForm
):
"""
Django admin form for CertificateTemplate model
"""
organizations
=
get_organizations
()
org_choices
=
[(
org
[
"id"
],
org
[
"name"
])
for
org
in
organizations
]
org_choices
.
insert
(
0
,
(
''
,
'None'
))
organization_id
=
forms
.
TypedChoiceField
(
choices
=
org_choices
,
required
=
False
,
coerce
=
int
,
empty_value
=
None
)
class
Meta
(
object
):
""" Meta definitions for CertificateTemplateForm """
model
=
CertificateTemplate
class
CertificateTemplateAdmin
(
admin
.
ModelAdmin
):
"""
Django admin customizations for CertificateTemplate model
"""
list_display
=
(
'name'
,
'description'
,
'organization_id'
,
'course_key'
,
'mode'
,
'is_active'
)
form
=
CertificateTemplateForm
class
CertificateTemplateAssetAdmin
(
admin
.
ModelAdmin
):
"""
Django admin customizations for CertificateTemplateAsset model
"""
list_display
=
(
'description'
,
'__unicode__'
)
admin
.
site
.
register
(
CertificateGenerationConfiguration
)
admin
.
site
.
register
(
CertificateHtmlViewConfiguration
,
ConfigurationModelAdmin
)
admin
.
site
.
register
(
BadgeImageConfiguration
)
admin
.
site
.
register
(
CertificateTemplate
,
CertificateTemplateAdmin
)
admin
.
site
.
register
(
CertificateTemplateAsset
,
CertificateTemplateAssetAdmin
)
lms/djangoapps/certificates/api.py
View file @
f8f23240
...
...
@@ -14,6 +14,7 @@ from opaque_keys.edx.keys import CourseKey
from
openedx.core.djangoapps.content.course_overviews.models
import
CourseOverview
from
xmodule.modulestore.django
import
modulestore
from
util.organizations_helpers
import
get_course_organizations
from
certificates.models
import
(
CertificateStatuses
,
...
...
@@ -21,7 +22,8 @@ from certificates.models import (
CertificateGenerationCourseSetting
,
CertificateGenerationConfiguration
,
ExampleCertificateSet
,
GeneratedCertificate
GeneratedCertificate
,
CertificateTemplate
,
)
from
certificates.queue
import
XQueueCertInterface
...
...
@@ -373,6 +375,46 @@ def get_active_web_certificate(course, is_preview_mode=None):
return
None
def
get_certificate_template
(
course_key
,
mode
):
"""
Retrieves the custom certificate template based on course_key and mode.
"""
org_id
,
template
=
None
,
None
# fetch organization of the course
course_organization
=
get_course_organizations
(
course_key
)
if
course_organization
:
org_id
=
course_organization
[
0
][
'id'
]
if
org_id
and
mode
:
template
=
CertificateTemplate
.
objects
.
filter
(
organization_id
=
org_id
,
course_key
=
course_key
,
mode
=
mode
,
is_active
=
True
)
# if don't template find by org and mode
if
not
template
and
org_id
and
mode
:
template
=
CertificateTemplate
.
objects
.
filter
(
organization_id
=
org_id
,
mode
=
mode
,
is_active
=
True
)
# if don't template find by only org
if
not
template
and
org_id
:
template
=
CertificateTemplate
.
objects
.
filter
(
organization_id
=
org_id
,
is_active
=
True
)
# if we still don't template find by only course mode
if
not
template
and
mode
:
template
=
CertificateTemplate
.
objects
.
filter
(
mode
=
mode
,
is_active
=
True
)
return
template
[
0
]
.
template
if
template
else
None
def
emit_certificate_event
(
event_name
,
user
,
course_id
,
course
=
None
,
event_data
=
None
):
"""
Emits certificate event.
...
...
lms/djangoapps/certificates/migrations/0023_auto__del_unique_badgeassertion_course_id_user__add_unique_badgeassert.py
0 → 100644
View file @
f8f23240
# -*- coding: utf-8 -*-
from
south.utils
import
datetime_utils
as
datetime
from
south.db
import
db
from
south.v2
import
SchemaMigration
from
django.db
import
models
class
Migration
(
SchemaMigration
):
def
forwards
(
self
,
orm
):
# Removing unique constraint on 'BadgeAssertion', fields ['course_id', 'user']
db
.
delete_unique
(
'certificates_badgeassertion'
,
[
'course_id'
,
'user_id'
])
# Adding unique constraint on 'BadgeAssertion', fields ['course_id', 'user', 'mode']
db
.
create_unique
(
'certificates_badgeassertion'
,
[
'course_id'
,
'user_id'
,
'mode'
])
def
backwards
(
self
,
orm
):
# Removing unique constraint on 'BadgeAssertion', fields ['course_id', 'user', 'mode']
db
.
delete_unique
(
'certificates_badgeassertion'
,
[
'course_id'
,
'user_id'
,
'mode'
])
# Adding unique constraint on 'BadgeAssertion', fields ['course_id', 'user']
db
.
create_unique
(
'certificates_badgeassertion'
,
[
'course_id'
,
'user_id'
])
models
=
{
'auth.group'
:
{
'Meta'
:
{
'object_name'
:
'Group'
},
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'80'
}),
'permissions'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
"orm['auth.Permission']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
})
},
'auth.permission'
:
{
'Meta'
:
{
'ordering'
:
"('content_type__app_label', 'content_type__model', 'codename')"
,
'unique_together'
:
"(('content_type', 'codename'),)"
,
'object_name'
:
'Permission'
},
'codename'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'content_type'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['contenttypes.ContentType']"
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'50'
})
},
'auth.user'
:
{
'Meta'
:
{
'object_name'
:
'User'
},
'date_joined'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'email'
:
(
'django.db.models.fields.EmailField'
,
[],
{
'max_length'
:
'75'
,
'blank'
:
'True'
}),
'first_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'30'
,
'blank'
:
'True'
}),
'groups'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
"orm['auth.Group']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'is_active'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'is_staff'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'is_superuser'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'last_login'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'last_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'30'
,
'blank'
:
'True'
}),
'password'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'128'
}),
'user_permissions'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
"orm['auth.Permission']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
}),
'username'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'30'
})
},
'certificates.badgeassertion'
:
{
'Meta'
:
{
'unique_together'
:
"(('course_id', 'user', 'mode'),)"
,
'object_name'
:
'BadgeAssertion'
},
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'default'
:
'None'
,
'max_length'
:
'255'
,
'blank'
:
'True'
}),
'data'
:
(
'django.db.models.fields.TextField'
,
[],
{
'default'
:
"'{}'"
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'mode'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'user'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
})
},
'certificates.badgeimageconfiguration'
:
{
'Meta'
:
{
'object_name'
:
'BadgeImageConfiguration'
},
'default'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'icon'
:
(
'django.db.models.fields.files.ImageField'
,
[],
{
'max_length'
:
'100'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'mode'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'125'
})
},
'certificates.certificategenerationconfiguration'
:
{
'Meta'
:
{
'ordering'
:
"('-change_date',)"
,
'object_name'
:
'CertificateGenerationConfiguration'
},
'change_date'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'changed_by'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
,
'null'
:
'True'
,
'on_delete'
:
'models.PROTECT'
}),
'enabled'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
})
},
'certificates.certificategenerationcoursesetting'
:
{
'Meta'
:
{
'object_name'
:
'CertificateGenerationCourseSetting'
},
'course_key'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'max_length'
:
'255'
,
'db_index'
:
'True'
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'enabled'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
})
},
'certificates.certificatehtmlviewconfiguration'
:
{
'Meta'
:
{
'ordering'
:
"('-change_date',)"
,
'object_name'
:
'CertificateHtmlViewConfiguration'
},
'change_date'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'changed_by'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
,
'null'
:
'True'
,
'on_delete'
:
'models.PROTECT'
}),
'configuration'
:
(
'django.db.models.fields.TextField'
,
[],
{}),
'enabled'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
})
},
'certificates.certificatewhitelist'
:
{
'Meta'
:
{
'object_name'
:
'CertificateWhitelist'
},
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'default'
:
'None'
,
'max_length'
:
'255'
,
'blank'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'user'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
}),
'whitelist'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
})
},
'certificates.examplecertificate'
:
{
'Meta'
:
{
'object_name'
:
'ExampleCertificate'
},
'access_key'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'25c5af67da3d47039aa8b00b3a929fa9'"
,
'max_length'
:
'255'
,
'db_index'
:
'True'
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'description'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
}),
'download_url'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
'None'
,
'max_length'
:
'255'
,
'null'
:
'True'
}),
'error_reason'
:
(
'django.db.models.fields.TextField'
,
[],
{
'default'
:
'None'
,
'null'
:
'True'
}),
'example_cert_set'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['certificates.ExampleCertificateSet']"
}),
'full_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"u'John Do
\\
xeb'"
,
'max_length'
:
'255'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'status'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'started'"
,
'max_length'
:
'255'
}),
'template'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
}),
'uuid'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'88190407a2f14c429a7b5336e3fb0189'"
,
'unique'
:
'True'
,
'max_length'
:
'255'
,
'db_index'
:
'True'
})
},
'certificates.examplecertificateset'
:
{
'Meta'
:
{
'object_name'
:
'ExampleCertificateSet'
},
'course_key'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'max_length'
:
'255'
,
'db_index'
:
'True'
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
})
},
'certificates.generatedcertificate'
:
{
'Meta'
:
{
'unique_together'
:
"(('user', 'course_id'),)"
,
'object_name'
:
'GeneratedCertificate'
},
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'default'
:
'None'
,
'max_length'
:
'255'
,
'blank'
:
'True'
}),
'created_date'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime.now'
,
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'distinction'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'download_url'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"''"
,
'max_length'
:
'128'
,
'blank'
:
'True'
}),
'download_uuid'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"''"
,
'max_length'
:
'32'
,
'blank'
:
'True'
}),
'error_reason'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"''"
,
'max_length'
:
'512'
,
'blank'
:
'True'
}),
'grade'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"''"
,
'max_length'
:
'5'
,
'blank'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'key'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"''"
,
'max_length'
:
'32'
,
'blank'
:
'True'
}),
'mode'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'honor'"
,
'max_length'
:
'32'
}),
'modified_date'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime.now'
,
'auto_now'
:
'True'
,
'blank'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'blank'
:
'True'
}),
'status'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'unavailable'"
,
'max_length'
:
'32'
}),
'user'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
}),
'verify_uuid'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"''"
,
'max_length'
:
'32'
,
'blank'
:
'True'
})
},
'contenttypes.contenttype'
:
{
'Meta'
:
{
'ordering'
:
"('name',)"
,
'unique_together'
:
"(('app_label', 'model'),)"
,
'object_name'
:
'ContentType'
,
'db_table'
:
"'django_content_type'"
},
'app_label'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'model'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
})
}
}
complete_apps
=
[
'certificates'
]
\ No newline at end of file
lms/djangoapps/certificates/migrations/0024_auto__add_certificatetemplate__add_unique_certificatetemplate_organiza.py
0 → 100644
View file @
f8f23240
# -*- coding: utf-8 -*-
from
south.utils
import
datetime_utils
as
datetime
from
south.db
import
db
from
south.v2
import
SchemaMigration
from
django.db
import
models
class
Migration
(
SchemaMigration
):
def
forwards
(
self
,
orm
):
# Adding model 'CertificateTemplate'
db
.
create_table
(
'certificates_certificatetemplate'
,
(
(
'id'
,
self
.
gf
(
'django.db.models.fields.AutoField'
)(
primary_key
=
True
)),
(
'created'
,
self
.
gf
(
'model_utils.fields.AutoCreatedField'
)(
default
=
datetime
.
datetime
.
now
)),
(
'modified'
,
self
.
gf
(
'model_utils.fields.AutoLastModifiedField'
)(
default
=
datetime
.
datetime
.
now
)),
(
'name'
,
self
.
gf
(
'django.db.models.fields.CharField'
)(
max_length
=
255
)),
(
'description'
,
self
.
gf
(
'django.db.models.fields.CharField'
)(
max_length
=
255
,
null
=
True
,
blank
=
True
)),
(
'template'
,
self
.
gf
(
'django.db.models.fields.TextField'
)()),
(
'organization_id'
,
self
.
gf
(
'django.db.models.fields.IntegerField'
)(
db_index
=
True
,
null
=
True
,
blank
=
True
)),
(
'course_key'
,
self
.
gf
(
'xmodule_django.models.CourseKeyField'
)(
db_index
=
True
,
max_length
=
255
,
null
=
True
,
blank
=
True
)),
(
'mode'
,
self
.
gf
(
'django.db.models.fields.CharField'
)(
default
=
'honor'
,
max_length
=
125
,
null
=
True
,
blank
=
True
)),
(
'is_active'
,
self
.
gf
(
'django.db.models.fields.BooleanField'
)(
default
=
False
)),
))
db
.
send_create_signal
(
'certificates'
,
[
'CertificateTemplate'
])
# Adding unique constraint on 'CertificateTemplate', fields ['organization_id', 'course_key', 'mode']
db
.
create_unique
(
'certificates_certificatetemplate'
,
[
'organization_id'
,
'course_key'
,
'mode'
])
# Adding model 'CertificateTemplateAsset'
db
.
create_table
(
'certificates_certificatetemplateasset'
,
(
(
'id'
,
self
.
gf
(
'django.db.models.fields.AutoField'
)(
primary_key
=
True
)),
(
'created'
,
self
.
gf
(
'model_utils.fields.AutoCreatedField'
)(
default
=
datetime
.
datetime
.
now
)),
(
'modified'
,
self
.
gf
(
'model_utils.fields.AutoLastModifiedField'
)(
default
=
datetime
.
datetime
.
now
)),
(
'description'
,
self
.
gf
(
'django.db.models.fields.CharField'
)(
max_length
=
255
,
null
=
True
,
blank
=
True
)),
(
'asset'
,
self
.
gf
(
'django.db.models.fields.files.FileField'
)(
max_length
=
255
)),
))
db
.
send_create_signal
(
'certificates'
,
[
'CertificateTemplateAsset'
])
def
backwards
(
self
,
orm
):
# Removing unique constraint on 'CertificateTemplate', fields ['organization_id', 'course_key', 'mode']
db
.
delete_unique
(
'certificates_certificatetemplate'
,
[
'organization_id'
,
'course_key'
,
'mode'
])
# Deleting model 'CertificateTemplate'
db
.
delete_table
(
'certificates_certificatetemplate'
)
# Deleting model 'CertificateTemplateAsset'
db
.
delete_table
(
'certificates_certificatetemplateasset'
)
models
=
{
'auth.group'
:
{
'Meta'
:
{
'object_name'
:
'Group'
},
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'80'
}),
'permissions'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
"orm['auth.Permission']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
})
},
'auth.permission'
:
{
'Meta'
:
{
'ordering'
:
"('content_type__app_label', 'content_type__model', 'codename')"
,
'unique_together'
:
"(('content_type', 'codename'),)"
,
'object_name'
:
'Permission'
},
'codename'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'content_type'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['contenttypes.ContentType']"
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'50'
})
},
'auth.user'
:
{
'Meta'
:
{
'object_name'
:
'User'
},
'date_joined'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'email'
:
(
'django.db.models.fields.EmailField'
,
[],
{
'max_length'
:
'75'
,
'blank'
:
'True'
}),
'first_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'30'
,
'blank'
:
'True'
}),
'groups'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
"orm['auth.Group']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'is_active'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'is_staff'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'is_superuser'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'last_login'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'last_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'30'
,
'blank'
:
'True'
}),
'password'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'128'
}),
'user_permissions'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
"orm['auth.Permission']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
}),
'username'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'30'
})
},
'certificates.badgeassertion'
:
{
'Meta'
:
{
'unique_together'
:
"(('course_id', 'user', 'mode'),)"
,
'object_name'
:
'BadgeAssertion'
},
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'default'
:
'None'
,
'max_length'
:
'255'
,
'blank'
:
'True'
}),
'data'
:
(
'django.db.models.fields.TextField'
,
[],
{
'default'
:
"'{}'"
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'mode'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'user'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
})
},
'certificates.badgeimageconfiguration'
:
{
'Meta'
:
{
'object_name'
:
'BadgeImageConfiguration'
},
'default'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'icon'
:
(
'django.db.models.fields.files.ImageField'
,
[],
{
'max_length'
:
'100'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'mode'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'125'
})
},
'certificates.certificategenerationconfiguration'
:
{
'Meta'
:
{
'ordering'
:
"('-change_date',)"
,
'object_name'
:
'CertificateGenerationConfiguration'
},
'change_date'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'changed_by'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
,
'null'
:
'True'
,
'on_delete'
:
'models.PROTECT'
}),
'enabled'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
})
},
'certificates.certificategenerationcoursesetting'
:
{
'Meta'
:
{
'object_name'
:
'CertificateGenerationCourseSetting'
},
'course_key'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'max_length'
:
'255'
,
'db_index'
:
'True'
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'enabled'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
})
},
'certificates.certificatehtmlviewconfiguration'
:
{
'Meta'
:
{
'ordering'
:
"('-change_date',)"
,
'object_name'
:
'CertificateHtmlViewConfiguration'
},
'change_date'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'changed_by'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
,
'null'
:
'True'
,
'on_delete'
:
'models.PROTECT'
}),
'configuration'
:
(
'django.db.models.fields.TextField'
,
[],
{}),
'enabled'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
})
},
'certificates.certificatetemplate'
:
{
'Meta'
:
{
'unique_together'
:
"(('organization_id', 'course_key', 'mode'),)"
,
'object_name'
:
'CertificateTemplate'
},
'course_key'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'db_index'
:
'True'
,
'max_length'
:
'255'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'description'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'is_active'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'mode'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'honor'"
,
'max_length'
:
'125'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
}),
'organization_id'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'db_index'
:
'True'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'template'
:
(
'django.db.models.fields.TextField'
,
[],
{})
},
'certificates.certificatetemplateasset'
:
{
'Meta'
:
{
'object_name'
:
'CertificateTemplateAsset'
},
'asset'
:
(
'django.db.models.fields.files.FileField'
,
[],
{
'max_length'
:
'255'
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'description'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
})
},
'certificates.certificatewhitelist'
:
{
'Meta'
:
{
'object_name'
:
'CertificateWhitelist'
},
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'default'
:
'None'
,
'max_length'
:
'255'
,
'blank'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'user'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
}),
'whitelist'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
})
},
'certificates.examplecertificate'
:
{
'Meta'
:
{
'object_name'
:
'ExampleCertificate'
},
'access_key'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'f14d7721cd154a57a4fb52b9d4b4bc75'"
,
'max_length'
:
'255'
,
'db_index'
:
'True'
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'description'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
}),
'download_url'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
'None'
,
'max_length'
:
'255'
,
'null'
:
'True'
}),
'error_reason'
:
(
'django.db.models.fields.TextField'
,
[],
{
'default'
:
'None'
,
'null'
:
'True'
}),
'example_cert_set'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['certificates.ExampleCertificateSet']"
}),
'full_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"u'John Do
\\
xeb'"
,
'max_length'
:
'255'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'status'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'started'"
,
'max_length'
:
'255'
}),
'template'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
}),
'uuid'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'789810b9a54b4dd5bae3feec5b4e9fdb'"
,
'unique'
:
'True'
,
'max_length'
:
'255'
,
'db_index'
:
'True'
})
},
'certificates.examplecertificateset'
:
{
'Meta'
:
{
'object_name'
:
'ExampleCertificateSet'
},
'course_key'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'max_length'
:
'255'
,
'db_index'
:
'True'
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
})
},
'certificates.generatedcertificate'
:
{
'Meta'
:
{
'unique_together'
:
"(('user', 'course_id'),)"
,
'object_name'
:
'GeneratedCertificate'
},
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'default'
:
'None'
,
'max_length'
:
'255'
,
'blank'
:
'True'
}),
'created_date'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime.now'
,
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'distinction'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'download_url'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"''"
,
'max_length'
:
'128'
,
'blank'
:
'True'
}),
'download_uuid'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"''"
,
'max_length'
:
'32'
,
'blank'
:
'True'
}),
'error_reason'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"''"
,
'max_length'
:
'512'
,
'blank'
:
'True'
}),
'grade'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"''"
,
'max_length'
:
'5'
,
'blank'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'key'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"''"
,
'max_length'
:
'32'
,
'blank'
:
'True'
}),
'mode'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'honor'"
,
'max_length'
:
'32'
}),
'modified_date'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime.now'
,
'auto_now'
:
'True'
,
'blank'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'blank'
:
'True'
}),
'status'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'unavailable'"
,
'max_length'
:
'32'
}),
'user'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
}),
'verify_uuid'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"''"
,
'max_length'
:
'32'
,
'blank'
:
'True'
})
},
'contenttypes.contenttype'
:
{
'Meta'
:
{
'ordering'
:
"('name',)"
,
'unique_together'
:
"(('app_label', 'model'),)"
,
'object_name'
:
'ContentType'
,
'db_table'
:
"'django_content_type'"
},
'app_label'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'model'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
})
}
}
complete_apps
=
[
'certificates'
]
\ No newline at end of file
lms/djangoapps/certificates/models.py
View file @
f8f23240
...
...
@@ -674,6 +674,88 @@ class BadgeImageConfiguration(models.Model):
return
cls
.
objects
.
get
(
default
=
True
)
.
icon
class
CertificateTemplate
(
TimeStampedModel
):
"""A set of custom web certificate templates.
Web certificate templates are Django web templates
to replace PDF certificate.
A particular course may have several kinds of certificate templates
(e.g. honor and verified).
"""
name
=
models
.
CharField
(
max_length
=
255
,
help_text
=
_
(
u'Name of template.'
),
)
description
=
models
.
CharField
(
max_length
=
255
,
null
=
True
,
blank
=
True
,
help_text
=
_
(
u'Description and/or admin notes.'
),
)
template
=
models
.
TextField
(
help_text
=
_
(
u'Django template HTML.'
),
)
organization_id
=
models
.
IntegerField
(
null
=
True
,
blank
=
True
,
db_index
=
True
,
help_text
=
_
(
u'Organization of template.'
),
)
course_key
=
CourseKeyField
(
max_length
=
255
,
null
=
True
,
blank
=
True
,
db_index
=
True
,
)
mode
=
models
.
CharField
(
max_length
=
125
,
choices
=
GeneratedCertificate
.
MODES
,
default
=
GeneratedCertificate
.
MODES
.
honor
,
null
=
True
,
blank
=
True
,
help_text
=
_
(
u'The course mode for this template.'
),
)
is_active
=
models
.
BooleanField
(
help_text
=
_
(
u'On/Off switch.'
),
default
=
False
,
)
def
__unicode__
(
self
):
return
u'
%
s'
%
(
self
.
name
,
)
class
Meta
(
object
):
# pylint: disable=missing-docstring
get_latest_by
=
'created'
unique_together
=
((
'organization_id'
,
'course_key'
,
'mode'
),)
class
CertificateTemplateAsset
(
TimeStampedModel
):
"""A set of assets to be used in custom web certificate templates.
This model stores assets used in custom web certificate templates
such as image, css files.
"""
description
=
models
.
CharField
(
max_length
=
255
,
null
=
True
,
blank
=
True
,
help_text
=
_
(
u'Description of the asset.'
),
)
asset
=
models
.
FileField
(
max_length
=
255
,
upload_to
=
'certificate_template_assets'
,
help_text
=
_
(
u'Asset file. It could be an image or css file.'
),
)
def
__unicode__
(
self
):
return
u'
%
s'
%
(
self
.
asset
.
url
,
)
# pylint: disable=no-member
class
Meta
(
object
):
# pylint: disable=missing-docstring
get_latest_by
=
'created'
@receiver
(
post_save
,
sender
=
GeneratedCertificate
)
#pylint: disable=unused-argument
def
create_badge
(
sender
,
instance
,
**
kwargs
):
...
...
lms/djangoapps/certificates/tests/test_views.py
View file @
f8f23240
...
...
@@ -30,6 +30,7 @@ from certificates.models import (
CertificateStatuses
,
CertificateHtmlViewConfiguration
,
CertificateSocialNetworks
,
CertificateTemplate
,
)
from
certificates.tests.factories
import
(
...
...
@@ -45,6 +46,11 @@ FEATURES_WITH_CERTS_ENABLED['CERTIFICATES_HTML_VIEW'] = True
FEATURES_WITH_CERTS_DISABLED
=
settings
.
FEATURES
.
copy
()
FEATURES_WITH_CERTS_DISABLED
[
'CERTIFICATES_HTML_VIEW'
]
=
False
FEATURES_WITH_CUSTOM_CERTS_ENABLED
=
{
"CUSTOM_CERTIFICATE_TEMPLATES_ENABLED"
:
True
}
FEATURES_WITH_CUSTOM_CERTS_ENABLED
.
update
(
FEATURES_WITH_CERTS_ENABLED
)
@attr
(
'shard_1'
)
@ddt.ddt
...
...
@@ -427,6 +433,30 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase):
self
.
course
.
save
()
self
.
store
.
update_item
(
self
.
course
,
self
.
user
.
id
)
def
_create_custom_template
(
self
,
org_id
=
None
,
mode
=
None
,
course_key
=
None
):
"""
Creates a custom certificate template entry in DB.
"""
template_html
=
"""
<html>
<body>
lang: ${LANGUAGE_CODE}
course name: ${accomplishment_copy_course_name}
mode: ${course_mode}
${accomplishment_copy_course_description}
</body>
</html>
"""
template
=
CertificateTemplate
(
name
=
'custom template'
,
template
=
template_html
,
organization_id
=
org_id
,
course_key
=
course_key
,
mode
=
mode
,
is_active
=
True
)
template
.
save
()
@override_settings
(
FEATURES
=
FEATURES_WITH_CERTS_ENABLED
)
def
test_rendering_course_organization_data
(
self
):
"""
...
...
@@ -724,6 +754,75 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase):
response_json
=
json
.
loads
(
response
.
content
)
self
.
assertEqual
(
CertificateStatuses
.
generating
,
response_json
[
'add_status'
])
@override_settings
(
FEATURES
=
FEATURES_WITH_CUSTOM_CERTS_ENABLED
)
@override_settings
(
LANGUAGE_CODE
=
'fr'
)
def
test_certificate_custom_template_with_org_mode_course
(
self
):
"""
Tests custom template search and rendering.
"""
self
.
_add_course_certificates
(
count
=
1
,
signatory_count
=
2
)
self
.
_create_custom_template
(
1
,
mode
=
'honor'
,
course_key
=
unicode
(
self
.
course
.
id
))
self
.
_create_custom_template
(
2
,
mode
=
'honor'
)
test_url
=
get_certificate_url
(
user_id
=
self
.
user
.
id
,
course_id
=
unicode
(
self
.
course
.
id
)
)
with
patch
(
'certificates.api.get_course_organizations'
)
as
mock_get_orgs
:
mock_get_orgs
.
side_effect
=
[
[{
"id"
:
1
,
"name"
:
"organization name"
}],
[{
"id"
:
2
,
"name"
:
"organization name 2"
}],
]
response
=
self
.
client
.
get
(
test_url
)
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertContains
(
response
,
'lang: fr'
)
self
.
assertContains
(
response
,
'course name: {}'
.
format
(
self
.
course
.
display_name
))
# test with second organization template
response
=
self
.
client
.
get
(
test_url
)
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertContains
(
response
,
'lang: fr'
)
self
.
assertContains
(
response
,
'course name: {}'
.
format
(
self
.
course
.
display_name
))
@override_settings
(
FEATURES
=
FEATURES_WITH_CUSTOM_CERTS_ENABLED
)
def
test_certificate_custom_template_with_org
(
self
):
"""
Tests custom template search if if have a single template for all courses of organization.
"""
self
.
_add_course_certificates
(
count
=
1
,
signatory_count
=
2
)
self
.
_create_custom_template
(
1
)
self
.
_create_custom_template
(
1
,
mode
=
'honor'
)
test_url
=
get_certificate_url
(
user_id
=
self
.
user
.
id
,
course_id
=
unicode
(
self
.
course
.
id
)
)
with
patch
(
'certificates.api.get_course_organizations'
)
as
mock_get_orgs
:
mock_get_orgs
.
side_effect
=
[
[{
"id"
:
1
,
"name"
:
"organization name"
}],
]
response
=
self
.
client
.
get
(
test_url
)
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertContains
(
response
,
'course name: {}'
.
format
(
self
.
course
.
display_name
))
@override_settings
(
FEATURES
=
FEATURES_WITH_CUSTOM_CERTS_ENABLED
)
def
test_certificate_custom_template_with_course_mode
(
self
):
"""
Tests custom template search if if have a single template for a course mode.
"""
mode
=
'honor'
self
.
_add_course_certificates
(
count
=
1
,
signatory_count
=
2
)
self
.
_create_custom_template
(
mode
=
mode
)
test_url
=
get_certificate_url
(
user_id
=
self
.
user
.
id
,
course_id
=
unicode
(
self
.
course
.
id
)
)
with
patch
(
'certificates.api.get_course_organizations'
)
as
mock_get_orgs
:
mock_get_orgs
.
return_value
=
[]
response
=
self
.
client
.
get
(
test_url
)
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertContains
(
response
,
'mode: {}'
.
format
(
mode
))
class
TrackShareRedirectTest
(
UrlResetMixin
,
ModuleStoreTestCase
,
EventTrackingTestCase
):
"""
...
...
lms/djangoapps/certificates/views/webview.py
View file @
f8f23240
...
...
@@ -7,22 +7,27 @@ import logging
from
django.conf
import
settings
from
django.contrib.auth.models
import
User
from
django.http
import
HttpResponse
from
django.template
import
RequestContext
from
django.utils.translation
import
ugettext
as
_
from
opaque_keys
import
InvalidKeyError
from
opaque_keys.edx.keys
import
CourseKey
from
microsite_configuration
import
microsite
from
courseware.courses
import
course_image_url
from
edxmako.shortcuts
import
render_to_response
from
edxmako.template
import
Template
from
eventtracking
import
tracker
from
xmodule.modulestore.django
import
modulestore
from
microsite_configuration
import
microsite
from
opaque_keys
import
InvalidKeyError
from
opaque_keys.edx.keys
import
CourseKey
from
student.models
import
LinkedInAddToProfileConfiguration
from
courseware.courses
import
course_image_url
from
util
import
organizations_helpers
as
organization_api
from
xmodule.modulestore.django
import
modulestore
from
certificates.api
import
(
get_active_web_certificate
,
get_certificate_url
,
emit_certificate_event
,
has_html_certificates_enabled
has_html_certificates_enabled
,
get_certificate_template
)
from
certificates.models
import
(
GeneratedCertificate
,
...
...
@@ -31,7 +36,6 @@ from certificates.models import (
BadgeAssertion
)
log
=
logging
.
getLogger
(
__name__
)
...
...
@@ -401,4 +405,11 @@ def render_html_view(request, user_id, course_id):
context
.
update
(
course
.
cert_html_view_overrides
)
# FINALLY, generate and send the output the client
if
settings
.
FEATURES
.
get
(
'CUSTOM_CERTIFICATE_TEMPLATES_ENABLED'
,
False
):
custom_template
=
get_certificate_template
(
course_key
,
user_certificate
.
mode
)
if
custom_template
:
template
=
Template
(
custom_template
)
context
=
RequestContext
(
request
,
context
)
return
HttpResponse
(
template
.
render
(
context
))
return
render_to_response
(
"certificates/valid.html"
,
context
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment