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
...
@@ -4,6 +4,7 @@ Utility library for working with the edx-organizations app
"""
"""
from
django.conf
import
settings
from
django.conf
import
settings
from
django.db.utils
import
DatabaseError
def
add_organization
(
organization_data
):
def
add_organization
(
organization_data
):
...
@@ -43,7 +44,15 @@ def get_organizations():
...
@@ -43,7 +44,15 @@ def get_organizations():
if
not
settings
.
FEATURES
.
get
(
'ORGANIZATIONS_APP'
,
False
):
if
not
settings
.
FEATURES
.
get
(
'ORGANIZATIONS_APP'
,
False
):
return
[]
return
[]
from
organizations
import
api
as
organizations_api
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
):
def
get_organization_courses
(
organization_id
):
...
...
lms/djangoapps/certificates/admin.py
View file @
f8f23240
...
@@ -2,12 +2,49 @@
...
@@ -2,12 +2,49 @@
django admin pages for certificates models
django admin pages for certificates models
"""
"""
from
django.contrib
import
admin
from
django.contrib
import
admin
from
django
import
forms
from
config_models.admin
import
ConfigurationModelAdmin
from
config_models.admin
import
ConfigurationModelAdmin
from
util.organizations_helpers
import
get_organizations
from
certificates.models
import
(
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
(
CertificateGenerationConfiguration
)
admin
.
site
.
register
(
CertificateHtmlViewConfiguration
,
ConfigurationModelAdmin
)
admin
.
site
.
register
(
CertificateHtmlViewConfiguration
,
ConfigurationModelAdmin
)
admin
.
site
.
register
(
BadgeImageConfiguration
)
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
...
@@ -14,6 +14,7 @@ from opaque_keys.edx.keys import CourseKey
from
openedx.core.djangoapps.content.course_overviews.models
import
CourseOverview
from
openedx.core.djangoapps.content.course_overviews.models
import
CourseOverview
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.django
import
modulestore
from
util.organizations_helpers
import
get_course_organizations
from
certificates.models
import
(
from
certificates.models
import
(
CertificateStatuses
,
CertificateStatuses
,
...
@@ -21,7 +22,8 @@ from certificates.models import (
...
@@ -21,7 +22,8 @@ from certificates.models import (
CertificateGenerationCourseSetting
,
CertificateGenerationCourseSetting
,
CertificateGenerationConfiguration
,
CertificateGenerationConfiguration
,
ExampleCertificateSet
,
ExampleCertificateSet
,
GeneratedCertificate
GeneratedCertificate
,
CertificateTemplate
,
)
)
from
certificates.queue
import
XQueueCertInterface
from
certificates.queue
import
XQueueCertInterface
...
@@ -373,6 +375,46 @@ def get_active_web_certificate(course, is_preview_mode=None):
...
@@ -373,6 +375,46 @@ def get_active_web_certificate(course, is_preview_mode=None):
return
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
):
def
emit_certificate_event
(
event_name
,
user
,
course_id
,
course
=
None
,
event_data
=
None
):
"""
"""
Emits certificate event.
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):
...
@@ -674,6 +674,88 @@ class BadgeImageConfiguration(models.Model):
return
cls
.
objects
.
get
(
default
=
True
)
.
icon
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
)
@receiver
(
post_save
,
sender
=
GeneratedCertificate
)
#pylint: disable=unused-argument
#pylint: disable=unused-argument
def
create_badge
(
sender
,
instance
,
**
kwargs
):
def
create_badge
(
sender
,
instance
,
**
kwargs
):
...
...
lms/djangoapps/certificates/tests/test_views.py
View file @
f8f23240
...
@@ -30,6 +30,7 @@ from certificates.models import (
...
@@ -30,6 +30,7 @@ from certificates.models import (
CertificateStatuses
,
CertificateStatuses
,
CertificateHtmlViewConfiguration
,
CertificateHtmlViewConfiguration
,
CertificateSocialNetworks
,
CertificateSocialNetworks
,
CertificateTemplate
,
)
)
from
certificates.tests.factories
import
(
from
certificates.tests.factories
import
(
...
@@ -45,6 +46,11 @@ FEATURES_WITH_CERTS_ENABLED['CERTIFICATES_HTML_VIEW'] = True
...
@@ -45,6 +46,11 @@ FEATURES_WITH_CERTS_ENABLED['CERTIFICATES_HTML_VIEW'] = True
FEATURES_WITH_CERTS_DISABLED
=
settings
.
FEATURES
.
copy
()
FEATURES_WITH_CERTS_DISABLED
=
settings
.
FEATURES
.
copy
()
FEATURES_WITH_CERTS_DISABLED
[
'CERTIFICATES_HTML_VIEW'
]
=
False
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'
)
@attr
(
'shard_1'
)
@ddt.ddt
@ddt.ddt
...
@@ -427,6 +433,30 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase):
...
@@ -427,6 +433,30 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase):
self
.
course
.
save
()
self
.
course
.
save
()
self
.
store
.
update_item
(
self
.
course
,
self
.
user
.
id
)
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
)
@override_settings
(
FEATURES
=
FEATURES_WITH_CERTS_ENABLED
)
def
test_rendering_course_organization_data
(
self
):
def
test_rendering_course_organization_data
(
self
):
"""
"""
...
@@ -724,6 +754,75 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase):
...
@@ -724,6 +754,75 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase):
response_json
=
json
.
loads
(
response
.
content
)
response_json
=
json
.
loads
(
response
.
content
)
self
.
assertEqual
(
CertificateStatuses
.
generating
,
response_json
[
'add_status'
])
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
):
class
TrackShareRedirectTest
(
UrlResetMixin
,
ModuleStoreTestCase
,
EventTrackingTestCase
):
"""
"""
...
...
lms/djangoapps/certificates/views/webview.py
View file @
f8f23240
...
@@ -7,22 +7,27 @@ import logging
...
@@ -7,22 +7,27 @@ import logging
from
django.conf
import
settings
from
django.conf
import
settings
from
django.contrib.auth.models
import
User
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
django.utils.translation
import
ugettext
as
_
from
opaque_keys
import
InvalidKeyError
from
courseware.courses
import
course_image_url
from
opaque_keys.edx.keys
import
CourseKey
from
microsite_configuration
import
microsite
from
edxmako.shortcuts
import
render_to_response
from
edxmako.shortcuts
import
render_to_response
from
edxmako.template
import
Template
from
eventtracking
import
tracker
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
student.models
import
LinkedInAddToProfileConfiguration
from
courseware.courses
import
course_image_url
from
util
import
organizations_helpers
as
organization_api
from
util
import
organizations_helpers
as
organization_api
from
xmodule.modulestore.django
import
modulestore
from
certificates.api
import
(
from
certificates.api
import
(
get_active_web_certificate
,
get_active_web_certificate
,
get_certificate_url
,
get_certificate_url
,
emit_certificate_event
,
emit_certificate_event
,
has_html_certificates_enabled
has_html_certificates_enabled
,
get_certificate_template
)
)
from
certificates.models
import
(
from
certificates.models
import
(
GeneratedCertificate
,
GeneratedCertificate
,
...
@@ -31,7 +36,6 @@ from certificates.models import (
...
@@ -31,7 +36,6 @@ from certificates.models import (
BadgeAssertion
BadgeAssertion
)
)
log
=
logging
.
getLogger
(
__name__
)
log
=
logging
.
getLogger
(
__name__
)
...
@@ -401,4 +405,11 @@ def render_html_view(request, user_id, course_id):
...
@@ -401,4 +405,11 @@ def render_html_view(request, user_id, course_id):
context
.
update
(
course
.
cert_html_view_overrides
)
context
.
update
(
course
.
cert_html_view_overrides
)
# FINALLY, generate and send the output the client
# 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
)
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