28

formset で単体テストを実行できません。

私はテストをしようとします:

class NewClientTestCase(TestCase):
    
    def setUp(self):
        self.c = Client()

    def test_0_create_individual_with_same_adress(self):
        
        post_data =  {
            'ctype': User.CONTACT_INDIVIDUAL,
            'username': 'dupond.f',        
            'email': 'new@gmail.com', 
            'password': 'pwd', 
            'password2': 'pwd', 
            'civility': User.CIVILITY_MISTER, 
            'first_name': 'François', 
            'last_name': 'DUPOND', 
            'phone': '+33 1 34 12 52 30', 
            'gsm': '+33 6 34 12 52 30', 
            'fax': '+33 1 34 12 52 30', 
            'form-0-address1': '33 avenue Gambetta', 
            'form-0-address2': 'apt 50', 
            'form-0-zip_code': '75020', 
            'form-0-city': 'Paris', 
            'form-0-country': 'FRA', 
            'same_for_billing': True,            
        }
        
        response = self.c.post(reverse('client:full_account'), post_data, follow=True)   

        self.assertRedirects(response, '%s?created=1' % reverse('client:dashboard'))

そして、私はこのエラーがあります:

ValidationError: [u'ManagementForm データが見つからないか、改ざんされています']

私の見解 :

def full_account(request, url_redirect=''):    
    from forms import NewUserFullForm,  AddressForm,  BaseArticleFormSet
    
    fields_required = []
    fields_notrequired = []
    
    AddressFormSet = formset_factory(AddressForm, extra=2,  formset=BaseArticleFormSet)
    
    if request.method == 'POST':        
        form = NewUserFullForm(request.POST)        
        objforms = AddressFormSet(request.POST)            
       
        if objforms.is_valid() and form.is_valid():            
            user = form.save()            
            address = objforms.forms[0].save()

            
            if url_redirect=='':
                url_redirect = '%s?created=1' % reverse('client:dashboard')
                logon(request, form.instance)            
            return HttpResponseRedirect(url_redirect)
    else:
        form = NewUserFullForm()
        objforms = AddressFormSet()   
    
    return direct_to_template(request, 'clients/full_account.html', {
        'form':form,
        'formset': objforms, 
        'tld_fr':False, 
    })

と私のフォームファイル:

class BaseArticleFormSet(BaseFormSet):

    def clean(self):        
        
        msg_err = _('Ce champ est obligatoire.')
        non_errors = True
        
        if 'same_for_billing' in self.data and self.data['same_for_billing'] == 'on':
            same_for_billing = True
        else:            
            same_for_billing = False
        
        for i in [0, 1]:
            
            form = self.forms[i]           
            
            for field in form.fields:                                
                name_field = 'form-%d-%s' % (i, field )
                value_field = self.data[name_field].strip()                
                
                if i == 0 and self.forms[0].fields[field].required and value_field =='':                    
                    form.errors[field] = msg_err                    
                    non_errors = False
                    
                elif i == 1 and not same_for_billing and self.forms[1].fields[field].required and value_field =='':
                    form.errors[field] = msg_err                    
                    non_errors = False
        
        return non_errors

class AddressForm(forms.ModelForm):

    class Meta:
        model = Address

    address1 = forms.CharField()
    address2 = forms.CharField(required=False)
    zip_code = forms.CharField()
    city = forms.CharField()
    country = forms.ChoiceField(choices=CountryField.COUNTRIES,  initial='FRA')
4

7 に答える 7

28

特に、ManagmentForm バリデーターは、POST される次のアイテムを探していることがわかりました。

form_data = {
            'form-TOTAL_FORMS': 1, 
            'form-INITIAL_FORMS': 0 
}
于 2009-12-14T00:29:01.637 に答える
14

すべての Django フォームセットには、投稿に含める必要がある管理フォームが付属しています。公式ドキュメントはそれをかなりよく説明しています。単体テストで使用するには、自分で記述する必要があります。(私が提供したリンクは例を示しています)、またはformset.management_formデータを出力する呼び出し。

于 2009-10-27T13:23:34.487 に答える
7

実際、応答のコンテキストを調べることで、フォームセットにあるものを簡単に再現できます。

以下のコードを検討してください (self.client通常のテスト クライアントである場合):

url = "some_url"

response = self.client.get(url)
self.assertEqual(response.status_code, 200)

# data will receive all the forms field names
# key will be the field name (as "formx-fieldname"), value will be the string representation.
data = {}

# global information, some additional fields may go there
data['csrf_token'] = response.context['csrf_token']

# management form information, needed because of the formset
management_form = response.context['form'].management_form
for i in 'TOTAL_FORMS', 'INITIAL_FORMS', 'MIN_NUM_FORMS', 'MAX_NUM_FORMS':
    data['%s-%s' % (management_form.prefix, i)] = management_form[i].value()

for i in range(response.context['form'].total_form_count()):
    # get form index 'i'
    current_form = response.context['form'].forms[i]

    # retrieve all the fields
    for field_name in current_form.fields:
        value = current_form[field_name].value()
        data['%s-%s' % (current_form.prefix, field_name)] = value if value is not None else ''

# flush out to stdout
print '#' * 30
for i in sorted(data.keys()):
    print i, '\t:', data[i]

# post the request without any change
response = self.client.post(url, data)

重要な注意点

dataを呼び出す前に変更するとself.client.post、DB が変更される可能性があります。結果として、self.client.get特に管理フォームとフォームセット内のフォームの順序については、後続の への呼び出しが同じデータを生成しない可能性があります (基になるクエリセットに応じて異なる順序になる可能性があるため)。この意味は

  • を変更data[form-3-somefield]して呼び出すとself.client.get、同じフィールドが次のように表示される場合がありますdata[form-8-somefield]
  • dataa の前に変更すると、同じ で再度self.client.post呼び出すことはできません。 a を呼び出して、再度再構築する必要があります。self.client.postdataself.client.getdata
于 2016-07-20T11:11:04.923 に答える
0

私のケースは外れ値かもしれませんが、一部のインスタンスでは実際に在庫の「contrib」管理フォーム/テンプレートに設定されたフィールドが欠落しており、エラーが発生していました

「ManagementForm データが見つからないか、改ざんされています」

保存したとき。

問題は、欠落しているインラインを調査しているときに見つかったunicodeメソッド (SomeModel: [Bad Unicode data]) にありました。

得られた教訓は、MS キャラクター マップを使用しないことだと思います。私の問題は下品な分数 (¼、½、¾) に関するものでしたが、さまざまな方法で発生する可能性があると思います。特殊文字については、w3 utf-8 ページからコピー/貼り付けすると修正されました。

追記-utf-8

于 2010-06-16T13:45:36.227 に答える
0

これはまったくフォームセットではないようです。フォームセットには、POST されるすべての値と、Bartek が言及する ManagementForm に常に何らかのプレフィックスがあります。テストしようとしているビューのコードと、それが使用するフォーム/フォームセットを投稿すると、助けになったかもしれません。

于 2009-10-27T13:45:32.807 に答える