
..... class Detect(models.Model): def chioce_id(self): data = self.objects.all() id = len(data) + 1 return id detect_id = models.BigIntegerField(verbose_name='编号',default=chioce_id) ....... 为什么一直报我错呢? 我想弄个可自填可手改的序号, 这方法在类里不能用吗?有别的法吗?
1 blueaurora 2022-04-25 21:43:31 +08:00 虽然你没有把错误的 log 贴上来,但是能发现一个错误: data = self.objects.all() .把 self 改成 Detect ,即: data = Detect.objects.all() 因为 objects 是类中的,不是实例中的 |
2 blueaurora 2022-04-25 21:45:44 +08:00 至于 default=choice_id , 我感觉也是不对的.. 因为 choice_id 方法 却是实例中的,但字段又是类中的.. |
3 maloneleo88 OP |
4 blueaurora 2022-04-25 21:48:43 +08:00 把 detect_id 的修改逻辑从字段的 default 里摘出来吧。 不要写在 model 类的定义当中了吧 |
5 blueaurora 2022-04-25 21:49:51 +08:00 @maloneleo88 嗯嗯,default 的这个,我只是感觉可能有问题,但如果你跑通了那就忽略质疑吧, 这就是 python.. |
6 maloneleo88 OP |
7 blueaurora 2022-04-25 21:51:56 +08:00 在 java 中,类一般都是静态写好的;但在 python 中,动态创建新类和修改类 跟玩似的 |
8 maloneleo88 OP @blueaurora 真的是到处都弄不明白,我一般是弄不了了就上 js 魔改 - -! |
9 blueaurora 2022-04-25 21:54:45 +08:00 @maloneleo88 啊,比如这里 default 就是 0 或 -1 ; 然后 detect_id 的变化逻辑,写在业务中,比如重写 model 的 save ,在 save 时 去修改 detect_id |
10 maloneleo88 OP @blueaurora 你的意思是在 views 里直接拿到 queryset 再往表单 val 里填吧 |
11 gotounix 2022-04-25 22:01:42 +08:00 函数写到类外面,不用参数,self 换成 Detect |
12 westoy 2022-04-25 22:12:03 +08:00 你这个 chioce_id 的生成有点太暴力的啊.......... |
13 maloneleo88 OP @gotounix 放外面不行 NameError: name 'Detect' is not defined |
14 maloneleo88 OP @westoy 哈哈 给出个招 |
15 maloneleo88 OP @gotounix 反正是扔上面找不到类, 扔下面好不到函数。 扔里面就报错 |
16 mimzy 2022-04-25 22:21:08 +08:00 |
17 mimzy 2022-04-25 22:23:18 +08:00 |
18 maloneleo88 OP @mimzy 大佬! 然后怎么调用? 这个没学到过 |
20 mimzy 2022-04-25 22:32:00 +08:00 |
21 westoy 2022-04-25 22:49:10 +08:00 @maloneleo88 metaclass 要在类定义里搞到类名要用黑魔法的 比如你这个 from werkzeug.utils import import_string ...... choice_id = models.IntegerField( default = (lambda m=f"{__module__}.{__qualname__}": lambda:import_string(m).objects.aggregate(current=models.Count("pk")+1)['current'])() ) 不过不建议使用, 代码还是写的清楚一点比较好 |
22 maloneleo88 OP |
23 westoy 2022-04-25 23:02:26 +08:00 @maloneleo88 直接 default=lambda : Detect.objects.aggregate(current=models.Count("pk")+1)['current'] 啊 |
24 xhzhang 2022-04-26 09:04:44 +08:00 这是要实现 id 递增吗?为什么不用 sequence 之类的,要用这么暴力的方法呢 |
25 xhzhang 2022-04-26 09:10:33 +08:00 看你这个是要支持自填,非自填情况下要取当前总条数+1 。 这个 id 如果是有唯一要求,自填的 id 还要先检查是否已有 ,并抛出错误。 如果没有唯一性要求,那就没有必要加个 choice_id 这种方法,用 uuid ,rangdom 之类的生成随机序列作为编号,另外加一个字段建立 sequence 用于区分不同的数据。 主要是不懂为何会有你现在这种需求,没有业务目标直接写代码,感觉怪怪的 |
26 ray5173 2022-04-26 09:58:44 +08:00 写外面没问题的,不知道你用的那个版本的 django ,我用 1.10 ,代码里有一个类似的需求(默认取当前最大值+1),就是通过 chioce_id 函数放外面实现的。 |
27 45HXlKzal6W56zUJ 2022-04-26 10:19:34 +08:00 楼主听我的,django 默认有个 id 就是自增的,所以如果不是特别需要,你这个 id 字段没有必要创建。 第二, 你这个 id 的算法有严重的问题!!!!!! 假设,你有数据库有 30 条数据,那么第 31 条 id 就是 31. 此时进行了一次删除,数据库就又剩 30 ,那么第 32 条的 id 又是 31 了 |
28 wnh3yang 2022-04-26 11:19:17 +08:00 bug 就是麽的 |
29 nonduality 2022-04-26 11:54:16 +08:00 如果没有特殊要求,最好用数据库的自增 id (整数或 uuid 都可以),只需把字段增加一属性 primary=True 。没事别自己 hack 。 |
30 wingor2015 2022-04-26 17:54:35 +08:00 dicc 的意见非常重要,自己定义 id 没有这么简单,但是如果你一定要这么做呢,也能实现 chioce_id 这个方法应该放到 class Detect 定义的外面,才能正确找到,但是放到外面就无法获取到 objects.count (不要用 all 再 len ) 要实现的这个逻辑的话,你可以放到 save 方法里 detect_id = models.BigIntegerField(verbose_name='编号',default=None) def save(self, *args, **kwargs): if not self. detect_id: self. detect_id = self.__class__.objects.count() + 1 super(Detect, self).save(*args, **kwargs) |
31 maloneleo88 OP 感谢大家回复,其实我后来想了下也是没必要的。就是个编号问题,甚至不需要写库里,直接 html 循环出编号就可以了 |
32 954 2022-04-28 09:32:30 +08:00 |
34 954 2022-04-28 09:57:42 +08:00 |