2017-09-21 13 views
0

モデルLanguageを定義しました。言語オブジェクトを作成した人を追跡する必要があります。私は同じ言語の複数のインスタンスを必要としません。そのため、ユーザーが言語を作成しようとしたときに言語が既に存在するかどうかを確認できるようにしたいと考えています。それが存在すれば、私はすでに存在するものを使うことができるとユーザに伝えます。そうでなければ、彼らはそれを作成することができます。私はカスタムUserモデルを使用しています。モデルのインスタンスが既にデータベースに存在するかどうかを確認する方法

USERS = get_user_model().objects.all() 
from random import choice 

class Language(models.Model): 
    language = models.CharField(max_length=25, unique=True) 
    creator = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) 

    def __str__(self): 
     return self.language 

    def get_absolute_url(self): 
     return reverse('chinemerem:language_index') 

    def save(self, *args, **kwargs): 
     self.language = self.language.upper() 
     super(Language, self).save(*args, **kwargs) 

私は以下のようにdjangoshelltry/exceptLanguageインスタンスを作成することができます。私は、Djangoの管理を介して、言語のインスタンスを作成しようとする

try: 
    language, exists = Language.objects.get_or_create(creator=choice(USERS), 
           language='german') 
except IntegrityError: 
    pass 

しかしdjango adminIntegrityErrorスローします。

私の質問:モデル内に上記のtry/exceptブロックを実装して、ユーザーが作成しようとしたときに言語が既に存在するかどうかを確認するにはどうすればよいですか?

私は多くの検索を行い、参考になると思われるsignalsからpre_saveを見つけました。しかし、djangoのドキュメントにはほとんど例がありません。

ご協力いただければ幸いです。

+0

モデルマネージャを作成し、一致する言語が存在するかどうかをチェックするマネージャメソッドを定義します。この場合は常にマネージャメソッドを使用して保存する必要があります –

+0

モジュールレベルの変数としてクエリセットを作成しないでください - 無効なデータで終了します –

+0

[一致するクエリの処理方法オブジェクトを取得するときに存在する](https://stackoverflow.com/questions/33119507/how-to-handle-matching-query-does-not-exist-when-getting-an-object) – Sayse

答えて

3

Your problem comes from the way you call get_or_create() - あなたが検索引数として二つのフィールドを渡すので、最初language='german'creator=<youruserhere>Languageを探してみてください。同じ言語が異なるクリエーターではなく存在している場合、それはORMは、新しいレコードを作成しようとしてwhere句に一致する、と。

languageキックに、一意制約しないソリューションは、中creatorを渡すことですサイドノートとして

language, created = Language.objects.get_or_create(
    # this is used for lookup (get) 
    language="german", 
    # this is used for eventual create 
    defaults={'creator':choice(USERS)} 
    ) 

場合、返されるタプルの2番目の要素はTrue次のようになります。検索はのみとcreatorにのみ必要に応じて新しいレコードを作成するために使用されるlanguagedefaults引数として辞書を作っているので、既に存在するレコードがfだった場合は新しいレコードが作成され、Falseオンド。

あなたのModelAdminに何か変わったことがないか、またはモデルコード全体を投稿していない場合を除いて、エラーメッセージとともにフォームを再表示するだけで、IntegrityError(最終的にフォームの検証とインスタンス保存の間で競合条件が発生しない限り、非常に非常にまれです)。検証中の一意性チェックはModelFormのデフォルトの機能ですので、適用されない唯一の理由は、フォームのclean()メソッドをオーバーライドしてsuper().clean()メソッドを呼び出さないようにすることです。

+0

全モデルコードがあります。あなたの答えから私はあなたが私の質問を完全に理解していないことがわかります。おそらく私はそれをうまく説明しなかったでしょう。しかし、あなたは 'get_or_create'を呼び出す際に**言語**を使うべきであるという事実を私に警告しました。なぜなら、それは興味のある変数であり、作成者ではないからです。 – Parousia

+0

** ...続き... **しかし、私の問題は 'django'シェルで' Language'モデルを作ることではありません。問題は、djangoの管理者が既に存在する言語を作成しようとすると 'UNIQUE制約が失敗しました 'という文句です。たとえば、ユーザー* bruno *が 'Language' * german *を初めて作成するとします。後の別のユーザー* parousia *は同じ* german * 'Language'を作成したいと考えています。 *ドイツ語*は「ユニーク」なので、今や衝突があります。だから問題は:**どのように私はドイツ語*の存在のための '言語'テーブルをチェックし、それがすでに存在すれば正常に終了するのですか?** *優雅な出口は私が探しているものです* – Parousia

+0

@Parousia既に言及したように、何か奇妙な、ジャンゴアドミニストレーターはちょうどここで正しいことを行う必要があります - エラーメッセージでフォームを再表示します。私はちょうどダブルチェックし、それは箱の外で動作します。代わりに500エラーが発生した場合は、あなたのコードに、あなたが投稿しなかったものや、どこかに壊れたものがあります(結局、フォーム検証とインスタンス保存の間で競合条件が発生しない限り、 )。 –

0

あなたは、メソッドが存在するすべての人に

getLanguage = Language.objects.filter(language=request['langugage']).exists() 

if not getLanguage: 
# create the model 
0

感謝を使用することができます。ここで、モデルマネージャの問題をどのように解決したかを説明します。

2つのモデルマネージャを使用しました。モデル管理者の一人としてobjects = models.Manager()を使用しました。私は多くのコードを書き直す必要はありません。

from django.db import models 
class LanguageManager(models.Manager): 
    def language_exists(self, language): 
     return super(LanguageManager, self).get_queryset().filter(language=language.upper()).exists() 

class Language(models.Model): 
    creator = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) 
    language = models.CharField(max_length=25, unique=True) 
    objects = models.Manager() 
    languages = LanguageManager() 

    def __str__(self): 
     return self.language 

    def get_absolute_url(self): 
     return reverse('chinemerem:language_index') 

    def save(self, *args, **kwargs): 
     self.language = self.language.upper() 
     if Language.languages.language_exists(self.language): 
      return "Language already exists." 
     else: 
      super(Language, self).save(*args, **kwargs) 
関連する問題