• 【多对多】多对多取数无序的问题


    orm 中的多对多插入数据,会按照插入顺序在中间表中创建数据

    a 表通过关系字段查到所有的 b 对象,形如 a.filed.all() 此时查出的 b 对象是无序的,会按照 b 对象的创建顺序去除 如插入顺序为 1,7,2,6,11 取值时结果为 1,2,6,7,11 打乱了初始顺序

    此时可以手动创建中间表来管理这部分关系
    另外也可以使用 through 达到这种效果,而且不用多创建表

    a.filed.through.objects.filter(arg=xxx).order_by('id').values_list('funcargs_id')
    通过 through 可以获取 django 自建的第三张表,因为在顺序插入数据的时候,第三章表中的数据会自增,他的 id 可以作为顺序的参照,
    通过第三张表获取到顺序之后,在通过自己的一些处理即可反推出 a.filed.all()中的对象顺序。

    class FuncConfig(models.Model):
       """
       任务处理函数配置
       """
       func_id = models.AutoField(primary_key=True)
       name = models.CharField('名称', max_length=50, null=False, blank=False)
       func = models.CharField('函数', max_length=50, null=False, blank=False)
       config_type = models.CharField('配置类型', choices=CONFIG_TYPE, max_length=64, default='FileConfig')
       args = models.ManyToManyField(FuncArgs, verbose_name='接口参数', blank=True)
       args_name = models.TextField('参数别名', blank=True, null=True)
       args_index = models.CharField('参数顺序', max_length=512, null=True, blank=True)
    
       def __str__(self):
           return f"{self.name}"
    
       class Meta:
           verbose_name = '接口配置'
           verbose_name_plural = '接口配置'
    
       def get_args(self):
           args_data = list(self.args.all().values())
           for i in args_data:
               source = get_source_data(i['source_data'])
               i.update({'source_data': source, 'value': ''})
           # 参数插入顺序
           args_input_index = self.args_index.split(',')
           # 第三方表中的参数 id 顺序
           args_through_index = sorted(args_input_index)
           data = []
           if args_data:
               name_list = self.args_name.split(',')
               # 按照插入顺序
               for index, input_index in enumerate(args_input_index):
                   item = args_data[args_through_index.index(input_index)]
                   # 引入参数别名
                   if name_list:
                       item['name'] = name_list[index]
                   data.append(item)
           return data
       
       # 在 每次 func 对象 save 的时候,会根据目前的顺序在 args_index 上记录
       def save(self, force_insert=False, force_update=False, using=None, update_fields=None, *args, **kwargs):
           args_input_id = self.args.through.objects.filter(funcconfig=self).order_by('id').values_list('funcargs_id')
           self.args_index = ','.join([str(i[0]) for i in args_input_id])
           super().save(*args, **kwargs)
    

    2021-06-07 11:48:47 add 和 set 的区别

    当多对多 set 的时候,django orm 有自己一套插入规则,顺序不会被保证,不论是 obj1.m2m.set(id_list) 还是 obj1.m2m.add(*[obj_list]) 顺序都是经过转化后的,如果要顺序的话,只能做 for 循环遍历,一个一个的 add(obj)

  • 相关阅读:
    收藏CSS经典技巧
    理解这26句话将不再烦恼
    包转发率得计算和背板带宽的计算
    mysql 建表 AUTO_INCREMENT , 数据类型 VARCHAR
    Linux Wine with *.bat *.exe ( Photoshop and etc.. )
    [转载]expect spawn、linux expect 用法小记
    sqlmap.py Database injection and hak
    xls===>csv tables===via python ===> sqlite3.db
    sftp 服务器外网访问设置
    vsftp FTP服务器外网访问设置
  • 原文地址:https://www.cnblogs.com/cizao/p/14850726.html
Copyright © 2020-2023  润新知