2012-02-15 4 views
0

Как я могу улучшить этот блок кода?Лучший способ создать несколько объектов за один раз в Django

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

Вы получите исключение в третьей строке. – DrTyrsa

+0

Какие у вас проблемы с кодом? Почему один шаг будет терпеть неудачу? Прошло ли это раньше? –

ответ

0

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

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

Смежные вопросы