2011-11-08 39 views
7

Tôi có một mô hình được hỗ trợ bởi chế độ xem cơ sở dữ liệu.Django - Cách ngăn chặn việc tạo ràng buộc khóa ngoại vi cơ sở dữ liệu

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' 

Tôi cần phải tham khảo này trong một mô hình

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

tôi không thể chạy syncdb vì ràng buộc khoá ngoại không thể được tạo ra tham khảo một cái nhìn.

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]), 
) 

Cách giải quyết là để đưa ra các Meta: trỏ db_table đến xem và để db đồng bộ tạo ra các bàn OrgCode, sau đó đặt Meta: db_table trở lại sau khi syncdb.

Có cách nào để ngăn chặn việc tạo ra các ràng buộc khóa ngoại cho một số trường hoặc mô hình nhất định không?

Cập nhật: Tôi đã thêm một phương pháp tĩnh để mô hình có liên quan cho thấy đó là một cái nhìn

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 

Sau đó overrode DatabaseCreation.sql_for_inline_foreign_key_references trong creation.py django_mssql:

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)  

Các sql tạo ra từ syncdb loại bỏ ràng buộc:

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

Nó liên quan đến hack django_mssql vì vậy tôi sẽ tiếp tục cố gắng, có lẽ hooking vào tín hiệu django.db.backends.signals.connection_created sẽ làm việc ...

Trả lời

10

Phiên bản phát triển django có trường db_constraint cho trường mô hình ForeignKey - docs.

+0

Cảm ơn! Đó là những gì tôi cần, bây giờ tôi sẽ chỉ phải chờ cho đến khi nó được phát hành và tôi có thể gỡ bỏ hack của mình. –

+1

'db_constraint' có thể được sử dụng an toàn kể từ phiên bản 1.6 –

4

Nếu bạn đặt managed=False (Django docs) trong mô hình của bạn Meta lớp, Django sẽ không tạo bảng khi bạn chạy syncdb.

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

    class Meta: 
     managed = False 

Django có móc đến provide initial sql data. Chúng tôi có thể (ab?) Sử dụng điều này để có được Django để tạo ra bảng ngay lập tức sau khi chạy syncdb.

Tạo một file myapp/sql/assessmentlocation.sql, có chứa các bảng báo cáo tạo:

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

Nếu bạn có các mô hình khác với các phím nước ngoài cho mô hình AssessmentLocation, bạn có thể có vấn đề nếu Django cố gắng áp dụng các ràng buộc khoá ngoại trước khi thực hiện sql tùy chỉnh để tạo bảng. Nếu không, tôi nghĩ phương pháp này sẽ hiệu quả.

+0

Cảm ơn! Tôi nhìn vào nó và nó hoạt động. Mô hình đối tượng liên quan dựa trên khung nhìn là một phần của một khung mà tôi đang xây dựng để các nhà phát triển khác sử dụng. Tôi đang cố gắng không đi lạc từ việc tạo mô hình syncdb và tài liệu chuẩn django. –

Các vấn đề liên quan