Лучший способ создать несколько объектов за один раз в Django - PullRequest
0 голосов
/ 15 февраля 2012

Как я могу улучшить этот блок кода?

Должен ли я поместить все в метод сохранения?Использовать несколько блоков 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 голосов
/ 15 февраля 2012

Вы используете сигналы , чтобы создать все другие объекты после создания исходного пользователя. Таким образом, вы можете разбить блоки на отдельные методы / приемники сигналов (один для профиля, один для временного пароля и т. Д.), Каждый из которых будет вызываться при создании исходного пользователя.

Что касается транзакции - вы можете отложить фиксацию новых объектов в БД до тех пор, пока они не будут созданы все. Это означает, что если вы выйдете из try / catch без исключения, вы знаете, что все объекты созданы и, следовательно, спаси их. Это становится более трудным, если вы разбиваете единственный метод на меньшие приемники сигнала.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...