你如何在Django ORM中同时进行多个连接?

时间:2018-02-07 08:35:43

标签: python django join

鉴于一堆图形地图,我需要查询用户有权访问哪些地图,因为他拥有地图或因为他已被授予“会员资格”。

有一个Map_desc(地图描述)模型,对于Map_desc中的每个对象,可能有很多Mapmembership对象。

因为它稍后将被提供给模板中的ModelChoiceFields,所以我需要一个QuerySet来返回所有具有相关Mapmembership对象的Map_desc对象,以及所有已设置为“owner”的Map_desc对象。

这是一个简单的连接,但令人惊讶的是难以在Django中完成。

models.py(简化)

class Map_desc(models.Model):
  owner = models.ForeignKey(User, null=False, on_delete=models.CASCADE)

class Mapmember(models.Model):
  member = models.ForeignKey(User, null=False, on_delete=models.CASCADE)
  ofmap = models.ForeignKey(Map_desc, null=False, on_delete=models.CASCADE)

我首先尝试没有工作(半伪代码):

shared = Map_desc.objects.filter(id=mapmember_set.ofmap)

然后是另一个获取地图的查询:

owned = Map_desc.objects.filter(owner=thisUser)

将它们与

绑在一起
accessiblemaps = chain(shared,owned)

问题在于因为有多个Map_desc对象,所以mapmember_set实际上不可用。如果您使用 .first()将查询限制为一个Map_desc,它确实有效,这就是我发现的所有教程和SO问题。

所以我提出了以下解决方案,确实工作,但我想知道是否有更有效的方法,或者只是有不同的方法可以帮助我理解ORM的意图用于涉及多个“父对象”行的连接。

views.py

from django.db.models import Q

def all_accessible_maps(request, thisUser):
  # Returns maps thisUser has access to, whether owned or as a 'member'
  try:
    sharedmaps = Mapmember.objects.filter(member=thisUser).values_list('ofmap')
    allaccessible = Map_desc.objects.filter(Q(id__in=sharedmaps) | Q(owner=thisUser))    
  except:
    raise

all_accessible_maps.alters_data = True

1 个答案:

答案 0 :(得分:1)

您只需添加Q(mapmember__member=thisUser)__即可加入Mapmember表:

Map_desc.objects.filter(Q(owner=thisUser) | Q(mapmember__member=thisUser))