Adding StockRecord forms to StockRecordFormSet in dashboard/catalogue/forms.py

99 views
Skip to first unread message

Chris L

unread,
Apr 18, 2014, 5:15:39 PM4/18/14
to django...@googlegroups.com
I need to create a StockRecord form for each partner that a user is associated with. The Partner field is replace by the plain text name, and instead of adding a stock record form each time you save, it just gives you x forms, where x is the number of partners.

The difficulty for me is that as far as I can tell, I cannot use the extra= parameter of the inlineformset_factory, because StockRecordFormSet inherits BaseStockRecordFormSet, and BaseStockRecordFormSet = inlineformset_factory(Product, StockRecord, form=StockRecordForm, extra=1)

Perhaps there is a simpler solution, but what I have tried to do is set that extra=0, then inside StockRecordFormSet I create the number of forms I need. Here is the snippet of code which does that:

class StockRecordFormSet(BaseStockRecordFormSet):

    def __init__(self, product_class, user, *args, **kwargs):
        self.user = user
        self.require_user_stockrecord = not user.is_staff
        self.product_class = product_class
        super(StockRecordFormSet, self).__init__(*args, **kwargs)

        self.create_forms_for_all_warehouses()
        self.set_initial_data()

    def create_forms_for_all_warehouses(self):
        #! This makes a form for each warehouse (partner)
        i = self.total_form_count()
        for partner in self.user.partners.all():
            self.forms.append(self._construct_form(i))

            self.forms[i].instance.partner = partner
            self.forms[i].is_bound = False
            i += 1

The problem with this, though, is that total_form_count() never gets incremented, and I cannot figure out how to do it. This causes stockrecord_formset.is_valid() to fail because it has .errors. Here is the stacktrace:

Environment:


Request Method: POST

Django Version: 1.6.1
Python Version: 2.7.5
Installed Applications:
['django.contrib.auth',
 'django.contrib.admin',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.messages',
 'django.contrib.flatpages',
 'django.contrib.staticfiles',
 'oscar.apps.dashboard.pages',
 'oscar.apps.dashboard.reviews',
 'south',
 'compressor',
 'oscar',
 'oscar.apps.analytics',
 'oscar.apps.checkout',
 'oscar.apps.address',
 'oscar.apps.shipping',
 'catalogue',
 'oscar.apps.catalogue.reviews',
 'partner',
 'oscar.apps.basket',
 'oscar.apps.payment',
 'oscar.apps.offer',
 'oscar.apps.order',
 'customer',
 'oscar.apps.promotions',
 'oscar.apps.search',
 'oscar.apps.voucher',
 'oscar.apps.wishlists',
 'dashboard',
 'oscar.apps.dashboard.reports',
 'oscar.apps.dashboard.users',
 'oscar.apps.dashboard.orders',
 'oscar.apps.dashboard.promotions',
 'dashboard.catalogue',
 'oscar.apps.dashboard.offers',
 'dashboard.partners',
 'oscar.apps.dashboard.pages',
 'oscar.apps.dashboard.ranges',
 'oscar.apps.dashboard.reviews',
 'oscar.apps.dashboard.vouchers',
 'oscar.apps.dashboard.communications',
 'haystack',
 'treebeard',
 'sorl.thumbnail']
Installed Middleware:
('django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'oscar.apps.basket.middleware.BasketMiddleware',
 'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware')


Traceback:
File "/home/suprafly/Envs/TradeWinds/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  114.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/suprafly/Envs/TradeWinds/local/lib/python2.7/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
  22.                 return view_func(request, *args, **kwargs)
File "/home/suprafly/Envs/TradeWinds/local/lib/python2.7/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
  22.                 return view_func(request, *args, **kwargs)
File "/home/suprafly/Envs/TradeWinds/local/lib/python2.7/site-packages/django/views/generic/base.py" in view
  69.             return self.dispatch(request, *args, **kwargs)
File "/home/suprafly/Envs/TradeWinds/local/lib/python2.7/site-packages/django/views/generic/base.py" in dispatch
  87.         return handler(request, *args, **kwargs)
File "/home/suprafly/Envs/TradeWinds/local/lib/python2.7/site-packages/django/views/generic/edit.py" in post
  228.         return super(BaseUpdateView, self).post(request, *args, **kwargs)
File "/home/suprafly/Envs/TradeWinds/local/lib/python2.7/site-packages/django/views/generic/edit.py" in post
  171.             return self.form_valid(form)
File "/home/suprafly/TradeWinds_project/TradeWinds/dashboard/catalogue/views.py" in form_valid
  226.         return self.process_all_forms(form)
File "/home/suprafly/TradeWinds_project/TradeWinds/dashboard/catalogue/views.py" in process_all_forms
  257.             stockrecord_formset.is_valid(),
File "/home/suprafly/Envs/TradeWinds/local/lib/python2.7/site-packages/django/forms/formsets.py" in is_valid
  292.         err = self.errors
File "/home/suprafly/Envs/TradeWinds/local/lib/python2.7/site-packages/django/forms/formsets.py" in errors
  267.             self.full_clean()
File "/home/suprafly/Envs/TradeWinds/local/lib/python2.7/site-packages/django/forms/formsets.py" in full_clean
  326.             self.clean()
File "/home/suprafly/TradeWinds_project/TradeWinds/dashboard/catalogue/forms.py" in clean
  174.                                         for form in self.forms])

Exception Type: AttributeError at /dashboard/catalogue/products/create/4/
Exception Value: 'StockRecordForm' object has no attribute 'cleaned_data'

Chris L

unread,
Apr 25, 2014, 3:28:27 PM4/25/14
to django...@googlegroups.com
I fixed this by:

ResizeableBaseStockRecordFormSet = lambda num_forms: inlineformset_factory(
    Product, StockRecord, form=StockRecordForm, extra=num_forms, max_num=num_forms, can_delete=False)


def stockrecordformset_factory(num_forms):
    class StockRecordFormSet(ResizeableBaseStockRecordFormSet(num_forms)):

So now I can create extra fields on the fly, as I need them.

Maik Hoepfel

unread,
Apr 27, 2014, 8:39:36 AM4/27/14
to django...@googlegroups.com
On 25/04/14 20:28, Chris L wrote:
> I fixed this by:
>
> ResizeableBaseStockRecordFormSet = lambda num_forms: inlineformset_factory(
> Product, StockRecord, form=StockRecordForm, extra=num_forms,
> max_num=num_forms, can_delete=False)
>
>
> def stockrecordformset_factory(num_forms):
> class StockRecordFormSet(ResizeableBaseStockRecordFormSet(num_forms)):
>
> So now I can create extra fields on the fly, as I need them.
>
That's a cool way to solve it!

Chris L

unread,
Apr 29, 2014, 6:29:24 PM4/29/14
to django...@googlegroups.com
I am finding that the ease and simplicity of doing stuff like this is the beauty of python.
Reply all
Reply to author
Forward
0 new messages