2016-05-12 6 views
0

私はDjangoのデータベースから特定のオブジェクトセットを効率的に取得する方法を見つけようとしています。複数の制約のもとでdbからオブジェクトを取得するには?

ネストされたループを使用してこれを行うことはできますが、それは最善の方法ではないと思います。

私はこのUserProfileためLanguageオブジェクトのセットを返すプロパティメソッドverified_languagesを持っているモデルLanguageUserProfileを持っています。私は正確に何をしたいです

は、これらのUserProfilesverified_languages財産法でlanguage属性を持っている場合、すべてのUserProfilesのすべてlanguagesのセットを返しますget_to_languages(language)呼ばLanguageモデルの静的メソッドを作成することです。だから、

がこれらUser Sがあった場合 -

1st. user: 
name = 'Peter' 
userprofile.verified_languages = ['english','german','arabic','french'] 

2nd. user: 
name = 'Evgen' 
userprofile.verified_languages = ['german','arabic','spanish'] 

3rd. user: 
name = 'Anton' 
userprofile.verified_languages = ['russian','arabic','italian'] 

と私は、彼らがドイツ語を知っているので、それはEvgenのとピーターの言語のセットを返しますget_to_languages(Languages.objects.get(name='german'))

メソッドを呼び出します。

filterを使用すると可能ですか?

私の古いソリューション:

@staticmethod 
def get_languages_to(language): 
    userprofiles = UserProfile.objects.all() 
    result = set() 
    for up in userprofiles: 
     if language in up.languages_verified: 
      result.update(up.languages_verified) 
    result.remove(language) 
    return list(result) 

USERPROFILE:

class UserProfile(models.Model): 
    user = models.OneToOneField(User, related_name='userprofile', help_text=_('Related user')) 
    date_of_birth = models.DateField(null=True, blank=True, help_text=_('Date of birth')) 
    telephone = models.CharField(max_length=40, null=True, blank=True, help_text=_('Your telephone number')) 
    IBAN = models.CharField(max_length=40, null=True, blank=True, help_text=_('Bank account unique number')) 
    created = models.DateTimeField(auto_now_add=True) 
    modified = models.DateTimeField(auto_now=True) 

    MARITAL_STATUS_CHOICES = (
     ('single', 'Single'), 
     ('married', 'Married'), 
     ('separated', 'Separated'), 
     ('divorced', 'Divorced'), 
     ('widowed', 'Widowed'), 
    ) 

    marital_status = models.CharField(max_length=40, choices=MARITAL_STATUS_CHOICES, null=True, blank=True) 

    HOW_DO_YOU_KNOW_ABOUT_US_CHOICES = (
     ('coincidence', u'It was coincidence'), 
     ('relative_or_friends', 'From my relatives or friends'), 
    ) 

    how_do_you_know_about_us = models.CharField(max_length=40, choices=HOW_DO_YOU_KNOW_ABOUT_US_CHOICES, null=True, 
               blank=True) 


    is_translator = models.BooleanField(default=False) 

    language_levels = models.ManyToManyField('LanguageLevel', blank=True, related_name='translators') 

    rating = models.IntegerField(default=0) 

    number_of_ratings = models.BigIntegerField(default=0) 

    @property 
    def languages(self): 
     """ 
     Returns: all languages of current user include not-verified ones 

     """ 
     return [x.language for x in self.language_levels.all()] 

    @property 
    def languages_verified(self): 
     """ 
     Returns: verified languages of current user 

     """ 
     return [x.language for x in self.language_levels.exclude(level__name='unknown')] 

    def passive_skill(self, language): 
     """ 
     True if user has at least passive skill (lowest level) of the language 
     Args: 
      language: Language object 

     Returns: Bool 

     """ 
     if language in self.languages_verified: 
      return True 
     return False 
+0

'Language'は' UserProfile'とm2mの関係にありますか? –

+0

いいえ、明示的にはありません。これは、外部キーとして言語を持つLanguageLevelモデルへのm2mを持っています。私は私の質問の一番下にUserProfileを追加しました。 –

答えて

0

まあ、私はそれがこの方法を行うことができると思う:まず、現在の言語が含まれており、そのlevel_nameがあることすべてLanguageLevelを取得unknownでなければ、すべてのユーザープロファイルを結果LanguageLevelから取得します。最後に、これらのUSERPROFILES(どうやらそれはテストされていないのですが、それを試してみてください)にリンクされているすべての言語を取得:__inは非常に非効率的ですが、あなたは、レコードの膨大な量を持っていない場合、それはだと

language_levels = LanguageLevel.objects.filter(language=language) \ 
             .exclude(level__name='unknown') 

userprofiles = UserProfile.objects.filter(language_levels__in=language_levels) 

all_languages = profiles.values_list('language_levels__language', 
             flat=True).distinct() 

注意をそれ大丈夫なはず。パフォーマンスに注意を払い、それがうまくいくかどうかを確認してください。

+0

ところで、 'through'キーワードを使って、' UserProfile'と 'Language'の間のm2m関係を定義することができます。 djangoの観点から、1つのレベルの関係を保存します。 –

関連する問題