我正试图弄清楚如何有效地从Django
中的数据库中获取特定的对象集。
我可以使用嵌套循环来做到这一点,但我认为这不是一个好主意。
我的模型Language
和UserProfile
有一个属性方法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
答案 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()
的效率非常低,但如果您没有大量的记录,则应该没问题。只需注意性能,看看是否顺利。