Проблема проверки набора форм Django: как использовать набор запросов в request.POST? - PullRequest
1 голос
/ 25 марта 2011

Я работаю с modelformset и немного застрял. Я передаю, скажем, 20 форм, используя modelformsetfactory. Эти формы построены и отображаются на странице. Когда я возвращаюсь после публикации, я хочу, чтобы только некоторые из этих форм были проверены и сохранены, а не все, в зависимости от значения поля модели.

Я подумал, что могу использовать queryset в request.POST, чтобы ограничить формы, которые я хочу в моем наборе форм, которые должны быть проверены. Но это не работает. Можно ли как-нибудь ограничить количество форм?

Для набора запросов, ограничивающего количество экземпляров модели, которые я пробовал

formset = PaymentOptionFormSet(request.POST, queryset=payment_option_posted_queryset)

Я получаю следующую ошибку:

IndexError at /seller/seller_profile/

list index out of range


Traceback:
File "/home/shagun/work/tinla/django/core/handlers/base.py" in get_response
  100.                     response = callback(request, *callback_args, **callback_kwargs)
File "/home/shagun/work/tinla/web/views/user_views.py" in seller_profile
  164.             formset = PaymentOptionFormSet(request.POST, queryset=payment_option_posted_queryset)           
File "/home/shagun/work/tinla/orders/forms.py" in __init__
  400.         super(BasePaymentOptionFormSet, self).__init__(*args,**kwargs)
File "/home/shagun/work/tinla/django/forms/models.py" in __init__
  423.         super(BaseModelFormSet, self).__init__(**defaults)
File "/home/shagun/work/tinla/django/forms/formsets.py" in __init__
  47.         self._construct_forms()
File "/home/shagun/work/tinla/django/forms/formsets.py" in _construct_forms
  97.             self.forms.append(self._construct_form(i))
File "/home/shagun/work/tinla/django/forms/models.py" in _construct_form
  447.             kwargs['instance'] = self.get_queryset()[i]
File "/home/shagun/work/tinla/django/db/models/query.py" in __getitem__
  172.             return self._result_cache[k]

Exception Type: IndexError at /seller/seller_profile/
Exception Value: list index out of range

Мой код выглядит так:

def seller_profile(request):
    from accounts.models import PaymentOption, PaymentMode
    payment_options = PaymentOption.objects.select_related('payment_mode').filter(payment_mode__client__id=1)
    payment_option_queryset = PaymentOption.objects.filter(payment_mode__client__id='1')
    payment_option_posted_queryset = PaymentOption.objects.filter(payment_mode__client__id='1', is_active='1')

    if request.user.is_authenticated():

        PaymentOptionFormSet = modelformset_factory(PaymentOption, formset = BasePaymentOptionFormSet, extra=0, fields = ("payment_delivery_address", "bank_branch", "bank_ac_name", "bank_ac_type", "bank_ac_no", "bank_address", "bank_ifsc", "is_active"))
        user = request.user.get_profile()
        if request.method == "POST":#If the form has been submitted
            form1 = SellerProfileForm(request.POST, instance = user)
            form2 = SellerNotificationForm(request.POST, instance = user)
            formset = PaymentOptionFormSet(request.POST, queryset=PaymentOption.objects.all())

            counting = 0
            for form in formset.forms:
                counting +=1
            print "count = ",counting
            print formset.is_valid()
            if form1.is_valid() and form2.is_valid:
                form1.save()
                form2.save()
            else:
                my_acct_ctxt = getMyAccountContext(request)
                return render_to_response('seller/seller_profile.html',
                {
                    'form1': form1,
                    'form2': form2,
                    'formset': formset,
                    'error1': form1.errors,
                    'error2': form2.errors,
                    'errorformset': formset.errors,
                    'payment_options': payment_options,
                    'acc': my_acct_ctxt,
                },
                context_instance=RequestContext(request))

        else: #If the form has not been submitted 
            form1 = SellerProfileForm(instance = user)
            form2 = SellerNotificationForm(instance = user)
            formset = PaymentOptionFormSet(queryset=payment_option_queryset)
            counter = 0

        my_acct_ctxt = getMyAccountContext(request)
    return render_to_response('seller/seller_profile.html',
        {
        'form1': form1,
        'form2': form2,
        'formset': formset,
        'payment_options': payment_options,
        'acc':my_acct_ctxt,
        },
        context_instance=RequestContext(request))

1 Ответ

0 голосов
/ 31 марта 2011

Если вам требуется условная проверка набора форм, вы можете переопределить метод очистки набора форм.Вот пример того, как я сделал это в admin с помощью встроенного набора форм, который вы, вероятно, можете изменить в соответствии со своими потребностями, поскольку классы Formset довольно однородны.

class MyInlineFormset(forms.models.BaseInlineFormSet):
    def clean(self):
        for form in self.forms:
            try:
                if form.cleaned_data:
                    delete = form.cleaned_data.get('DELETE')
                    if not delete:
                        my_field = form.cleaned_data.get('my_field', None)
                        if my_field:
                            if my_field == 'some_value':
                              #only validate the other values
                              #if the field you're looking for
                              #has a particular value, etc
                              another_field = form.cleaned_data.get('another_field')

                              #more validation here where you can raise
                              #forms.ValidationError()

            except AttributeError:
                pass

Надеюсь, это поможет вам!

...