首页 文章

如何复制查询集Django

提问于
浏览
2

我试图在保存def save_related(self,request,form,* args,** kwargs)方法之前和之后访问ManyToManyField的queryset . 我想比较它们并获得添加到ManyToManyField的新对象 .

所以,我正在使用旧的queryset:

def save_related(self, request, form, * args, * * kwargs):
    obj = form.instance
    queryset_before = obj.translations.all()
    print(queryset_before)
    super(WordAdmin, self).save_related(request, form, * args, * * kwargs) 
    print(queryset_before)

但是print(queryset_before)在调用super() . save_related之后输出新的,更新的查询集 .

所以:

  • 如何复制queryset,这样保存会不会影响它?

  • 或者有没有办法更正确地比较ManyToManyField的旧值和新值?

2 回答

  • 1

    您可以在保存之前和之后获取ID列表,然后比较这些列表:

    def save_related(self, request, form, *args, **kwargs):
        obj = form.instance
        list_before = list(obj.translations.all().values_list('pk', flat=True))
        super(WordAdmin, self).save_related(request, form, *args, ** kwargs) 
        list_after = list(obj.translations.all().values_list('pk', flat=True))
        added_ids = [x for x in list_after if x not in list_before]
        removed_ids = [y for y in list_before if y not in list_after]
    
  • 1

    问题是打印查询集只会评估查询集的一部分,因此,它不会填充查询集的内部缓存 .

    您需要在进行更改之前完全评估查询集,以便填充内部缓存 . 最简单的方法是使用 bool() 函数:

    def save_related(self, request, form, *args, **kwargs):
        obj = form.instance
        queryset_before = obj.translations.all()
        bool(queryset_before)
        print(queryset_before)
        super(WordAdmin, self).save_related(request, form, *args, **kwargs) 
        print(queryset_before)
    

    现在两个print语句都应该给你相同的结果 .

相关问题