.....
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
dicc 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
|