• 坐看云起时
    2021-04-12
    发现一个问题,test_score_of_general_ability 和 paper_score 无法支持 100 分。 虽然很难遇到这么完美的人,但是还是要对面试者抱有信心嘛! 不支持的原因是:decimal_places=1, max_digits=3 表示最多只支持3位数,还有一位给了小数部分。所以范围是 -99.9 ~ 99.9 有负数也不太合理。 所以我就研究了下如何 set range 并且验证。 原来包括两个部分: 1. 需要 from django.core.validators import MaxValueValidator, MinValueValidator 2. 需要 增加 digits:decimal_places=1, max_digits=4 Django 的逻辑是这样的: 1. 首先 decimal_places=1, max_digits=4 确定最大支持范围 2. 然后 MaxValueValidator, MinValueValidator 去做 range 控制。 具体操作: 1. 导入:from django.core.validators import MaxValueValidator, MinValueValidator. 2. 在 models.DecimalField 里面加入:..., validators=[MaxValueValidator(100.0), MinValueValidator(0.0)] 3. 覆盖 class Candidate 的 save 方法去执行 validator,默认是不会执行的!! 我发现这一点花了好多功夫! def save(self, *args, **kwargs): # Run validations self.full_clean() return super().save(*args, **kwargs) 4. 但是如果只是这样就止步,只能算达到我们的需求。遇到 负数和大于100的分数会报错。 可是不完美的是,当遇到不符合的数时,会打印一堆的 异常信息,看着太难受了。 所以呢,我进一步优化了 save 方法里面的异常处理: def save(self, *args, **kwargs): try: self.full_clean() return super().save(*args, **kwargs) except ValidationError as e: print("Saving candidate [" + self.username + "] failed") print("Print out key/value for debug purpose as below:") for k,v in self.__dict__.items(): if not k.startswith("_"): if str(v) != "" and str(v) != "None": print(" " + str(k) + " : " + str(v)) print("Exception error message: " + str(e)) sys.exit(1) 这样呢,就可以在出错的时候打印所有字段的名字和值,结合异常信息 str(e) 就很清楚了,给大家看看我的输出: Import 刘备 successfully! Saving candidate [诸葛亮] failed Print out key/value for debug purpose as below: username : 诸葛亮 city : 沂南县 phone : 18100000004 bachelor_school : 北大 major : 定国安邦 degree : 教授 test_score_of_general_ability : -2 paper_score : 100 Exception error message: {'test_score_of_general_ability': ['确保该值大于或等于0.0。']}
    展开

    作者回复: 赞

    共 3 条评论
    13
  • 坐看云起时
    2021-04-11
    对于 使用 csv 库,如果不删除第一行表头,可以这样做: with open(path, 'rt', encoding='utf-8-sig') as f: reader = csv.reader(f, dialect='excel', delimiter=',') header = next(reader) if header != None: for row in reader: print(row[0] + " " + row[1])

    作者回复: 赞,指定encoding的方法更优雅

    
    2
  • 现在也用吹风机
    2021-01-15
    为什么candidate对象数据会自动导入到数据库呢。没看到写数据库操作呀

    作者回复: 一行代码 Candidates.objects.create()就保存到数据库中了,不需要更多的代码了。

    
    1
  • 黑牛
    2021-09-12
    如何实现让HR自己导入csv或者xls?

    作者回复: 可以自己实现一个页面

    共 2 条评论
    
  • bowfgc
    2021-08-07
    UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 4: illegal multibyte sequence 我的电脑是Mac 英文OS 与评论区的同学遇到相同的问题,更换为中文语言后依旧报错。 继续查找原因,mac下的encoding的编码有问题,在stackoverflow上找到一个问题的答案,把encoding修改为'ISO-8859-1'进行解码,虽然不报上面的错误,通过读取文件后进行遍历,捕捉异常得到line contains NUL,证明这个excel文件还是有问题。 换个思路来考虑,既然是要读取excel文件为什么不用专门的库去处理呢? 解决思路: 1. 安装xlrd模块 pip install xlrd==1.2.0 指定低版本,默认安装的高版本会报错,xlrd.biffh.XLRDError: Excel xlsx file; not supported 2. 更新代码 import xlrd def handle(self, *args, **kwargs): path = kwargs['path'] data = xlrd.open_workbook(path) table = data.sheet_by_index(0) row_num = table.nrows try: for row in range(0, row_num): candidate = Candidate.objects.create( username=table.row_values(row)[0], city=table.row_values(row)[1], phone=table.row_values(row)[2], bachelor_school=table.row_values(row)[3], major=table.row_values(row)[4], degree=table.row_values(row)[5], test_score_of_general_ability=table.row_values(row)[6], paper_score=table.row_values(row)[7], ) print(candidate) except Exception as e: print(e) 完美解决,能解决问题的代码就是好代码。 另外,编码解码的问题,还希望老师能解答下。
    展开

    作者回复: 参考课程的常见问题: https://www.ruoguedu.com/post/django-course-faq/

    
    
  • August
    2021-03-06
    为什么我无法使用自定义命令 Unknown command: 'import_candidates' Type 'manage.py help' for usage.

    作者回复: 检查下import candidates的脚本文件目录放对了没,可以加微信群聊,贴出来代码结构

    共 2 条评论
    
  • Stony.修行僧
    2020-10-31
    csv.reader(header=False)
    共 2 条评论
    10
  • 坐看云起时
    2021-04-11
    课程里面 csv 里面的第一行是 header,如果你打印出来,有可能会看到第一个显示的是 \ufeff,比如: ./manage.py import_candidates --path ./external_assets/candidates.csv ['\ufeff候选人姓名', '城市', '手机号码', '本科学校', '专业', '学历', '综合能力评测成绩', '笔试成绩'] \ufeff 是字节顺序标记, BOM(Bytes order mark),用于表示 UTF-16 编码的 大字节序或小字节序, 参见: https://stackoverflow.com/questions/17912307/u-ufeff-in-python-string 编码的区别比较繁琐,我就不在这里班门弄斧了,只是分享下我遇到的情况。 我遇到 \ufeff,在 open 的时候 使用 encoding='utf-8-sig' 就不会再打印出 \ufeff。
    共 2 条评论
    5
  • xd
    2021-08-06
    HR当然开心,导入数据的活交给了开发..
    
    4
  • 魁星
    2020-11-27
    方便一点的方式是直接按字典读入,然后通过字典解包传入参数 reader = csv.DictReader(f, delimiter=",") for row in reader: candidate = Candidate.objects.create(**row)
    共 2 条评论
    3