我有一个功能,用户不经常上传他们的数据csv,可能包括大约200个记录和80个字段,可能记录在6000 django数据库对象的区域。
我想让他们预览数据,所以我在views.py中有以下代码(在这里缩短了......):
@login_required
def import_assessments(request):
import csv
if request.method == 'POST':
form = AssessmentUploadForm(request.POST, request.FILES)
if form.is_valid():
# handle standard form fields
year = int(request.POST['date_year'])
...
# handle uploaded .csv file
reader = csv.reader(request.FILES['file_upload'])
data = csv.DictReader(request.FILES['file_upload'])
# make some empty lists
unmatched_pupils = []
pupil_tuples = []
csv_errors = []
# make a list of included objectives, derived from column headings
...
# handle the pupil data rows
for row in data:
# build a list of objective,assessment tuples for this pupil
assessments_list = []
for string in objective_strings:
theobjective = included_objectives[string]
assessments_list.append((theobjective, row[string]))
# look the pupil up, and in any case add this new tuple to the pupil's results
firstname = row["First name"]
surname = row["Surname"]
tutor_group = row["Tutor group"]
try:
if tutor_group:
thepupil = Pupil.objects.get(firstname__iexact = firstname, surname__iexact = surname, tutor_group__iexact = tutor_group)
else:
thepupil = Pupil.objects.get(firstname__iexact = firstname, surname__iexact = surname)
except Pupil.DoesNotExist:
unmatched_pupils.append(
(
(firstname,surname,tutor_group),
assessments_list
))
...
else:
pupil_tuples.append(
(
thepupil,
assessments_list
))
# now create errors
if unmatched_pupils:
if len(unmatched_pupils) >=2:
themessage = 'The following pupils could not be identified in the database:'
else:
themessage = 'The following pupil could not be identified in the database:'
csv_errors.append({
'type': 'unmatched_pupils',
'class': 'error',
'message': themessage,
'offenders': unmatched_pupils,
'instruction': 'Check for typing errors in the name or tutor group. If pupils are new, you can add them individually, or import whole year groups using the links below.',
})
...
# render a preview page
return render_to_response('import_preview.html', locals(), context_instance=RequestContext(request))
else:
form = AssessmentUploadForm(request.POST)
else:
form = AssessmentUploadForm()
return render_to_response('assessments_upload.html', locals(), context_instance=RequestContext(request))
我的真实视图功能有点长(163行),有额外的代码来检查多个可能的瞳孔匹配,以及csv列标题中所有潜在的拼写错误和意外重复。由于这些都不是表单错误,我将它们发送到在csv_errors
列表中打包的import_preview.html文件,在那里向他们提供建议。
如果没有错误,我的预览页面会显示一个数据表,所有数据都打包在pupil_tuples
中。我的下一步是添加一个链接/按钮将所有这些保存到数据库。我在第一次测试此上载时(在我介绍所有错误检查之前)使用的传统代码行是:
Assessment.objects.get_or_create(objective=theobjective, pupil=thepupil, teacher=theteacher, status=status, date=thedate)
我想知道这一切的布局应该是什么。我的数据已全部打包在pupil_tuples
列表中,我只想get_or_create
,但我应该使用指向新视图功能的链接,新表单,if request.method == 'POST'
码?
PS我还真的需要分别加载csv.reader和csv.DictReader吗?这是一个资源问题吗?我想迭代所有标题作为列表,检查重复,我不认为DictReader会让我这样做。但是我希望DictReader的所有便利用于我的其余部分。