鉴于一堆图形地图,我需要查询用户有权访问哪些地图,因为他拥有地图或因为他已被授予“会员资格”。
有一个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
答案 0 :(得分:1)
您只需添加Q(mapmember__member=thisUser)
,__
即可加入Mapmember
表:
Map_desc.objects.filter(Q(owner=thisUser) | Q(mapmember__member=thisUser))