2016-10-20 7 views
0
私は語彙を構築しています

をし、持っている以下のモデル:理解ジャンゴGenericForeignKeyとGenericRelation

class Word(Model): 
name = CharField(max_length=75) 

class EnNoun(Model): 
word = OneToOneField(Word) 

class FrNoun(Model): 
word = ForeignKey(Word) 
gender = CharField() 

同じ単語はEnNounFrNounの両方にすることができます。 EnNounFrNounの両方について、指定した単語の結果を最も少ない数のクエリを使用して取得することは可能ですか(言語と品詞の類似クラスはItAdverbなどあります)。

1つの言語から別の言語への翻訳を保存する方法(20以上のテーブルのクエリはオプションではありません)。

GenericForeignどのようなキーですか? 一般的にどのように使用しますか?

ありがとうございます。

UPDATE

には、次の翻訳クラスを持っている:

@python_2_unicode_compatible 
class Translation(Model): 
    from_content_type = ForeignKey(ContentType, related_name='from_word_content_type') 
    from_object_id = UUIDField(default=uuid.uuid4) 
    from_word = GenericForeignKey('from_content_type', 'from_object_id') 

    to_content_type = ForeignKey(ContentType, related_name='to_word_content_type') 
    to_object_id = UUIDField(default=uuid.uuid4) 
    to_word = GenericForeignKey('to_content_type', 'to_object_id') 

しかし、それは動作しません: フィールド「to_wordは」オートリバース関係を生成しないので、逆に使用することはできません照会。 GenericForeignKeyの場合は、GenericRelationを追加することを検討してください。

答えて

1

GenericForeignKeyはあなたにForeignKey振る舞いを与えることはなく、オブジェクトのいずれかのタイプに対してもしようと、彼らは、オブジェクトタイプのセットのためにそれを行う(彼らは維持するprimery_keyと別のものを維持するために2列、1で定義されている理由のthats contenty_type)。 Djangoは手動でセットアップにそれらを持っている(ForeignKeysとは違って)GenericForeignKeysのための逆の関係を自動的に作成していないため

GenericRelationは、GenericForeignKeyの逆の関係です。

私は翻訳/語彙スタッフでのベストプラクティスに非常に慣れていないんだけど、あなたはGenericRelationsGenericForeignKeysで問題にアプローチしたい場合は、それを行うための一つの方法は、次のようになります。

class Word(Model): 
    name = CharField(max_length=75) 
    nouns = GenericRelation('WordNoun', content_type_field='noun_ct', object_id_field='noun_id') 

class WordNoun(Model): 
    word = ForeignKey(Word) 
    noun_ct = ForeignKey(ContentType, 
     on_delete=models.CASCADE, 
     #this is optional 
     limit_choices_to = {"model__in": ('EnNoun', 'FrNoun')} 
    ) 
    noun_id = PositiveIntegerField() 
    noun = GenericForeignKey('noun_ct', 'noun_id') 

class EnNoun(Model): 
    word = OneToOneField(Word) 

class FrNoun(Model): 
    word = ForeignKey(Word) 
    gender = CharField() 

私たちは、基本的に 、ワード名詞の関係を維持するモデルを作成するこのギブは、以下の

# Having some word 
word = Word.objects.get(pk=1) 

# With 1 query you can get a list with 
# all WordNoun objects for this word. 
word_nouns = word.nouns.all() 

あるこのアプローチの問題は後にあなたがword_nounsリストを取得することで、されています単一のnounインスタンスにアクセスすると、新しいクエリが作成されます。わずかにこれを最適化する

for word_noun in word.nouns.all(): 
    print word_noun.noun #this will make a query 

一つの方法は、prefetch_relatedを使用するので、単一を有する場合(1 EnNoun及び2 FrNounを言うことができます)。

そして代わり4つのクエリ - 各contenty_typeEnNounFrNoun)用word_nouns 1及び2

for word_noun in word.nouns.all().prefetch_related('noun'): 
    print word_noun.noun #this will not make a query 

差を - 各nounためword_nouns 3 1、我々は3つのクエリに最適化クエリの数は、関連するWordNounオブジェクトの数ではなく、異なるContentTypesの数に依存するようになりました。

これは、から1つのcontenty_typeがプリフェッチされているリストにある場合に便利ですが、1つがある場合は違いはありません。Noun per contenty_type`です。

class Word(Model): 
    name = CharField(max_length=75) 

class WordNoun(Model): 
    LANG_CHOICES = (
     ('en', 'English'), 
     ('fr', 'French'), 
    ) 
    word = ForeignKey(Word) 
    lang = models.CharField(max_length=2, choices=LANG_CHOICES) 
    gender = CharField(max_length=2, blank=True, default='') 


#Now accessing all word_nouns would as easy as: 
word_nouns = word.wordnoun_set.all() 
+0

OK:私は考えることができる

別のアプローチは、以下のモデル構造を使用することです。ありがとうございました。私はこの場合GenericForeignKeyが効率的ではないと思います。しかし、私は今翻訳テーブルをやっています。そして私はそれが事実だと思います。アップデート –

+0

を参照してください。この 'to_word'エラーが発生したら?何らかのフィルタリングをしようとしているようですね? 'from_word'と' to_word'属性に 'Word'クラスのみを使用している場合は、' GenericForeignKey'の代わりに通常の 'ForeignKey'を安全に使うことができます。 – Todor

+0

私はget_or_createを使用しました。ジェネリックキーのフィルタリングはどのように行うのですか? –

関連する問題