加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

django – 如何在基于过滤器的ManyToMany关系中删除多个对象?

发布时间:2020-12-16 23:02:19 所属栏目:Python 来源:网络整理
导读:给出这两个模型: class Item(models.Model): timestamp = models.DateTimeField()class Source(models.Model): items = models.ManyToManyField(Item,related_name="sources") 我可以在给定的时间之前使用以下内容找到所有的Source的项目: source.items.fi
给出这两个模型:
class Item(models.Model):
    timestamp = models.DateTimeField()

class Source(models.Model):
    items = models.ManyToManyField(Item,related_name="sources")

我可以在给定的时间之前使用以下内容找到所有的Source的项目:

source.items.filter(timestamp__lte=some_datetime)

如何有效地删除与该查询匹配的所有项目?我想我可以尝试这样的事情:

items_to_remove = list(source.items.filter(timestamp__lte=some_datetime))
source.items.remove(*items_to_remove)

但这似乎不好

请注意,我不想删除这些项目,因为它们也可能属于其他来源.我只想删除他们与具体来源的关系.

解决方法

我认为你的钱是正确的,除非你不需要转换成清单.
source.items.remove(*source.items.filter(*args))

remove / add方法如下所示

remove(self,*objs)
add(self,*objs)

和文档http://www.djangoproject.com/documentation/models/many_to_many/
使用[p1,p2,p3]的形式添加多个示例,所以我会下注相同的删除,看到参数是一样的.

>>> a2.publications.add(p1,p3)

多一点挖掘,remove函数逐个迭代* obj,检查它是否是有效的模型,否则使用值作为PK,然后删除与pk__in的项目,所以我会说是的,最好的方法是首先查询您的m2m表,以删除对象,然后将这些对象传递给m2m管理器.

# django.db.models.related.py
    def _remove_items(self,source_field_name,target_field_name,*objs):
        # source_col_name: the PK colname in join_table for the source object
        # target_col_name: the PK colname in join_table for the target object
        # *objs - objects to remove

        # If there aren't any objects,there is nothing to do.
        if objs:
            # Check that all the objects are of the right type
            old_ids = set()
            for obj in objs:
                if isinstance(obj,self.model):
                    old_ids.add(obj.pk)
                else:
                    old_ids.add(obj)
            if self.reverse or source_field_name == self.source_field_name:
                # Don't send the signal when we are deleting the
                # duplicate data row for symmetrical reverse entries.
                signals.m2m_changed.send(sender=rel.through,action="pre_remove",instance=self.instance,reverse=self.reverse,model=self.model,pk_set=old_ids)
            # Remove the specified objects from the join table
            db = router.db_for_write(self.through.__class__,instance=self.instance)
            self.through._default_manager.using(db).filter(**{
                source_field_name: self._pk_val,'%s__in' % target_field_name: old_ids
            }).delete()
            if self.reverse or source_field_name == self.source_field_name:
                # Don't send the signal when we are deleting the
                # duplicate data row for symmetrical reverse entries.
                signals.m2m_changed.send(sender=rel.through,action="post_remove",pk_set=old_ids)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读