如何改进此代码块?
我应该把所有内容都放在save方法中吗?使用多个try..except块?此外,如何回滚整个事务,以便在其中一个“创建”阶段失败时,其余的先前创建的对象将被回滚。
@login_required
def admin_import_residents_confirm(request, comp_slug, file_id):
comp = get_object_or_404(Comp, slug=comp_slug)
file = get_object_or_404(ResidentImportFile, id=file_id)
resident_list = ResidentImportData.objects.filter(comp=comp,
file=file)
if request.method == 'POST':
for resident in resident_list:
try:
# create the user objects here
pw = User.objects.make_random_password(length=6,
allowed_chars='1234567890')
fusername = '{0}{1}{2}'.format(resident.first_name,
resident.last_name,
re.sub('\D', '', resident.unit_number))
user = User.objects.create(
username = fusername,
password = pw,
first_name = resident.first_name,
last_name = resident.last_name)
# second create the profile objects
Profile.objects.create(user=user,
contact_number=resident.contact_number)
# third create the role objects
role = Role.objects.filter(comp=comp,
name=2)[0]
role.user.add(user)
# fourth create the usercomp object
Usercomp.objects.create(
user=user,
comp=comp,
unit_number=resident.unit_number,
block_number=resident.block_number)
# fifth store the one time passwords
TempPasswords.objects.create(
user=user,
password=pw)
# sixth update created status
resident.is_created = True
resident.save()
except Exception, e:
print e
url = reverse('admin_import_residents_confirm',
args=[comp.slug, file.id ])
return redirect(url)
url = reverse('admin_resident_list', args=[comp.slug])
return redirect(url)
答案 0 :(得分:0)
创建初始用户后,使用signals创建所有其他对象。通过这种方式,您可以将块分解为单独的方法/信号接收器(一个用于配置文件,一个用于临时密码等),所有这些都将在创建初始用户时调用。
关于事务 - 你可以阻止将新对象提交到DB,直到它们全部被创建,这意味着如果你没有异常地退出try / catch,你知道所有的对象都被创建了,因此保存他们。如果将单个方法分解为较小的信号接收器,则会变得更加困难。