17

単純なモデルがあるとしましょう:

Class Contact(models.Model):
    email = models.EmailField(max_length=70,blank=True)
    first = models.CharField(max_length=25,blank=True)
    last = models.CharField(max_length=25,blank=True)

私がやりたいのは、電子メールを一意に設定することですが、そうする際には、空白の電子メールアドレスを除外するようにする必要があります-それは望ましくありません.

このようなことを考えていましたが、これに対処するためのより良い方法があるかどうか疑問に思っています。

from django.core.validators import email_re
from django.core.exceptions import ValidationError

def save(self, *args, **kwargs):
    # ... other things not important here
    self.email = self.email.lower().strip() # Hopefully reduces junk to ""
    if self.email != "": # If it's not blank
        if not email_re.match(self.email) # If it's not an email address
            raise ValidationError(u'%s is not an email address, dummy!' % self.email)
        if Contact.objects.filter(email = self.email) # If it already exists
            raise ValidationError(u'%s already exists in database, jerk' % self.email) 
    super(Contact, self).save(*args, **kwargs)

これを行うより良い方法はありますか?

4

4 に答える 4

24

残念ながら、null=True、unique=True、blank=True を設定するだけでは簡単ではありません。csv またはその他のテキストベースのソースを使用してインポートしようとすると、Django の一部で一意性のために "" が重複してはならないものとして扱われます。

回避策は、次のように save メソッドを上書きすることです。

def save(self, *args, **kwargs):
    # ... other things not important here
    self.email = self.email.lower().strip() # Hopefully reduces junk to ""
    if self.email != "": # If it's not blank
        if not email_re.match(self.email) # If it's not an email address
            raise ValidationError(u'%s is not an email address, dummy!' % self.email)
    if self.email == "":
        self.email = None
    super(Contact, self).save(*args, **kwargs)

次に、unique、null、および blank を使用すると、意図したとおりに機能します。

Class Contact(models.Model):
    email = models.EmailField(max_length=70,blank=True, null= True, unique= True)
于 2013-03-20T20:54:46.037 に答える
10

これを行うだけです:

class Contact(models.Model):
    email = models.EmailField(max_length=70, null=True, blank=True, unique=True)
于 2013-03-15T00:38:26.623 に答える
7

save を使用しようとしましたが、 clean メソッドでエラーが既に発生しているため、それでも機能しませんでした。そのため、モデルの代わりにそれを上書きしました。次のようになります。

Class MyModel(models.Model):
    email = models.EmailField(max_length=70,blank=True)
    first = models.CharField(max_length=25,blank=True)
    last = models.CharField(max_length=25,blank=True)
    phase_id = models.CharField('The Phase', max_length=255, null=True, blank=True, unique=True)

    ...

    def clean(self):
        """
        Clean up blank fields to null
        """
        if self.phase_id == "":
            self.phase_id = None

これは私にとってはうまく機能し、保存を使用した答えは場合によっては機能する可能性があります。これは、基本クラスのクリーンで残りの検証が行われる前に、 "" を None にリセットすることで機能するはずです。乾杯 :)

于 2014-11-19T16:25:42.933 に答える