我正在尝试找到从查询集中的许多对象中删除单个m2m关系的最有效方法。例如,假设我有3个模型类来创建消息传递系统 - 配置文件,将多个配置文件链接在一起的线程,以及链接到单个线程的帖子,并跟踪哪些配置文件尚未读取帖子。
class Profile(models.Model):
# stuff here
class Thread(models.Model):
profiles = models.ManyToManyField('Profile')
class Post(models.Model):
thread = models.ForeignKey('Thread')
not_seen_by = models.ManyToManyField('Profile')
给出个人资料:
prof = Profile.objects.get(id=profile_id)
一个帖子:
thrd = Thread.objects.get(id=thread_id)
一个包含该帖子所有帖子的查询集:
msgs = Post.objects.filter(thread=thrd)
从prof
中的所有not_seen_by
个对象中的Post
字段中删除个人资料msgs
的最有效方法是什么?
最简单的方法是遍历所有对象:
for m in msgs:
m.not_seen_by.remove(prof)
但这似乎效率不高 - prof
可能会也可能不会not_seen_by
。能够在查询集本身上调用方法会更容易 - 像msgs.not_seen_by.remove(prof)
这样的事情。有没有任何方法允许这样的事情?如果是这样,它甚至会更有效率,还是它本质上是运行循环的简写代码?
我已阅读this post,但使用Post.not_seen_by.through.objects
仅允许通过id
,post
和profile
进行过滤,因此我无法限制remove
仅对Posts
thrd
进行操作
答案 0 :(得分:2)
我建议将中间模型显式化,然后直接使用其管理器:
class Profile(models.Model):
# stuff here
class Thread(models.Model):
profiles = models.ManyToManyField('Profile')
class Post(models.Model):
thread = models.ForeignKey('Thread')
not_seen_by = models.ManyToManyField('Profile', through='NotSeenBy')
class NotSeenBy(models.Model):
post = models.ForeignKey('Post')
profile = models.ForeignKey('Profile')
prof = Profile.objects.get(id=profile_id)
thrd = Thread.objects.get(id=thread_id)
NotSeenBy.objects.filter(post__thread=thrd, profile=prof).delete()
答案 1 :(得分:1)
在我的视图中,您可以将删除限制为特定帖子的帖子。
喜欢这个
Post.not_seen_by.through.objects.filter(post__thread=t, profile=prof).delete()
请告诉我是不是错了..
如果这不起作用,您总是可以在Django中使用.raw
编写原始查询。然后使用SQL的魔法来做到这一点。 :);)