Django查询Category报DoesNotExist 如何为未分组数据创建分类
问题说明
为未分组的爬取职位数据匹配对应分类时触发报错,已确认报错直接原因是数据库中不存在title字段值为"Others"的Category表记录,且现有分类匹配逻辑对其他预设分类也存在同类风险——若Manager/Engineer/Architect任意一类分类记录不存在,同样会抛出匹配失败的异常。
报错堆栈
Traceback (most recent call last): File "C:\Users\MUHUMUZA IVAN\Desktop\JobPortal\test.py", line 128, in <module> the_category = Category.objects.get(title="Others") File "C:\Users\MUHUMUZA IVAN\AppData\Local\Programs\Python\Python310\lib\site-packages\django\db\models\manager.py", line 82, in manager_method return getattr(self.get_queryset(), name)(*args, **kwargs) File "C:\Users\MUHUMUZA IVAN\AppData\Local\Programs\Python\Python310\lib\site-packages\django\db\models\query.py", line 397, in get raise self.model.DoesNotExist( jobapp.models.Category.DoesNotExist: Category matching query does not exist.
原有业务实现代码
for test_job in final_jobs: if 'Manager' in test_job['title']: the_category = Category.objects.get(title='Manager') elif 'Engineer' in test_job['title']: the_category = Category.objects.get(title= 'Engineer') elif 'Architect' in test_job['title']: the_category = Category.objects.get(title='Architect') else: the_category = Category.objects.get(title="Others")
修复方案
两种方案可根据业务场景选择:
- 方案1:提前初始化全量预设分类
适合分类固定、不会动态增减的场景,提前把代码里用到的所有分类写入数据库,从根源避免找不到记录的问题。
执行python manage.py shell进入Django交互环境,运行以下代码完成分类初始化:
初始化完成后原有代码即可正常运行。from jobapp.models import Category preset_categories = ["Manager", "Engineer", "Architect", "Others"] for cat_title in preset_categories: # 已存在的分类不会重复创建 Category.objects.get_or_create(title=cat_title) - 方案2:改造分类匹配逻辑,自动创建缺失分类
鲁棒性更强,不需要提前手动初始化数据,匹配分类时如果对应记录不存在就自动创建,不会中断爬取数据的处理流程。改造后的代码如下:for test_job in final_jobs: if 'Manager' in test_job['title']: the_category, _ = Category.objects.get_or_create(title='Manager') elif 'Engineer' in test_job['title']: the_category, _ = Category.objects.get_or_create(title='Engineer') elif 'Architect' in test_job['title']: the_category, _ = Category.objects.get_or_create(title='Architect') else: the_category, _ = Category.objects.get_or_create(title="Others") # 后续关联the_category和当前test_job的逻辑保持不变即可
注意:Django的
get_or_create方法返回值为(模型实例, 是否新创建)的二元元组,赋值时需要取第一个元素作为分类实例使用。
内容的提问来源于stack exchange,提问作者Muhumuza
相关产品推荐
相关产品推荐

