Django 2.0执行makemigrations报错:目标新增字段不存在
解决Django添加字段时makemigrations报错的最优方案
嘿,我完全懂你这个头疼的问题!之前我也踩过一模一样的坑——每次加新字段跑makemigrations就报字段不存在,注释代码虽然能临时解决,但太麻烦了。咱们来彻底搞定它:
问题根源拆解
你遇到的错误本质是:Django在执行makemigrations时会加载项目的URL配置,进而导入视图模块。而你的MarcaList类在定义阶段(也就是模块被导入的时候)就直接遍历了Marca模型的所有对象,这会触发数据库查询,但此时你要加的eh_maiores_bancos字段还没被迁移到数据库里,自然会报“字段不存在”的错误。
最优解决方案:把查询逻辑移到请求处理阶段
核心思路就是:类定义阶段只做配置,不要执行任何数据库操作,把需要遍历模型对象的逻辑移到类的方法内部,只有当真正有请求进来时才执行查询。
举个例子,假设你原来的代码是这样的(类定义时直接查库):
class MarcaList(generics.ListCreateAPIView): # 错误写法:类定义阶段就执行查询 marcas = Marca.objects.all() for m in marcas: # 比如动态生成某些配置、处理字段之类的逻辑 pass
把它改成这样,把逻辑移到list方法里(只有请求触发时才运行):
class MarcaList(generics.ListCreateAPIView): queryset = Marca.objects.all() serializer_class = MarcaSerializer def list(self, request, *args, **kwargs): # 在这里执行遍历逻辑,只有请求到来时才会触发数据库查询 marcas = self.get_queryset() for m in marcas: # 你的处理逻辑,比如字段处理、配置生成等 pass # 调用父类的list方法完成正常的响应流程 return super().list(request, *args, **kwargs)
如果你的遍历是为了动态生成序列化器字段,或者其他初始化逻辑,可以用延迟加载的属性来实现:
class MarcaList(generics.ListCreateAPIView): queryset = Marca.objects.all() @property def processed_marcas(self): # 这个属性只有在被访问时才会执行数据库查询 marcas = self.get_queryset() processed_data = [] for m in marcas: # 你的处理逻辑 processed_data.append(m) return processed_data # 在需要用到的地方调用self.processed_marcas即可
为什么这个方案比注释代码好?
注释代码再跑迁移确实能临时解决问题,但每次修改模型字段都要重复“注释→迁移→取消注释”的流程,不仅麻烦还容易出错。而把查询逻辑移到请求处理阶段,完全符合Django的生命周期设计——类定义只做配置,数据库操作留到请求处理时执行,从根本上避免了迁移时的冲突。
另外,如果你项目里还有其他模块顶层的数据库查询(比如全局变量里直接写Model.objects.all()),也建议一并调整到函数/方法内部,避免类似的问题。
内容的提问来源于stack exchange,提问作者Lucca Augusto
相关产品推荐
相关产品推荐

