【发布时间】:2018-07-17 11:18:58
【问题描述】:
给定一堆图形地图,我需要查询用户可以访问哪些地图,要么是因为他拥有地图,要么是因为他已获得地图的“会员资格”。
有一个 Map_desc(地图描述)模型,对于 Map_desc 中的每个对象,可能有许多 Mapmembership 对象。
因为它稍后将被提供给模板中的 ModelChoiceFields,所以我需要一个 QuerySet 来返回所有具有相关 Mapmembership 对象的 Map_desc 对象,以及所有将“所有者”设置为当前用户的 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
【问题讨论】:
-
看起来您可以使用 ManyToManyField 来表示成员关系