1. 程式人生 > 程式設計 >Django 解決阿里雲部署同步資料庫報錯的問題

Django 解決阿里雲部署同步資料庫報錯的問題

寫在最前面:

在阿里雲租了一臺伺服器,搭建了一個部落格,採用的是Ubuntu+Django+uwsgi+nginx+mysql的結構。

運行了一段時間後,我發現我忘記了django自帶後臺的密碼!

然後很常規的修改密碼的操作,就是無法登陸!

然後想再建立一個超級使用者,登上去看看什麼情況,結果建立超級使用者又報錯?

可是本地環境是ok的,然後同步資料庫出錯。。。反正沒有對的。

然後同步資料庫報錯如下:

Django 解決阿里雲部署同步資料庫報錯的問題

手機端截的圖,查了一下報錯,應該是setting.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的過程。

補充知識:django2.0 foreignKey提示on_delete

據說在django2.0之前建立外來鍵foreignKey的引數on_delete是有預設值的,所以這個引數可以不用填,但在2.0之後on_delete沒有預設值了,所以這個引數一定要傳,不然就報以下的錯:

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(前提FK欄位需要設定為可空,一對一同理)

# models.ForeignKey('關聯表',on_delete=models.SET_DEFAULT,default='預設值')

on_delete=models.SET_DEFAULT,與之關聯的值設定為預設值(前提FK欄位需要設定預設值,一對一同理)

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",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='[email protected]',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,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,**kwargs):
  kwargs['unique'] = True
  super().__init__(to,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)這裡可以直接對第三張表直接操

方式二:自動建立關係表

class Host(models.Model):
 nid = models.AutoField(primary_key=True)
 hostname = models.CharField(max_length=32,to_field='id')
 # 10
class Application(models.Model):
 name = models.CharField(max_length=32)
 r = models.ManyToManyField("Host") --------------> appname_application_r 表名

無法直接對第三張表進行操作

只能間接操作————————————————————

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,4])
 
obj.r.remove(1)   刪
obj.r.remove(2,4)
obj.r.remove(*[1,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,symmetrical=None,through=None,through_fields=None,db_table=None,swappable=True,**kwargs):
  super().__init__(**kwargs)

以上這篇Django 解決阿里雲部署同步資料庫報錯的問題就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。