2016-04-19 5 views
0

私は形でクリーンな方法を使用して、データをきれいにしようとしているが、私はそれをやったとき、私はジャンゴから私の形でその唯一のエラーページを検証エラーを参照してくださいいけません。Djangoのフォームクリーンなデータ

は私が編集を持っているし、フォームを作成し、私は1つの場所で、このクリーンを持っていますが、2つのビューにコピーしないしたいと思います。

あなたは私にいくつかのアドバイスを与えることはできますか? 私はフォームできれいで有効なドキュメントを読んでいますが、それでも問題はあります。私はそれの例を与える:

Views.py

@user_passes_test(lambda u: u.is_staff, login_url='/account/login/') 
def client_create(request): 

    dict = {} 

    if request.method == 'POST': 
     form_user = ClientUserCreateForm(request.POST, prefix="user") 
     form_client = ClientForm(request.POST, prefix="client") 
     if form_user.is_valid() and form_client.is_valid(): 
      obj_user = form_user.save(commit=False) 
      obj_client = form_client.save(commit=False) 

      obj_user.username = form_client.cleaned_data['vat'] 
      obj_user.set_password(form_client.cleaned_data['vat']) 
      obj_user.is_active = 1 
      obj_user.save() 

      obj_client.id_id = obj_user.id 
      obj_client.save() 

       # Redirect to Client profile 
       return HttpResponseRedirect(reverse('client_profile', args={obj_client.id_id})) 

     # If forms have error show view again with errors 
     dict['form_user'] = form_user 
     dict['form_client'] = form_client 
     return render(request, 'panel/client/form.html', dict) 
    else: 
     dict['form_user'] = ClientUserCreateForm(prefix="user") 
     dict['form_client'] = ClientForm(prefix="client") 
     return render(request, 'panel/client/form.html', dict) 

にForms.py

class ClientUserCreateForm(forms.ModelForm): 
    first_name = forms.CharField(required=True) 
    last_name = forms.CharField(required=True) 
    email = forms.CharField(required=True) 

    class Meta: 
     model = User 
     fields = ('first_name', 'last_name', 'email') 

    def __init__(self, *args, **kwargs): 
     super(ClientUserCreateForm, self).__init__(*args, **kwargs) 
     self.fields['first_name'].widget.attrs.update({ 
      'type': 'text', 
      'class': 'form-control', 
      'id': 'input-text', 
     }) 
     self.fields['last_name'].widget.attrs.update({ 
      'type': 'text', 
      'class': 'form-control', 
      'id': 'input-text', 
     }) 
     self.fields['email'].widget.attrs.update({ 
      'type': 'text', 
      'class': 'form-control', 
      'id': 'input-text', 
     }) 

    def clean(self): 
     data = self.cleaned_data 

     first_name = data.get('first_name') 
     last_name = data.get('last_name') 
     email = data.get('email') 

     data['first_name'] = first_name[0].upper() + first_name[1:].lower() 
     data['last_name'] = last_name[0].upper() + last_name[1:].lower() 
     data['email'] = email.lower() 

     return data 


class ClientForm(forms.ModelForm): 
    tags = forms.CharField(widget=forms.Textarea, required=False) 

    class Meta: 
     model = Client 
     fields = ('address', 'zip_code', 'city', 'country', 'forwarding_address', 
        'forwarding_zip_code', 'forwarding_city', 'forwarding_country',) 

    def __init__(self, *args, **kwargs): 
     super(ClientForm, self).__init__(*args, **kwargs) 
     self.fields['country'].queryset = CountriesChoices.objects.all() 
     self.fields['forwarding_country'].queryset = CountriesChoices.objects.all() 
     self.fields['country'].initial = 1 
     self.fields['address'].widget.attrs.update({ 
      'type': 'text', 
      'class': 'form-control', 
      'id': 'input-text', 
     }) 
     self.fields['zip_code'].widget.attrs.update({ 
      'type': 'text', 
      'class': 'form-control', 
      'id': 'input-text', 
     }) 
     self.fields['city'].widget.attrs.update({ 
      'type': 'text', 
      'class': 'form-control', 
      'id': 'input-text', 
     }) 
     self.fields['country'].widget.attrs.update({ 
      'class': 'form-control', 
     }) 


    def clean(self): 
     data = self.cleaned_data 

     address = data.get('address') 
     zip_code = data.get('zip_code') 
     city = data.get('city') 
     forwarding_address = data.get('forwarding_address') 
     forwarding_zip_code = data.get('forwarding_zip_code') 
     forwarding_city = data.get('forwarding_city') 

     data['address'] = address[0].upper() + address[1:].lower() 
     data['zip_code'] = zip_code 
     data['city'] = city[0].upper() + city[1:].lower() 

     if len(forwarding_address) > 0: 
      data['forwarding_address'] = forwarding_address[0].upper() + forwarding_address[1:].lower() 
     else: 
      data['forwarding_address'] = address[0].upper() + address[1:].lower() 

     if len(forwarding_zip_code) > 0: 
      data['forwarding_zip_code'] = forwarding_zip_code 
     else: 
      data['forwarding_zip_code'] = zip_code 

     if len(forwarding_city) > 0: 
      data['forwarding_city'] = forwarding_city[0].upper() + forwarding_city[1:].lower() 
     else: 
      data['forwarding_city'] = city[0].upper() + city[1:].lower() 

     return data 

をたとえば私は、フィールド "FIRST_NAME"、空のままにして、私はエラーDjangoのページを持ってwith: 'NoneType'オブジェクトは、 "このフィールドは必須です"というエラーのフォームページ以外は、サブスクリプト化できません(以下のトレースバック)。

トレースバック

Environment: 


Request Method: POST 
Request URL: http://127.0.0.1:8000/panel/client/edit/6/ 

Django Version: 1.8.8 
Python Version: 3.5.1 
Installed Applications: 
('django.contrib.admin', 
'django.contrib.auth', 
'django.contrib.contenttypes', 
'django.contrib.sessions', 
'django.contrib.messages', 
'django.contrib.staticfiles', 
'core', 
'api', 
'client', 
'registration', 
'avatar', 
'filer', 
'mptt', 
'easy_thumbnails', 
'reversion') 
Installed Middleware: 
('django.contrib.sessions.middleware.SessionMiddleware', 
'django.middleware.common.CommonMiddleware', 
'django.middleware.csrf.CsrfViewMiddleware', 
'django.contrib.auth.middleware.AuthenticationMiddleware', 
'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 
'django.contrib.messages.middleware.MessageMiddleware', 
'django.middleware.clickjacking.XFrameOptionsMiddleware', 
'django.middleware.security.SecurityMiddleware') 


Traceback: 
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\core\handlers\base.py" in get_response 
    132.      response = wrapped_callback(request, *callback_args, **callback_kwargs) 
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\contrib\auth\decorators.py" in _wrapped_view 
    22.     return view_func(request, *args, **kwargs) 
File "C:\Users\loc\PycharmProjects\pro\core\views.py" in client_edit 
    192.   if form_user.is_valid() and form_client.is_valid(): 
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\forms\forms.py" in is_valid 
    184.   return self.is_bound and not self.errors 
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\forms\forms.py" in errors 
    176.    self.full_clean() 
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\forms\forms.py" in full_clean 
    393.   self._clean_form() 
File "C:\Users\loc\dJangoEnvironment\lib\site-packages\django\forms\forms.py" in _clean_form 
    417.    cleaned_data = self.clean() 
File "C:\Users\loc\PycharmProjects\pro\core\forms.py" in clean 
    421.   data['first_name'] = first_name[0].upper() + first_name[1:].lower() 

Exception Type: TypeError at /panel/client/edit/6/ 
Exception Value: 'NoneType' object is not subscriptable 
+1

Djangoのエラーページとは何ですか? – primoz

+0

@Primozたとえば、 "first_name"フィールドを空白のままにして、djangoページに「NoneType」オブジェクトが「このフィールドは必須です」というフォームページを除いてサブスクリプトできません。私はクリーンメソッドをコメントし、その仕事が正しいとき。 – Thaian

+0

'obj_user.username = form_client.cleaned_data ['vat']'の '' vat ''の意味は何ですか? これはあなたの間違いだと思いますが、これは何であるか説明できますか? –

答えて

3

あなたは、個々のclean_<fieldname>方法でそのように検証を行う必要があります。それらは、コンテンツがすでに有効であり、読み込まれている場合にのみ呼び出されます。だから、:あなたのFIRST_NAMEとLAST_NAME検証も

def clean_firstname(self): 
    first_name = self.cleaned_data['first_name'] 
    return first_name[0].upper() + first_name[1:].lower() 

def clean_last_name(self): 
    last_name = self.cleaned_data['last_name'] 
    return last_name[0].upper() + last_name[1:].lower() 

def clean_email(self): 
    email = self.cleaned_data['email'] 
    return email.lower() 

注意したい正確なフォーマットに変換する、last_name.capitalize()を使用することによって単純化することができます。

+0

私は** ** mailing_email空白と私は取得していますフィールド去るとき、私は他の問題を抱えている:\t ** NOT NULL制約失敗**:core_client.mailing_email - フィールド長とasignをチェックし、私やった方法** ** clean_mailing_email lenngthが0のときの通常の電子メールです。これを解決する方法は? (自己): の場合len(self.cleaned_data ['mailing_email']。lower())> 0: 返されるself.cleaned_data ['mailing_email'] lower() else: return self.cleaned_data。 get( 'email') ' – Thaian

+1

これは、メインの' clean'メソッドで*すべきことです。なぜなら、フィールドが空白の場合には 'clean_mailing_email'も呼び出されないからです。 –

関連する問題