2011-11-08 70 views
7

我有一個數據庫視圖支持的模型。Django - 如何防止數據庫外鍵約束創建

class OrgCode(models.Model): 
    org_code    = models.CharField(db_column=u'code',max_length=15) 
    org_description   = models.CharField(max_length=250) 
    org_level_num   = models.IntegerField() 

    class Meta: 
     db_table = u'view_FSS_ORG_PROFILE' 

我需要另一個模型

class AssessmentLocation(models.Model): 
    name    = models.CharField(max_length=150) 
    org     = models.ForeignKey(OrgCode) 

我不能運行執行syncdb,因爲不能建立外鍵約束引用視圖引用此。

u"Foreign key 'FK__main_asse__org__1D114BD1' 
references object 'view_FSS_ORG_PROFILE' 
which is not a user table.", None, 0, -214 
7217900), None) 
Command: 
CREATE TABLE [main_assessmentlocation] (
    [id] int IDENTITY (1, 1) NOT NULL PRIMARY KEY, 
    [name] nvarchar(150) NOT NULL, 
    [org] int NOT NULL REFERENCES [view_FSS_ORG_PROFILE] ([id]), 
) 

解決方法是取出元:db_table指向視圖,讓同步數據庫創建的OrgCode表,然後把元:db_table回來後執行syncdb。

有沒有辦法阻止某些模型或字段的外鍵約束的創建?

更新:我添加了一個靜態方法相關的示範指示它是一個視圖

class OrgCode(models.Model): 
    org_code    = models.CharField(max_length=15) 
    org_description   = models.CharField(max_length=250) 

    @staticmethod 
    def is_backend_view(): 
     return True 

然後推翻在django_mssql creation.py DatabaseCreation.sql_for_inline_foreign_key_references:

def sql_for_inline_foreign_key_references(self, field, known_models, style): 
    try: 
     field.rel.to.is_backend_view() 
     return "", False 
    except: 
     return super(DatabaseCreation,self).sql_for_inline_foreign_key_references(field, known_models, style)  

從生成的SQL syncdb忽略了約束:

CREATE TABLE [main_assessmentlocation] (
    [id] int IDENTITY (1, 1) NOT NULL PRIMARY KEY, 
    [name] nvarchar(150) NOT NULL, 
    [org] int, -- NO FK CONSTRAINT ANYMORE -- 
); 

它涉及盜號django_mssql所以我會繼續努力,也許鉤住django.db.backends.signals.connection_created信號將工作...

回答

10

django開發版的db_constraint字段爲ForeignKey model field - docs

+0

謝謝!這就是我所需要的,現在我只需要等待它發佈,然後我就可以刪除我的黑客。 –

+1

從版本1.6開始,可以安全地使用db_constraint –

4

如果設置在模型中的managed=FalseDjango docsMeta類,當您運行syncdb時,Django不會創建表。

class AssessmentLocation(models.Model): 
    name = models.CharField(max_length=150) 
    org = models.ForeignKey(OrgCode) 

    class Meta: 
     managed = False 

Django有一個掛鉤provide initial sql data。我們可以(ab?)使用它來讓Django在運行syncdb後立即創建表。

創建一個文件myapp/sql/assessmentlocation.sql,包含創建表的語句:

CREATE TABLE [main_assessmentlocation] (
    [id] int IDENTITY (1, 1) NOT NULL PRIMARY KEY, 
    [name] nvarchar(150) NOT NULL, 
    [org] int, -- NO FK CONSTRAINT ANYMORE -- 
); 

如果您有其他型號外鍵的AssessmentLocation模型,你可能有問題,如果Django的嘗試執行之前應用外鍵約束自定義sql來創建表。否則,我認爲這種方法將起作用。

+0

謝謝!我看着這個,它確實有效。基於視圖的相關對象模型是我正在構建以供其他開發人員使用的框架的一部分。我試圖不要從syncdb模型創建和標準Django文檔中偏離。 –