在Django中一次创建多个对象的更好方法

时间:2012-02-15 17:00:39

标签: django

如何改进此代码块?

我应该把所有内容都放在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)

1 个答案:

答案 0 :(得分:0)

创建初始用户后,使用signals创建所有其他对象。通过这种方式,您可以将块分解为单独的方法/信号接收器(一个用于配置文件,一个用于临时密码等),所有这些都将在创建初始用户时调用。

关于事务 - 你可以阻止将新对象提交到DB,直到它们全部被创建,这意味着如果你没有异常地退出try / catch,你知道所有的对象都被创建了,因此保存他们。如果将单个方法分解为较小的信号接收器,则会变得更加困难。