Django2.1.3框架中(fields.E300)和(fields.E307)报错处理
使用Django框架创建了Web项目,修改了模型models.py之后,执行数据库迁移操作,出现如下报错:
models.py内容如下:
from django.db import models from django.contrib.auth.models import User # Create your models here. class Asset(models.Model): """所有资产的共有数据表""" assets_type_choice = ( ('Server', '服务器'), ('NetworkDevice', '网络设备'), ('StorageDevice', '存储设备'), ('SecurityDevice', '安全设备'), ('Software', '软件资产'), ) asset_status = ( (0, '在线'), (1, '下线'), (2, '未知'), (3, '故障'), (4, '备用'), ) asset_type = models.CharField(choices=assets_type_choice, max_length=64, default='Server', verbose_name='资产类型') name = models.CharField(max_length=64, unique=True, verbose_name='资产名称') # 不可重复 sn = models.CharField(max_length=128, unique=True, verbose_name='资产序列号') # 不可重复 business_unit = models.ForeignKey('BusinessUnit', null=True, blank=True, verbose_name='所属业务线', on_delete=models.CASCADE) status = models.CharField(choices=asset_status, max_length=64, default=0, verbose_name='设备状态') manufacturer = models.ForeignKey('Manufacturer', null=True, blank=True, verbose_name='设备制造商', on_delete=models.CASCADE) manage_ip = models.GenericIPAddressField(null=True, blank=True, verbose_name='管理IP') tags = models.ManyToManyField('Tag', blank=True, verbose_name='标签') admin = models.ForeignKey(User, null=True, blank=True, verbose_name='资产管理员', related_name='admin', on_delete=models.CASCADE) idc = models.ForeignKey('IDC', null=True, blank=True, verbose_name='所在数据中心', on_delete=models.CASCADE) contract = models.ForeignKey('Contract', null=True, blank=True, verbose_name='合同', on_delete=models.CASCADE) purchase_date = models.DateField(null=True, blank=True, verbose_name='购买日期') expire_date = models.DateField(null=True, blank=True, verbose_name='过保日期') price = models.FloatField(null=True, blank=True, verbose_name='价格') approved_by = models.ForeignKey(User, null=True, blank=True, verbose_name='批准人', related_name='approved_by', on_delete=models.CASCADE) memo = models.TextField(null=True, blank=True, verbose_name='备注') c_time = models.DateTimeField(auto_now_add=True, verbose_name='批准日期') m_time = models.DateTimeField(auto_now=True, verbose_name='更新日期') def __str__(self): return '<%s> %s' % (self.get_asset_type_display(), self.name) class Meta: verbose_name = '资产总表' verbose_name_plural = verbose_name ordering = ['-c_time'] class Server(models.Model): """服务器设备""" sub_asset_type_choice = ( (0, 'PC服务器'), (1, '刀片机'), (2, '小型机'), ) created_by_choice = ( ('auto', '自动添加'), ('manual', '手工录入'), ) asset = models.OneToOneField('Asset', on_delete=models.CASCADE) # 非常关键的一对一关联! sub_asset_type = models.SmallIntegerField(choices=sub_asset_type_choice, default=0, verbose_name="服务器类型") created_by = models.CharField(choices=created_by_choice, max_length=32, default='auto', verbose_name="添加方式") hosted_on = models.ForeignKey('self', related_name='hosted_on_server', blank=True, null=True, verbose_name="宿主机", on_delete=models.CASCADE) # 虚拟机专用字段 model = models.CharField(max_length=128, null=True, blank=True, verbose_name='服务器型号') raid_type = models.CharField(max_length=512, blank=True, null=True, verbose_name='Raid类型') os_type = models.CharField('操作系统类型', max_length=64, blank=True, null=True) os_distribution = models.CharField('发行版本', max_length=64, blank=True, null=True) os_release = models.CharField('操作系统版本', max_length=64, blank=True, null=True) def __str__(self): return '%s--%s--%s <sn:%s>' % (self.asset.name, self.get_sub_asset_type_display(), self.model, self.asset.sn) class Meta: verbose_name = '服务器' verbose_name_plural = "服务器" class SecurityDevice(models.Model): """安全设备""" sub_asset_type_choice = ( (0, '防火墙'), (1, '入侵检测设备'), (2, '互联网网关'), (4, '运维审计系统'), ) asset = models.OneToOneField('Asset', on_delete=models.CASCADE) sub_asset_type = models.SmallIntegerField(choices=sub_asset_type_choice, default=0, verbose_name="安全设备类型") def __str__(self): return self.asset.name + "--" + self.get_sub_asset_type_display() + " id:%s" % self.id class Meta: verbose_name = '安全设备' verbose_name_plural = "安全设备" class StorageDevice(models.Model): """存储设备""" sub_asset_type_choice = ( (0, '磁盘阵列'), (1, '网络存储器'), (2, '磁带库'), (4, '磁带机'), ) asset = models.OneToOneField('Asset', on_delete=models.CASCADE) sub_asset_type = models.SmallIntegerField(choices=sub_asset_type_choice, default=0, verbose_name="存储设备类型") def __str__(self): return self.asset.name + "--" + self.get_sub_asset_type_display() + " id:%s" % self.id class Meta: verbose_name = '存储设备' verbose_name_plural = "存储设备" class NetworkDevice(models.Model): """网络设备""" sub_asset_type_choice = ( (0, '路由器'), (1, '交换机'), (2, '负载均衡'), (4, 'VPN设备'), ) asset = models.OneToOneField('Asset', on_delete=models.CASCADE) sub_asset_type = models.SmallIntegerField(choices=sub_asset_type_choice, default=0, verbose_name="网络设备类型") vlan_ip = models.GenericIPAddressField(blank=True, null=True, verbose_name="VLanIP") intranet_ip = models.GenericIPAddressField(blank=True, null=True, verbose_name="内网IP") model = models.CharField(max_length=128, null=True, blank=True, verbose_name="网络设备型号") firmware = models.CharField(max_length=128, blank=True, null=True, verbose_name="设备固件版本") port_num = models.SmallIntegerField(null=True, blank=True, verbose_name="端口个数") device_detail = models.TextField(null=True, blank=True, verbose_name="详细配置") def __str__(self): return '%s--%s--%s <sn:%s>' % (self.asset.name, self.get_sub_asset_type_display(), self.model, self.asset.sn) class Meta: verbose_name = '网络设备' verbose_name_plural = "网络设备" class Software(models.Model): """ 只保存付费购买的软件 """ sub_asset_type_choice = ( (0, '操作系统'), (1, '办公\开发软件'), (2, '业务软件'), ) sub_asset_type = models.SmallIntegerField(choices=sub_asset_type_choice, default=0, verbose_name="软件类型") license_num = models.IntegerField(default=1, verbose_name="授权数量") version = models.CharField(max_length=64, unique=True, help_text='例如: CentOS release 6.7 (Final)', verbose_name='软件/系统版本') def __str__(self): return '%s--%s' % (self.get_sub_asset_type_display(), self.version) class Meta: verbose_name = '软件/系统' verbose_name_plural = "软件/系统" class IDC(models.Model): """机房""" name = models.CharField(max_length=64, unique=True, verbose_name="机房名称") memo = models.CharField(max_length=128, blank=True, null=True, verbose_name='备注') def __str__(self): return self.name class Meta: verbose_name = '机房' verbose_name_plural = "机房" class Manufacturer(models.Model): """厂商""" name = models.CharField('厂商名称', max_length=64, unique=True) telephone = models.CharField('支持电话', max_length=30, blank=True, null=True) memo = models.CharField('备注', max_length=128, blank=True, null=True) def __str__(self): return self.name class Meta: verbose_name = '厂商' verbose_name_plural = "厂商" class BusinessUnit(models.Model): """业务线""" parent_unit = models.ForeignKey('self', blank=True, null=True, related_name='parent_level', on_delete=models.CASCADE) name = models.CharField('业务线', max_length=64, unique=True) memo = models.CharField('备注', max_length=64, blank=True, null=True) def __str__(self): return self.name class Meta: verbose_name = '业务线' verbose_name_plural = "业务线" class Contract(models.Model): """合同""" sn = models.CharField('合同号', max_length=128, unique=True) name = models.CharField('合同名称', max_length=64) memo = models.TextField('备注', blank=True, null=True) price = models.IntegerField('合同金额') detail = models.TextField('合同详细', blank=True, null=True) start_day = models.DateField('开始日期', blank=True, null=True) end_day = models.DateField('失效日期', blank=True, null=True) license_num = models.IntegerField('license数量', blank=True, null=True) c_day = models.DateField('创建日期', auto_now_add=True) m_day = models.DateField('修改日期', auto_now=True) def __str__(self): return self.name class Meta: verbose_name = '合同' verbose_name_plural = "合同" class Tag(models.Model): """标签""" name = models.CharField('标签名', max_length=32, unique=True) c_day = models.DateField('创建日期', auto_now_add=True) def __str__(self): return self.name class Meta: verbose_name = '标签' verbose_name_plural = "标签" class Disk(models.Model): """存储设备""" disk_interface_type_choice = ( ('SATA', 'SATA'), ('SAS', 'SAS'), ('SCSI', 'SCSI'), ('SSD', 'SSD'), ('unknown', 'unknown'), ) asset = models.ForeignKey('Asset', on_delete=models.CASCADE) sn = models.CharField('硬盘SN号', max_length=128) slot = models.CharField('所在插槽位', max_length=64, blank=True, null=True) model = models.CharField('磁盘型号', max_length=128, blank=True, null=True) manufacturer = models.CharField('磁盘制造商', max_length=128, blank=True, null=True) capacity = models.FloatField('磁盘容量(GB)', blank=True, null=True) interface_type = models.CharField('接口类型', max_length=16, choices=disk_interface_type_choice, default='unknown') def __str__(self): return '%s: %s: %s: %sGB' % (self.asset.name, self.model, self.slot, self.capacity) class Meta: verbose_name = '硬盘' verbose_name_plural = "硬盘" unique_together = ('asset', 'sn') class EventLog(models.Model): """ 日志. 在关联对象被删除的时候,不能一并删除,需保留日志。 因此,on_delete=models.SET_NULL """ name = models.CharField('事件名称', max_length=128) event_type_choice = ( (0, '其它'), (1, '硬件变更'), (2, '新增配件'), (3, '设备下线'), (4, '设备上线'), (5, '定期维护'), (6, '业务上线\更新\变更'), ) asset = models.ForeignKey('Asset', blank=True, null=True, on_delete=models.SET_NULL) # 当资产审批成功时有这项数据 new_asset = models.ForeignKey('NewAssetApprovalZone', blank=True, null=True, on_delete=models.SET_NULL) # 当资产审批失败时有这项数据 event_type = models.SmallIntegerField('事件类型', choices=event_type_choice, default=4) component = models.CharField('事件子项', max_length=256, blank=True, null=True) detail = models.TextField('事件详情') date = models.DateTimeField('事件时间', auto_now_add=True) user = models.ForeignKey(User, blank=True, null=True, verbose_name='事件执行人', on_delete=models.SET_NULL) # 自动更新资产数据时没有执行人 memo = models.TextField('备注', blank=True, null=True) def __str__(self): return self.name class Meta: verbose_name = '事件纪录' verbose_name_plural = "事件纪录" class NewAssetApprovalZone(models.Model): """新资产待审批区""" sn = models.CharField('资产SN号', max_length=128, unique=True) # 此字段必填 asset_type_choice = ( ('server', '服务器'), ('networkdevice', '网络设备'), ('storagedevice', '存储设备'), ('securitydevice', '安全设备'), ('IDC', '机房'), ('software', '软件资产'), ) asset_type = models.CharField(choices=asset_type_choice, default='server', max_length=64, blank=True, null=True, verbose_name='资产类型') manufacturer = models.CharField(max_length=64, blank=True, null=True, verbose_name='生产厂商') model = models.CharField(max_length=128, blank=True, null=True, verbose_name='型号') ram_size = models.PositiveIntegerField(blank=True, null=True, verbose_name='内存大小') cpu_model = models.CharField(max_length=128, blank=True, null=True, verbose_name='CPU型号') cpu_count = models.PositiveSmallIntegerField(blank=True, null=True) cpu_core_count = models.PositiveSmallIntegerField(blank=True, null=True) os_distribution = models.CharField(max_length=64, blank=True, null=True) os_type = models.CharField(max_length=64, blank=True, null=True) os_release = models.CharField(max_length=64, blank=True, null=True) data = models.TextField('资产数据') # 此字段必填 c_time = models.DateTimeField('汇报日期', auto_now_add=True) m_time = models.DateTimeField('数据更新日期', auto_now=True) approved = models.BooleanField('是否批准', default=False) def __str__(self): return self.sn class Meta: verbose_name = '新上线待批准资产' verbose_name_plural = "新上线待批准资产" ordering = ['-c_time']
报错信息如下:
Django报错处理: SystemCheckError: System check identified some issues: ERRORS: assets.Asset.admin: (fields.E300) Field defines a relation with model 'User', which is either not installed, or is abstract. assets.Asset.admin: (fields.E307) The field assets.Asset.admin was declared with a lazy reference to 'assets.user', but app 'assets' doesn't provide model 'user'. assets.Asset.approved_by: (fields.E300) Field defines a relation with model 'User', which is either not installed, or is abstract. assets.Asset.approved_by: (fields.E307) The field assets.Asset.approved_by was declared with a lazy reference to 'assets.user', but app 'assets' doesn't provide model 'user'. assets.EventLog.user: (fields.E300) Field defines a relation with model 'User', which is either not installed, or is abstract. assets.EventLog.user: (fields.E307) The field assets.EventLog.user was declared with a lazy reference to 'assets.user', but app 'assets' doesn't provide model 'user'.
解决方案:
1、在settings.py中添加如下配置:
SILENCED_SYSTEM_CHECKS = ['fields.E300', 'fields.E307']
2、将models.py文件中的'User'去掉双引号,改为User,具体见下图所示:
3、再次执行数据库迁移操作:
python manage.py makemigrations
python manage.py migrate
4、数据库表完成创建,日志如下:
“终身”学习,生活充满诗意!