如何在多个约束下从db获取对象?

时间:2016-05-12 19:06:04

标签: python django django-models django-filter

我正试图弄清楚如何有效地从Django中的数据库中获取特定的对象集。

我可以使用嵌套循环来做到这一点,但我认为这不是一个好主意。

我的模型LanguageUserProfile有一个属性方法verified_languages,它为此Language返回一组UserProfile个对象。

我想要的是创建名为Language的{​​{1}}模型的静态方法,如果这些get_to_languages(language) languages,则返回所有UserProfiles的所有UserProfiles } language属性方法中包含verified_languages属性。

所以,如果有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']

我称之为方法get_to_languages(Languages.objects.get(name='german'))

它将返回一套Evgen和Peter的语言,因为他们知道德语。

是否可以使用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

1 个答案:

答案 0 :(得分:0)

好吧,我认为可以这样做:首先,获取包含当前语言的所有LanguageLevel,并且level_name不是unknown,然后从结果中获取所有用户配置文件{ {1}}。最后,将所有语言链接到这些用户配置文件(显然它未经测试,但请尝试一下):

LanguageLevel

请注意,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() 的效率非常低,但如果您没有大量的记录,则应该没问题。只需注意性能,看看是否顺利。