Django部署阿里云同步数据库报错及ForeignKey参数详解

巷口听风
巷口听风
发布时间:2026-10-13| 5人浏览过
原创

本文记录在阿里云Ubuntu环境下部署Django博客时遇到的数据库同步报错及超级用户创建失败问题。通过修正STATIC_ROOT路径配置解决同步错误,并发现后台账号权限关闭导致无法登录。此外,详细解析Django 2.0+中ForeignKey的on_delete参数(CASCADE、PROTECT、SET_NULL等)及其在一对多、一对一和多对多关系中的具体应用与代码示例。

阿里云Django部署数据库同步报错排查

前言说明:

在阿里云服务器搭建博客系统,技术栈采用Ubuntu操作系统、Django框架、uWSGI应用服务器、Nginx反向代理以及MySQL数据库。

系统运行一段时间后,发现忘记了Django自带后台管理系统的登录密码。

尝试执行常规的密码修改操作,但始终无法成功登录后台。

随后尝试创建新的超级用户以排查情况,却遭遇创建报错。

本地开发环境运行正常,但生产环境同步数据库时出现错误,导致整体流程受阻。

同步数据库时的具体报错信息如下所示:

上述报错截图经查询分析,推测为settings.py配置文件存在问题,因此将生产环境的代码下载下来进行排查。

具体配置代码如下:


STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATICFILES_DIRS = (
 os.path.join(BASE_DIR, 'static'),
 #os.path.join(os.path.dirname(__file__), '../static/').replace('\\', '/'),
)

需要注意的是,STATIC_ROOT与STATICFILES_DIRS这两个配置项只需保留其中一个即可生效。

若必须同时配置两者,

请确保

STATIC_ROOT = os.path.join(BASE_DIR, 'static')

修改为

STATIC_ROOT = os.path.join(BASE_DIR, '/static/')

完成上述修改后,再次执行数据库同步操作。

此时,创建超级用户的操作也已恢复正常。

登录Admin后台后发现,原账号的权限已被关闭,这解释了为何之前修改密码无效。

后续将详细整理在阿里云部署Django的完整过程。

Django ForeignKey on_delete参数详解

补充知识:Django 2.0中ForeignKey关于on_delete参数的提示。

在Django 2.0版本之前,创建外键(ForeignKey)时on_delete参数存在默认值,因此可以省略不写。但在2.0及之后的版本中,该参数不再提供默认值,必须显式传入,否则将触发以下错误:

TypeError: __init__() missing 1 required positional argument: on_delete

接下来详细说明on_delete参数各选项的具体含义。

on_delete=None, # 删除关联表中的数据时,当前表与其关联的field的行为(注:此选项通常不推荐,具体行为依赖数据库约束)

on_delete=models.CASCADE, # 删除关联数据时,当前表中与之关联的数据也会被级联删除

on_delete=models.DO_NOTHING, # 删除关联数据时,不做任何操作(需依赖数据库外键约束处理)

on_delete=models.PROTECT, # 删除关联数据时,若存在关联记录则引发ProtectedError错误

# models.ForeignKey('关联表', on_delete=models.SET_NULL, blank=True, null=True)

on_delete=models.SET_NULL, # 删除关联数据时,将当前表中关联字段的值设置为null(前提是该字段允许为NULL,一对一关系同理)

# models.ForeignKey('关联表', on_delete=models.SET_DEFAULT, default='默认值')

on_delete=models.SET_DEFAULT, # 删除关联数据时,将当前表中关联字段的值设置为默认值(前提是该字段设置了默认值,一对一关系同理)

on_delete=models.SET, # 删除关联数据时,

a. 将关联字段的值设置为指定值,设置方式:models.SET(值)

b. 将关联字段的值设置为可执行对象的返回值,设置方式:models.SET(可执行对象)

外键关系创建与代码示例

示例:创建一对多外键关系。


class UserType(models.Model):
 caption = models.CharField(max_length=32)
 
class UserInfo(models.Model):
 user = models.CharField(max_length=32)
 email = models.EmailField()
 user_type = models.ForeignKey(to="UserType",to_field="id",on_delete=models.CASCADE)

定义外键后,使用models.xxxx.objects.create()创建数据时,外键字段的值需要传入关联表的对象实例,如下所示:


class UserType(models.Model):
 caption = models.CharField(max_length=32)
 
class UserInfo(models.Model):
 user = models.CharField(verbose_name='用户', max_length=32)
 email = models.EmailField()
 user_type = models.ForeignKey(to="UserType",to_field="id",on_delete=models.CASCADE)
-----------上面是的是在models.py,下面的是在views.py-------------
def test(requset):
 ut = models.UserType.objects.filter(id=1).first()
 #print(ut)
 models.UserInfo.objects.create(user='小明',email='abc@163.com',user_type=ut)
 return HttpResponse('ok')

一对多关系的继承代码示例:


class ForeignKey(ForeignObject):
 def __init__(self, to, on_delete, related_name=None, related_query_name=None,
 limit_choices_to=None, parent_link=False, to_field=None,
 db_constraint=True, **kwargs):
  super().__init__(to, on_delete, from_fields=['self'], to_fields=[to_field], **kwargs)

创建一对一关系。


OneToOneField(ForeignKey)
  to,   # 要进行关联的表名
  to_field=None    # 要关联的表中的字段名称
  on_delete=None,    # 当删除关联表中的数据时,当前表与其关联的行的行为
 
 ###### 对于一对一 ######
 # 1. 一对一其实就是 一对多 + 唯一索引
 # 2.当两个类之间有继承关系时,默认会创建一个一对一字段
 # 如下会在A表中额外增加一个c_ptr_id列且唯一:
class C(models.Model):
nid = models.AutoField(primary_key=True)
part = models.CharField(max_length=12)
 
class A(C):
id = models.AutoField(primary_key=True)
code = models.CharField(max_length=1)

一对一关系的继承代码示例:


class OneToOneField(ForeignKey):
 def __init__(self, to, on_delete, to_field=None, **kwargs):
  kwargs['unique'] = True
  super().__init__(to, on_delete, to_field=to_field, **kwargs)

多对多关系处理与前端展示

创建多对多关系。

方式一:通过自定义中间表建立关系。


class Host(models.Model):
 nid = models.AutoField(primary_key=True)
 hostname = models.CharField(max_length=32,db_index=True)
 ip = models.GenericIPAddressField(protocol="ipv4",db_index=True)
 port = models.IntegerField()
 b = models.ForeignKey(to="Business", to_field='id')
 # 10
class Application(models.Model):
 name = models.CharField(max_length=32)
 # 2
 
class HostToApp(models.Model):
 hobj = models.ForeignKey(to='Host',to_field='nid')
 aobj = models.ForeignKey(to='Application',to_field='id')
 
 
# HostToApp.objects.create(hobj_id=1,aobj_id=2)这里可以直接对第三张表直接操

方式二:利用Django自动创建关系表。


class Host(models.Model):
 nid = models.AutoField(primary_key=True)
 hostname = models.CharField(max_length=32,db_index=True)
 ip = models.GenericIPAddressField(protocol="ipv4",db_index=True)
 port = models.IntegerField()
 b = models.ForeignKey(to="Business", to_field='id')
 # 10
class Application(models.Model):
 name = models.CharField(max_length=32)
 r = models.ManyToManyField("Host") --------------> appname_application_r 表名

无法直接对第三张关系表进行常规ORM操作。

只能通过关联对象间接操作————————————————————


obj = models.Application.objects.get(id=1)
obj.name
 
# 第三张表操作:HostToApp table   基于id=1的Application添加对应关系
obj.r.add(1)增
obj.r.add(2)
obj.r.add(2,3,4)
obj.r.add(*[1,2,3,4])
 
obj.r.remove(1)   删
obj.r.remove(2,4)
obj.r.remove(*[1,2,3])
 
obj.r.clear() 清除app_id =1 的列
 
obj.r.set([3,5,7])   改set将原来数据库中的关系先全部删除,在添加1-3,1-5,1-7
——————————————————————————
# 所有相关的主机对象“列表” QuerySet
obj.r.all()   obj.filter() obj.first()

前端模板获取数据。


  {%for app in app_list%}
  <tr>
 <td>{{app.name}}</td>
 <td>{{app.r.all}}</td>
   </tr>
  {%endfor%}

多对多关系的继承代码示例:


class ManyToManyField(RelatedField):
 def __init__(self, to, related_name=None, related_query_name=None,
 limit_choices_to=None, symmetrical=None, through=None,
 through_fields=None, db_constraint=True, db_table=None,
 swappable=True, **kwargs):
  super().__init__(**kwargs)

以上关于Django解决阿里云部署同步数据库报错及ForeignKey参数用法的分享到此结束,希望能对读者有所帮助,欢迎支持。

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。