通过反向关系的Django复杂查询过滤器

时间:2019-06-24 13:27:25

标签: django django-queryset django-filter

我有两个模型:

if ( !obj && cat && cat.length > 0 && category_name_for_display )
{
  var arr = {};
  arr[cat] = category_name_for_display;
  category_names_for_display.push(arr);
}

出于搜索目的,我需要查询以下内容:

  1. 选择所有朋友和朋友的朋友(不包括自己)

  2. 用户名__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对象。因此,问题是: 我可以避免循环浏览结果并应用过滤器使数据库正常工作吗?

2 个答案:

答案 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}}。