–更新于:2016-07-13
近期重写这部分,使其成为django management command
(在dogwood版本下测试可用)
原因有二,其一是之前所用的功能函数不完备,随着对edx的了解深入,想用更安全的函数来完成批量注册功能,其二是希望做到更好的内聚性
这部分是从我的edx_siteapi抽出的一个功能模块,edx_siteapi项目试图把edx的一些功能变为RESTful api接口(类似canvas做的),供外部系统调用和整合,有兴趣的小伙伴可以关注这个项目
在搭建edX的时候,可能面临一个这样的需求:批量导入学生作为用户。
即便是采用cas注册这个需求可能依旧存在,校内系统可能存有用户课程关系,需要预先导入,所以用户实体需要预先存在系统中,而cas是一种首次登录才注册的机制
有时我们可能需要批量从既有数据库中导入用户,尤其是将Open edX用于SPOC中时
在此给出一个可行的解决方案。
大体思路
- 从校方数据库中导出用户文件(csv格式)
- 写脚本从csv文件中取得所需的字段(诸如学号,姓名)
- 使用
django management command
将用户导入系统(利用django management command能调用django上下文的机制,这也是此次更新的主要地方)
##实施细节
我们假设从数据库导出的文件student.csv 如下
1
2
3
4
5
6
|
:::text
姓名,学号,email,专业,班级
张三,201011,zs@qq.com,热能动力工程,动力1007班
李四,201012,ls@qq.com,热能动力工程,动力1008班
王五,201013,ww@qq.com,热能动力工程,动力1009班
...
|
注意逗号前后的空格是有影响的!
###编写脚本
在任意django app目录下创建management/commands/create_user_from_csv.py
,先上代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
#!/usr/bin/env python
# encoding: utf-8
from optparse import make_option
from django.core.management.base import BaseCommand
from student.forms import AccountCreationForm
from student.models import create_comments_service_user
from student.views import _do_create_account, AccountValidationError
from track.management.tracked_command import TrackedCommand
# 解析csv
import unicodecsv # utf-8 ,也可以用pandas:
def create_user(username, password, email, name):
form = AccountCreationForm(data={
'username': username,
'email': email,
'password': password,
'name': name,
},
tos_required=False)
try:
user, _, reg = _do_create_account(form)
reg.activate()
reg.save()
#create_comments_service_user(user) #这会促发网络请求
return user
except AccountValidationError as e:
print e.message
# wget https://raw.githubusercontent.com/edx/edx-platform/named-release/dogwood.rc/common/djangoapps/student/management/commands/create_user.py
class Command(TrackedCommand):
help = """
example:
# Enroll a user test@example.com into the demo course
# The username and name will default to "test"
sudo -u www-data /edx/bin/python.edxapp /edx/app/edxapp/edx-platform/manage.py lms create_user_from_csv --help --settings devstack
sudo -u www-data /edx/bin/python.edxapp /edx/app/edxapp/edx-platform/manage.py lms create_user_from_csv --csv /edx/app/edxapp/edx-platform/lms/djangoapps/siteapi/student.csv --settings devstack
"""
help = u"批量导入用户"
option_list = BaseCommand.option_list + (
make_option('-c', '--csv', #采用绝对路径
metavar='CSV',
dest='csv',
default=None,
help=u'用户注册表'),
)
def handle(self, *args, **options):
csv = options['csv']
with open(csv) as f:
f_csv = unicodecsv.DictReader(f, encoding='utf-8')
for item in f_csv:
print item[u"姓名"]
username = item[u"学号"]
email = item[u"email"]
name = item[u"姓名"]
password = username
create_user(username, password, email, name)
# 缺乏读写csv的技巧,next和边界,按header读取
# http://python3-cookbook.readthedocs.io/zh_CN/latest/c06/p01_read_write_csv_data.html
|
测试显示,8000名学生的话,大约需要导入十几分钟(旧版本)
###安装依赖
1
2
|
:::text
sudo /edx/bin/pip.edxapp install unicodecsv #dogwood版不需要
|
###开始导入
sudo -u www-data /edx/bin/python.edxapp /edx/app/edxapp/edx-platform/manage.py lms create_user_from_csv --csv /tmp/student.csv --settings devstack
###开始使用
在/login中使用email和password登录即可。
对于不想使用这种登录方式的,可以自己来写用户认证,诸如使用username和password登录之类的
###后记
文中我们创建用户使用的是python代码。
如果是单独创建用户,也可以用
1
|
sudo -u www-data /edx/bin/python.edxapp /edx/app/edxapp/edx-platform/manage.py lms create_user --username test123 --name test123 --password test123 --email test123@qq.com
|
如果你愿意也可以采用http请求创建,详情可以跟踪sysadmin里的创建用户功能(封装成restful接口可用作异构系统接口)
坑
删除用户之后创建同名用户,会造成:CommentClientRequestError: u’[“Username is already taken”]’,猜测是评论系统内依然留存有用户造成的,而评论系统是个异构系统(mongodb)
线索:
- import lms.lib.comment_client as cc
- cc_user = cc.User.from_django_user(user)
解决方案
如果我们的猜测是对的,应该只要删除点mongodb中的user应该就好了
1
2
3
4
5
|
:::text
mongo
use cs_comments_service_development
db.users.find()
db.users.remove({}) #移除所有,也可以写到python脚本里,使用pymongo
|
一切正常,猜测正确!