2012-01-13 6 views
20

これを正しく行う方法を明確に理解できません。モデルは以下の通りです:Django unique_together重複を防止していません

class Team(models.Model): 
    teamID=models.CharField(max_length=255) #this will be generated on the iPad 
    name=models.CharField(max_length=255) 
    slug=models.SlugField(max_length=50) 
    teamNumber=models.CharField(max_length=30) 
    checkIn=models.DateTimeField(default=datetime.now()) 
    totalScore=models.IntegerField(max_length=6) 

    class Meta: 
     unique_together = ("teamID", "name", "slug", "teamNumber", "totalScore") 

私が2回続けて提出すると、それはすべて保存されます。 Yikes !!!

+0

また、このモデルをFKとして使用するモデルもありますが、それは何か関係がありますか? – jasongonzales

+0

これはデータベースレベルで強制されます。 'unique_together'フィールドを追加した後に' python manage.py syncdb'を実行したことを覚えましたか? – aganders3

+0

まあ、私はマイグレーションをしました...ただ普通のオールシンクを試してみましょう – jasongonzales

答えて

10

(foo, bar)の代わりに((foo,bar),)の適切なネストされたタプル構文を試してみてください。

https://docs.djangoproject.com/en/dev/ref/models/options/#unique-together

+0

私は...無駄に、私はちょうどここで単純な何かが欠けている必要があります – jasongonzales

+0

OK、ここで問題は、私は、 Django *は重複したエントリを防止しますが、私のDjangoアプリケーションデータを送信している奇妙な小さなモバイルアプリケーションは、Django管理者のような検証を行うことはできませんし、Djangoアプリケーションからメッセージを受け取ることもできません。私はちょうどDjangoがこのデータを全く書いていないことが必要です。私は知っている、これは奇妙なユースケースです。 – jasongonzales

+0

これでアプリに戻って検証エラーメッセージを送信することにしました。私はこれが今働くと思う。誤ったアラームのために申し訳ありません。 – jasongonzales

8

はいparemeterのunique_togetherは、私が二つ以上の要素のタプルをテストしていませんが、それはあなたの例のために

を動作するはずです、入力としてタプルのタプルを受け取る:

unique_together = (("teamID", "name"), ("slug", "teamNumber")) 

または:

unique_together = (("teamID", "name", "slug", "teamNumber", "totalScore")) 
+1

2番目の例では、1要素タプルに必要な末尾のカンマがなく、効果的に長さ4のタプルになります。それは動作しますが、b/c Djangoは一意のグループ化が1つしかない場合はタプルのタプルを必要としません。私の問題は、 'unique_together'がモデルではなくMetaクラスの下にあることを確認して解決されました。 D'oh! – mattmc3

20

aganders3 mentこの制約はデータベースレベルで強制されます。私はあなたがこの種の制約をサポートしていないSQLiteのようなデータベースを使用していると仮定します。

管理者がすべて正常に動作する理由は、それが一意性検査自体を実行しているからです(制約違反を通知するためにデータベースに厳密に依存していない)。

あなたは一意性制約のこの種をサポートしているデータベースエンジンに切り替えることができます(MySQLやPostgresのいずれかが動作します)か、信号を使用してチェックインを追加することで見ることができる:http://djangosnippets.org/snippets/1628/

1

私は追加せず、このアプローチが役に立ったと評価してい不要なフィールド

class Request(models.Model): 
user = models.ForeignKey(User, related_name='request_list', on_delete=models.CASCADE) 
requested_user = models.ForeignKey(User, on_delete=models.CASCADE) 
request_date = models.DateField(default=timezone.now()) 
request_status = models.BooleanField(default=False) 

def save(self, *args, **kwargs): 
    # Checking for duplicate requests 
    try: 
     request = Request.objects.get(user=self.user, requested_user=self.requested_user) 
     raise ValidationError('Duplicate Value', code='invalid') 
    except self.DoesNotExist: 
     super(Request, self).save(*args, **kwargs) 

    # checking for reversed duplicate requests 
    try: 
     request_new = Request.objects.get(requested_user=self.user, user=self.requested_user) 
     raise ValidationError('Duplicate Value', code='invalid') 
    except self.DoesNotExist: 
     super(Request, self).save(*args, **kwargs) 

def __str__(self): 
    return self.user.username + '------>' + self.requested_user.username 
関連する問題