1

フォームを送信すると、奇妙なエラーが発生します。メソッド form.is_valid() を呼び出すと、組み込みコードの一部が属性にアクセスしようとするまでスタックが実行されますが、それは最近ではありません...問題の原因がわかりません。私はただ走る

mform = InvAddMainForm(request.POST)
    if mform.is_valid():
        ...

問題なく他のフォームで何度か行ったように。何が原因でしょうか?

編集:問題のフォームは次のようになります。

class InvAddMainForm(ModelForm):
    class Meta:
        model = Maintenance
        fields = ('serial','end','discount','vat')
    def __init__(self, *args, **kwargs):
        super(InvAddMainForm, self).__init__(*args, **kwargs)
        # The queryset of the field 'serial' is set to None here, as it is
        # Derived from the context
        self.fields['serial'] = SelectMaintenanceSerialField(required=True, queryset=None)
        self.fields['serial'].empty_label = None
        self.fields['end'].initial = Option.objects.get(pk='enddate').value
        self.fields['vat'].empty_label = None
        self.fields['vat'].queryset = Vat.objects.filter(disabled=False).order_by('name')

ビューの関連部分は次のようになります。

if 'addmain' in request.POST:
        mform = InvAddMainForm(request.POST)
        print str(mform)
        if mform.is_valid():
            mf = mform.save(commit=False)
            it = mf.serial

            if it.disabled:
                raise Exception('Cannot buy maintenance to disabled license')

            # check if maintenance for given item already is on invoice
            if Maintenance.objects.filter(invoice=inv, serial=it):
                raise Exception('Item already has maintenance on draft')

            startdate = None

            # continue maintenance
            latest = it.latest_main()
            if latest:
                startdate = latest.end

            # if maintenance date used, add one day
            if startdate:
                startdate += timedelta(days=1)

            if not startdate:
                startdate = it.pdate

            if not startdate:
                itinv = it.invoice()
                if itinv:
                    startdate = itinv.idate

            # otherwise use quote date
            if not startdate:
                ii = ItemInv.objects.filter(invoice=inv, item=it)
                if ii:
                    startdate = inv.qdate

            if not startdate:
                raise Exception('Could not determine start date')

            if startdate > mf.end:
                raise Exception("Start date after end date")

            # add back maintenance
            if startdate < inv.qdate:
                back = Maintenance(serial = mf.serial,
                                   invoice = inv,
                                   back = True,
                                   start = startdate,
                                   end = inv.qdate,
                                   price = it.prod.prodprice_set.get(cur=inv.cur).bmprice,
                                   discount = mf.discount,
                                   vat = mf.vat,
                                   parent = latest)
                latest = back.save()
                startdate = inv.qdate

            nm = Maintenance(serial = it,
                             invoice = inv,
                             start = startdate,
                             end = mf.end,
                             price = it.prod.prodprice_set.get(cur=inv.cur).mprice,
                             discount = mf.discount,
                             vat = mf.vat,
                             parent = latest)
            nm.save()
            updateinvoice(inv.iid)
            return redirect('invoice.invoice.invoice', inv.iid)
else:
        mform = InvAddMainForm()
    # vat = null AND pdate = null, license imported and removed
    mform.fields['serial'].queryset = Item.objects.filter(
                                                          account__in=cust_acc
                                                          ).exclude(
                                                                    prod__in=Product.objects.filter(prodprice__mprice__exact=0, prodprice__cur=inv.cur)
                                                                    ).exclude(
                                                                              disabled=True
                                                                              ).exclude(
                                                                                        vat__isnull=True,
                                                                                        pdate__isnull=True
                                                                                        )
    mform.fields['discount'].initial = def_discount
    mform.fields['vat'].initial = Vat.objects.get(name=calcVAT(inv.customer.main_address.country.cc, inv.customer.vatnr, 'PTS'), disabled=False)
...

テンプレートは単に form.as_table() を呼び出します...魔法はありません...

トレースバックは次のようになります。

AttributeError at /invoice/10013/
'NoneType' object has no attribute 'model'
Request Method: POST
Request URL:    http://127.0.0.1:8000/invoice/10013/
Django Version: 1.3.1
Exception Type: AttributeError
Exception Value:    
'NoneType' object has no attribute 'model'
Exception Location: /usr/lib/python2.7/dist-packages/django/forms/models.py in to_python, line 973
Python Executable:  /usr/bin/python
Python Version: 2.7.3
Python Path:    
['/home/ruben/mnt/derby/v2',
 '/usr/lib/python2.7',
 '/usr/lib/python2.7/plat-linux2',
 '/usr/lib/python2.7/lib-tk',
 '/usr/lib/python2.7/lib-old',
 '/usr/lib/python2.7/lib-dynload',
 '/usr/local/lib/python2.7/dist-packages',
 '/usr/lib/python2.7/dist-packages',
 '/usr/lib/python2.7/dist-packages/PIL',
 '/usr/lib/python2.7/dist-packages/gst-0.10',
 '/usr/lib/python2.7/dist-packages/gtk-2.0',
 '/usr/lib/python2.7/dist-packages/ubuntu-sso-client',
 '/usr/lib/python2.7/dist-packages/ubuntuone-client',
 '/usr/lib/python2.7/dist-packages/ubuntuone-control-panel',
 '/usr/lib/python2.7/dist-packages/ubuntuone-couch',
 '/usr/lib/python2.7/dist-packages/ubuntuone-installer',
 '/usr/lib/python2.7/dist-packages/ubuntuone-storage-protocol']
Server time:    Wed, 22 Aug 2012 14:13:06 +0200
Traceback Switch to copy-and-paste view

/usr/lib/python2.7/dist-packages/django/core/handlers/base.py in get_response
                        response = callback(request, *callback_args, **callback_kwargs) ...
▶ Local vars
/usr/lib/python2.7/dist-packages/django/db/transaction.py in inner
                res = func(*args, **kwargs) ...
▶ Local vars
/home/ruben/mnt/derby/v2/invoice/invoice.py in invoice
        print str(mform) ...
▶ Local vars
/usr/lib/python2.7/dist-packages/django/utils/encoding.py in __str__
        return self.__unicode__().encode('utf-8') ...
▶ Local vars
/usr/lib/python2.7/dist-packages/django/forms/forms.py in __unicode__
        return self.as_table() ...
▶ Local vars
/usr/lib/python2.7/dist-packages/django/forms/forms.py in as_table
            errors_on_separate_row = False) ...
▶ Local vars
/usr/lib/python2.7/dist-packages/django/forms/forms.py in _html_output
        top_errors = self.non_field_errors() # Errors that should be displayed above all fields. ...
▶ Local vars
/usr/lib/python2.7/dist-packages/django/forms/forms.py in non_field_errors
        return self.errors.get(NON_FIELD_ERRORS, self.error_class()) ...
▶ Local vars
/usr/lib/python2.7/dist-packages/django/forms/forms.py in _get_errors
            self.full_clean() ...
▶ Local vars
/usr/lib/python2.7/dist-packages/django/forms/forms.py in full_clean
        self._clean_fields() ...
▶ Local vars
/usr/lib/python2.7/dist-packages/django/forms/forms.py in _clean_fields
                    value = field.clean(value) ...
▶ Local vars
/usr/lib/python2.7/dist-packages/django/forms/fields.py in clean
    def clean(self, value):
        """
        Validates the given value and returns its "cleaned" value as an
        appropriate Python object.
        Raises ValidationError for any errors.
        """
        value = self.to_python(value) ...
        self.validate(value)
        self.run_validators(value)
        return value
    def bound_data(self, data, initial):
        """
▶ Local vars
/usr/lib/python2.7/dist-packages/django/forms/models.py in to_python
    def to_python(self, value):
        if value in EMPTY_VALUES:
            return None
        try:
            key = self.to_field_name or 'pk'
            value = self.queryset.get(**{key: value})
        except (ValueError, self.queryset.model.DoesNotExist): ...
            raise ValidationError(self.error_messages['invalid_choice'])
        return value
    def validate(self, value):
        return Field.validate(self, value)
▼ Local vars
Variable    Value
self    
<invoice.forms.SelectMaintenanceSerialField object at 0x7f14c83dc250>
value   
u'100035'
key 
'pk'

組み込みコードが機能しない最後の部分で混乱しています

編集: 今、私は問題を発見しましたが、原因ではありません...フォームにカスタムメイドのフォームフィールドを使用しています。このフィールドは SelectMaintenanceSerialField と呼ばれます。デフォルトのフィールドを使用すると、すべてが正常に機能します。カスタム フィールドのコードは次のようになります。

class SelectMaintenanceSerialField(ModelChoiceField):
    '''
    When adding maintenance to a product on a draft; formerly,
    only the serial of the product was shown. This field allows
    for a custom label for that form
    '''
    def label_from_instance(self, obj):
        '''
        This method sets the label for each of the objects of the queryset
        '''
        item = Item.objects.get(pk=str(obj.serial))
        name = item.prod.name
        return "%s, %s"%(str(obj.serial), str(name))

このフォームに何か問題があるか、何かを追加する必要があります。テンプレートをレンダリングするときは意図したとおりにフォームが表示されますが、データを送信するときは明らかに機能しません

4

1 に答える 1

2

ご迷惑をおかけして申し訳ありません...問題が見つかりました...クエリセットはビューが評価されたときにのみ決定できるため、カスタムフィールドは空のクエリセットで作成されます。フォームのインスタンスがFORMデータから作成されるときに、クエリセットを編集するのを忘れていました。今では意図したとおりに機能します

于 2012-08-22T12:37:10.143 に答える