1

OK、UserUpdateFormとRegistrationFormがあります。現在、この機能を備えたそれぞれ:

def clean_email(self):
    email = self.cleaned_data.get('email')

    if email and User.objects.filter(email=email).exclude(pk=self.instance.id).count():
        raise forms.ValidationError('Email already in use.')
    return email

この重複を避けるための理想的な方法は何だろうと思っていました。

お知らせ下さい。

** アップデート **

親関数を呼び出す必要があるが、それにいくつかのものがある場合はどうなりますか?

def clean_email(self):
    email = self.cleaned_data.get('email')

    if email and User.objects.filter(email=email).exclude(pk=self.instance.id).count():
        raise forms.ValidationError('Email already in use.')

    ### THIS BIT IS ONLY NEEDED IN ONE OF THE CHILD FORMS ###
    # Check whether the email was change or not
    if self.instance.email != email:

        # To not change the email in our database until the new one is verified
        return self.instance.email
    ###

    return email
4

4 に答える 4

1

mscの回答を拡張して、基本フォームを作成し、基本フォームを作成してUserUpdateForm拡張RegistrationFormします。

class YourBaseForm(ModelForm):

    def clean_email(self):
        email = self.cleaned_data.get('email')

        if email and User.objects.filter(email=email).exclude(pk=self.instance.id).count():
            raise forms.ValidationError('Email already in use.')
        return email

class UserUpdateForm(YourBaseForm):

    # ....add unique fields or methods here

class RegistrationForm(YourBaseForm):

    # ....add unique fields or methods here

これで、メソッドはとオブジェクトclean_emailの両方で使用できるようになります。UserUpdateFormRegistrationForm

フォームの継承についてもう少し詳しくは、ドキュメントをご覧ください。

アップデート:

サブクラスのメソッドを変更する必要がある場合は、それをオーバーライドできますが、次のようにスーパーclean_emailメソッドへの呼び出しを含めることができます-

UserUpdateForm(YourBaseForm):

    def clean_email(self):
        email = super(UserUpdateForm, self).clean_email()
        if self.instance.email != email:
            return self.instance.email
        return email
于 2013-01-28T07:23:31.357 に答える
1

その機能を持つ基本フォームを作成し、両方のフォームにその機能を拡張させることができます。

于 2013-01-28T03:22:00.537 に答える
1

たとえば、信号を使用します。

 models.py

 @receiver(pre_save, sender=User)
 def User_pre_save(sender, **kwargs):
     email = kwargs['instance'].email
     username = kwargs['instance'].username

     if not email: raise ValidationError("email required")
     if sender.objects.filter(email=email).exclude(username=username).count(): raise ValidationError("email is already exist")      

ビュー.py

 def view_name(request):
     try:
          .......
     except ValidationError, e:
        message_dict = e.update_error_dict({})
        state = message_dict[NON_FIELD_ERRORS] 
 return render(request, 'page.html', {'state':state}) 
于 2013-01-28T03:07:15.357 に答える
1

ベースフォームから継承するか(他の回答が示唆するように)、フォームがモデルから派生しているため、モデルのクリーニングに直接配置できます。このアプローチの唯一の問題は、毎回データベースにヒットすることです。選択肢を示しているだけです。

... モデルの clean() メソッドは、一意性チェックが行われる前に呼び出されます。モデルの clean() フックの詳細については、オブジェクトの検証を参照してください。

class MyModel(models.Model):
   # ... your model
   def clean(self):
        if self.email and User.objects.filter(email=self.email).exclude(pk=self.id).count():
        raise ValidationError('Email already in use.')
于 2013-01-28T04:20:57.877 に答える