我有两个模型:
if ( !obj && cat && cat.length > 0 && category_name_for_display )
{
var arr = {};
arr[cat] = category_name_for_display;
category_names_for_display.push(arr);
}
出于搜索目的,我需要查询以下内容:
选择所有朋友和朋友的朋友(不包括自己)
用户名__startswith(class User(AbstractBaseUser, PermissionsMixin):
username = models.CharField(db_index=True, max_length=20, unique = True)
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
full_name = models.CharField(db_index=True, max_length=256, null=True)
friends = models.ManyToManyField("self", related_name = 'friends', symmetrical=True)
)或full_name__startswith(query
)
给定结构,我不知道该怎么做:需要访问朋友,然后访问朋友并反转query
对象。因此,问题是:
我可以避免循环浏览结果并应用过滤器使数据库正常工作吗?
答案 0 :(得分:0)
为什么UserProfile
是一个单独的类?似乎这些字段属于User
。
您不问任何问题,因此几乎可以肯定的是,我最多只能提供部分答案。希望它能帮助您入门。 要访问朋友,您可以:
profile = UserProfile.objects.get(pk=1)
friends = UserProfile.friends.all().prefetch_related('friends')
for friend in friends:
f_user = friend.user
f_friends = friend.friends.all().prefetch_related('friends')
这在规模上将是低效的,但对于单个UserProfile
来说很好。否则,可以使用cached_property。实际上,文档似乎与您的问题相似。
如果您要从friends
s个查询集中获取UserProfile
,则应该.prefetch_related('friends')
class UserProfile(models.Model):
...
@cached_property
def my_friends(self):
return [f for f in self.friends.all().prefetch_related('friends')]
如果我没记错的话,使用这样的列表理解功能可以使您每次都免于命中数据库。
答案 1 :(得分:0)
由于朋友是profile = UserProfile.objects.get(user=<some_user>)
all_profiles = UserProfile.objects.filter(Q(user__username__startswith=query) |
Q(full_name__startswith=query)).distinct()
profile_friends = all_profiles.filter(friends=profile)
friends_of_friends = all_profiles.filter(friends__in=profile_friends)
all_friends = profile_friends | friends_of_friends
,也许是这样:
distinct
我还没有测试过,但是我认为它非常接近。可能会有一些重复,因此可能需要应用最后的{{1}}。