#8813: BaseInlineFormSet unable to save existing objects
--------------------+-------------------------------------------------------
 Reporter:  tobias  |       Owner:  nobody    
   Status:  new     |   Milestone:            
Component:  Forms   |     Version:  SVN       
 Keywords:          |       Stage:  Unreviewed
Has_patch:  0       |  
--------------------+-------------------------------------------------------
 The Error:
 {{{
 Environment:

 Request Method: POST
 Request URL: http://localhost:8000/caktus-
 books/ledger/exchange/215/edit/invoice/
 Django Version: 1.0-beta_2-SVN-8874
 Python Version: 2.5.2
 Installed Applications:
 ['django.contrib.auth',
  'django.contrib.contenttypes',
  'django.contrib.sessions',
  'django.contrib.sites',
  'django.contrib.admin',
  'django.contrib.humanize',
  'django.contrib.markup',
  'crm',
  'ledger']
 Installed Middleware:
 ('django.middleware.common.CommonMiddleware',
  'django.contrib.sessions.middleware.SessionMiddleware',
  'django.contrib.auth.middleware.AuthenticationMiddleware',
  'django.middleware.doc.XViewMiddleware')


 Traceback:
 File "/home/tobias/caktus/eclipse-
 workspace/caktus_books/django/core/handlers/base.py" in get_response
   86.                 response = callback(request, *callback_args,
 **callback_kwargs)
 File "/home/tobias/caktus/eclipse-
 workspace/caktus_books/django/contrib/auth/decorators.py" in __call__
   67.             return self.view_func(request, *args, **kwargs)
 File "/home/tobias/caktus/eclipse-
 workspace/caktus_books/django/db/transaction.py" in _commit_on_success
   238.                 res = func(*args, **kw)
 File "/home/tobias/caktus/eclipse-workspace/caktus_books/ledger/views.py"
 in create_edit_exchange
   88.                   transactions =
 transaction_formset.save(commit=False)
 File "/home/tobias/caktus/eclipse-
 workspace/caktus_books/django/forms/models.py" in save
   372.         return self.save_existing_objects(commit) +
 self.save_new_objects(commit)
 File "/home/tobias/caktus/eclipse-
 workspace/caktus_books/django/forms/models.py" in save_existing_objects
   386.             obj =
 existing_objects[form.cleaned_data[self._pk_field.name]]

 Exception Type: KeyError at /caktus-
 books/ledger/exchange/215/edit/invoice/
 Exception Value: None
 }}}

 From the debugger I found that:
 {{{
 self._pk_field.name = 'id'
 self._pk_field.name in form.cleaned_data is True
 form.cleaned_data[self._pk_field.name] is None
 }}}

 The Formset:
 {{{
 class BaseTransactionFormSet(BaseInlineFormSet):
         @requires_kwarg('exchange_type')
         def __init__(self, *args, **kwargs):
                 self.exchange_type = kwargs.pop('exchange_type')
                 super(BaseTransactionFormSet, self).__init__(*args,
 **kwargs)

         def add_fields(self, form, index):
                 super(BaseTransactionFormSet, self).add_fields(form,
 index)
                 form.fields.pop('project')

                 form.fields['memo'].widget =
 forms.TextInput(attrs={'size':'35'})
                 form.fields['quantity'].widget =
 forms.TextInput(attrs={'size':'5'})
                 form.fields['amount'].widget =
 forms.TextInput(attrs={'size':'8'})

                 et = self.exchange_type
                 if et.credit:
                         if et.slug == 'invoice':
                                 qs =
 ledger.Account.objects.filter(Q(type=et.credit.type) | Q(type='expense'))
                         else:
                                 qs =
 ledger.Account.objects.filter(type=et.credit.type)

                         form.fields['credit'].queryset =
 qs.order_by('number')
                 else:
                         form.fields.pop('credit')

                 if et.debit:
                         form.fields['debit'].queryset =
 ledger.Account.objects.filter(type=et.debit.type).order_by('number')
                 else:
                         form.fields.pop('debit')

 TransactionFormSet = inlineformset_factory(ledger.Exchange,
 ledger.Transaction, formset=BaseTransactionFormSet)
 }}}

 The View:
 {{{
 @login_required
 @transaction.commit_on_success
 def create_edit_exchange(request, exchange_type_slug, exchange_id=None):
         exchange_type = get_object_or_404(ledger.ExchangeType,
 slug=exchange_type_slug)
         exchange = None

         if exchange_id:
                 exchange = get_object_or_404(ledger.Exchange,
 pk=exchange_id, type=exchange_type)

         if request.POST:
                 exchange_form = ExchangeForm(
                         request.POST,
                         instance=exchange,
                         exchange_type=exchange_type,
                 )
                 transaction_formset = TransactionFormSet(
                         request.POST,
                         instance=exchange,
                         exchange_type=exchange_type,
                 )

                 if exchange_form.is_valid() and
 transaction_formset.is_valid():
                         exchange = exchange_form.save()

                         transactions =
 transaction_formset.save(commit=False)
                         for transaction in transactions:
                                 if exchange_type.credit:
                                         transaction.credit =
 exchange_form.cleaned_data['credit']
                                 if exchange_type.debit:
                                         transaction.debit =
 exchange_form.cleaned_data['debit']
                                 transaction.project =
 exchange_form.cleaned_data['project']
                                 transaction.save()

                         request.user.message_set.create(message='%s
 successfully saved.' % exchange_type)
                         return
 HttpResponseRedirect(reverse('list_exchanges',
 kwargs={'exchange_type_slug': exchange.type.slug}))
         else:
                 exchange_form = ExchangeForm(
                         instance=exchange,
                         exchange_type=exchange_type,
                 )
                 transaction_formset = TransactionFormSet(
                         instance=exchange,
                         exchange_type=exchange_type,
                 )

         context = {
                 'exchange': exchange,
                 'exchange_type': exchange_type,
                 'exchange_form': exchange_form,
                 'transaction_formset': transaction_formset,
         }

         return render_to_response('books/ledger/exchange/create.html',
 context, context_instance=RequestContext(request))
 }}}

-- 
Ticket URL: <http://code.djangoproject.com/ticket/8813>
Django Code <http://code.djangoproject.com/>
The web framework for perfectionists with deadlines
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to