无中间表时如何排序多对多字段值以实现相等比较?
解决Django ManyToMany字段值比较的顺序问题
你的问题出在order_by('pk')的作用对象不对——你当前是对Author模型自身的主键排序,但你筛选的是单个Author对象(filter(id=self.object.update_reader_id)),所以这个排序根本不会改变ManyToMany字段返回的关联对象顺序。要解决顺序导致的比较错误,有两种简单方法,都不需要用到中间表:
方法一:用集合比较(推荐,更简洁)
集合的相等性判断只关注元素是否完全一致,和顺序无关。直接将两个QuerySet转为集合即可:
# 用flat=True让values_list返回单个值而非元组 author_confirm_ids = Author.objects.filter(id=self.object.update_reader_id).values_list('author_confirm', flat=True) author_ids = Author.objects.filter(id=self.object.update_reader_id).values_list('author', flat=True) authors_are_equal = set(author_ids) == set(author_confirm_ids) authors_are_not_equal = not authors_are_equal
方法二:按关联对象的主键排序后比较列表
如果你必须用列表比较,需要指定关联对象的主键作为排序依据,而非Author自身的主键:
# 按author字段关联对象的主键排序 author_ids = Author.objects.filter(id=self.object.update_reader_id).values_list('author', flat=True).order_by('author__pk') # 按author_confirm字段关联对象的主键排序 author_confirm_ids = Author.objects.filter(id=self.object.update_reader_id).values_list('author_confirm', flat=True).order_by('author_confirm__pk') authors_are_equal = list(author_ids) == list(author_confirm_ids) authors_are_not_equal = not authors_are_equal
这里author__pk表示排序author字段关联的对象的主键,这样返回的QuerySet会按关联对象的主键顺序排列,转成列表后比较就不会因为顺序颠倒而判定不相等了。
内容的提问来源于stack exchange,提问作者Steve Smith
相关产品推荐
相关产品推荐

