我有一个Django模型,它与auth.User
类有两个多对多关系,如:
class Indicator(models.Model):
friends = models.ManyToManyField(User, related_name="+")
enemies = models.ManyToManyField(User, related_name="+")
related_name设置为“+”so that there's no backwards relation,即如果您是用户,我不需要u.friends_set
和u.enemies_set
。
添加,删除和清除“朋友”和“敌人”的工作正常 - 如果我直接在数据库中检查(即不通过Django),我可以看到我所期望的反映。但是,如果我通过Django获取查询集,我会给出'敌人'列表,无论我使用i.friends.all()
还是i.enemies.all()
(假设i
是一个指标实例)。
如果我检查了ManyRelatedManager,我发现through
属性是正确的,如果我理解正确的话,那就是允许添加/删除/清除正常工作的内容:
>>> i.friends.through
<class 'project.app.models.Indicator_friends'>
但是,get_query_set
方法basically获取超类(用户管理器)并使用kwargs i.friends.core_filters
调用过滤器,{'+__pk': 404L}
(如果指标ID)是404)。 core_filters对于“朋友”和“敌人”都是相同的,这解释了为什么我错误地为两者设置了相同的查询集。
我可以解决这个问题(不设置related_name):而不是i.friends.all()
我可以使用:
[friend.user for friend in i.friends.through.objects.filter(indicator__id=i.id)]
然而,这并不优雅。
(Django 1.3 - 我没有尝试过trunk,但是通过阅读代码它似乎具有相同的行为,使用Python 2.7)。
答案 0 :(得分:1)
查看django / db / models / fields / related.py,看来related_name ='+'选项实际上是在ManyToOneRel.is_hidden()中使用最后一个字符串切片进行测试的。因此,只需在任何字符串中添加“+”就可以解决问题,允许您在单个模型中使用唯一的名称,并且仍然忽略向后关系。
答案 1 :(得分:-1)
您可以随时直接为数据库设置自己的查询。我相信查询集确实认为指标是相同的。我不确定朋友和敌人是如何互动的,但也许你只能在那里查询特定的id。