2009-02-03 35 views
55

Tôi muốn sử dụng chế độ xem tôi đã tạo trong cơ sở dữ liệu của mình làm nguồn cho chế độ xem django của tôi.Tôi có thể sử dụng chế độ xem cơ sở dữ liệu làm mô hình ở Django không?

Điều này có thể, không sử dụng sql tùy chỉnh không?

****** 13/02/09 CẬP NHẬT ***********

Giống như nhiều các câu trả lời gợi ý, bạn có thể chỉ cần thực hiện quan điểm riêng của bạn trong cơ sở dữ liệu và sau đó sử dụng nó trong API bằng cách định nghĩa nó trong models.py.

một số cảnh báo mặc dù:

  • syncdb manage.py sẽ không hoạt động nữa
  • quan điểm cần điều tương tự vào đầu tên của nó như tất cả các mô hình khác (bảng) ví dụ: nếu ứng dụng của bạn được gọi là "điều" thì chế độ xem của bạn sẽ cần phải được gọi là thing_ $ viewname
+0

Để lệnh syncdb hoạt động, không đặt lớp mô hình của bạn cho chế độ xem trong models.py mà là một tệp riêng biệt! –

+2

Tốt hơn: xem câu trả lời bên dưới về managed = False trong lớp Meta trên mô hình của bạn. –

+3

Chế độ xem không cần phải có cùng tên với ứng dụng. Chỉ cần sử dụng trường Meta db_table. Ví dụ, chế độ xem có tên là its_a_View. lớp Meta: db_table = u'its_a_view ' – grantk

Trả lời

33

Kể từ Django 1.1, bạn có thể sử dụng Options.managed cho điều đó.

Đối với các phiên bản cũ hơn, bạn có thể dễ dàng xác định lớp Mô hình cho chế độ xem và sử dụng nó như các chế độ xem khác của bạn. Tôi chỉ thử nghiệm nó bằng cách sử dụng một ứng dụng dựa trên Sqlite và nó có vẻ hoạt động tốt. Chỉ cần đảm bảo thêm trường khóa chính nếu cột "khóa chính" của chế độ xem của bạn không được đặt tên là 'id' và chỉ định tên của chế độ xem trong tùy chọn Meta nếu chế độ xem của bạn không được gọi là 'app_classname'.

Vấn đề duy nhất là lệnh "syncdb" sẽ tăng ngoại lệ vì Django sẽ cố gắng tạo bảng. Bạn có thể ngăn chặn điều đó bằng cách xác định 'mô hình xem' trong một tệp Python riêng biệt, khác với models.py. Bằng cách này, Django sẽ không nhìn thấy chúng khi nhìn vào models.py để xác định các mô hình để tạo ra cho ứng dụng và do đó sẽ không cố gắng để tạo ra bảng.

+0

Bất kỳ ý tưởng làm thế nào nó sẽ xử lý gọi phương thức lưu trên đó? Một số dbms có lượt xem có thể cập nhật. –

+0

Tôi không chắc chắn. Rất có thể là Django chỉ đơn giản là cố gắng chạy một truy vấn INSERT hoặc UPDATE trên xem, nhưng tôi không có quá nhiều cái nhìn sâu sắc trong mã nguồn Django :-) –

+13

* Sigh *. ** Không cần downvotes, folks! ** Đây là một câu trả lời cổ xưa cho một câu hỏi cổ xưa. Vào tháng 2 năm 2009, không có 'Options.managed', xuất hiện trong Django 1.1 vào ngày 29 tháng 7 năm 2009 ... –

3

Chúng tôi đã thực hiện điều này khá rộng rãi trong các ứng dụng của chúng tôi với MySQL để làm việc xung quanh giới hạn cơ sở dữ liệu duy nhất của Django. Ứng dụng của chúng tôi có một vài cơ sở dữ liệu sống trong một cá thể MySQL duy nhất. Chúng ta có thể đạt được mô hình cơ sở dữ liệu chéo tham gia theo cách này miễn là chúng ta đã tạo ra các khung nhìn cho mỗi bảng trong cơ sở dữ liệu "hiện tại".

Theo như chèn/cập nhật vào lượt xem, với các trường hợp sử dụng của chúng tôi, chế độ xem về cơ bản là "chọn * từ [db.table];". Nói cách khác, chúng tôi không thực hiện bất kỳ phép nối phức tạp hoặc lọc nào để chèn/cập nhật kích hoạt từ save() hoạt động tốt. Nếu trường hợp sử dụng của bạn yêu cầu tham gia phức tạp như vậy hoặc lọc rộng, tôi nghi ngờ bạn sẽ không gặp bất kỳ sự cố nào đối với các trường hợp chỉ đọc, nhưng có thể gặp phải sự cố chèn/cập nhật. Tôi nghĩ rằng có một số ràng buộc cơ bản trong MySQL ngăn cản bạn cập nhật thành các chế độ xem chéo bảng, có các bộ lọc phức tạp, v.v.

Dù sao, số dặm của bạn có thể thay đổi nếu bạn đang sử dụng RDBMS ngoài MySQL, nhưng Django doesn ' t thực sự quan tâm nếu nó ngồi trên đầu trang của một bảng vật lý hoặc xem. Nó sẽ là RDBMS xác định xem nó có thực sự hoạt động như bạn mong đợi hay không. Như một người bình luận trước đó đã lưu ý, bạn có thể sẽ ném syncdb ra ngoài cửa sổ, mặc dù chúng ta đã làm việc thành công xung quanh nó với một tín hiệu post-syncdb thả bảng vật lý do Django tạo ra và chạy lệnh "create view ..." của chúng ta. Tuy nhiên, tín hiệu post-syncdb là một chút bí truyền theo cách nó được kích hoạt, vì vậy hãy báo trước emptor ở đó.

EDIT: Tất nhiên bởi "tín hiệu sau syncdb" Ý tôi là "hậu syncdb nghe"

90

Chỉ cần một bản cập nhật cho những người sẽ gặp phải câu hỏi này (từ Google hoặc bất cứ điều gì khác) ...

Hiện nay Django có một "cách thích hợp" đơn giản để define model without managing database tables:

Options.managed

Defaults để True, có nghĩa là Django sẽ tạo ra các bảng cơ sở dữ liệu thích hợp trong syncdb và loại bỏ chúng như một phần của một lệnh quản lý reset. Tức là, Django quản lý vòng đời của bảng cơ sở dữ liệu.

Nếu False, sẽ không có hoạt động tạo hoặc xóa bảng cơ sở dữ liệu nào được thực hiện cho mô hình này. Điều này rất hữu ích nếu mô hình đại diện cho một bảng hiện có hoặc một khung nhìn cơ sở dữ liệu đã được tạo ra bởi một số phương tiện khác. Đây là số chỉ có khác biệt khi managedFalse. Tất cả các khía cạnh khác của việc xử lý mô hình đều giống hệt như bình thường.

+2

Để cung cấp một số ngữ cảnh; tính năng này có sẵn ở Django 1.1 trở lên. – spence91

+1

Hãy nhớ rằng bạn sẽ chạy vào TransactionErrors khi cố gắng xóa các đối tượng được tham chiếu bởi các đối tượng trong khung nhìn cơ sở dữ liệu của bạn bằng 'models.ForeignKey'. – jnns

+0

Nếu bạn đang sử dụng Django 1.3+ thì bạn có thể tránh TransactionErrors bằng cách sử dụng [ForeignKey.on_delete] (https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ForeignKey. on_delete): 'user = models.ForeignKey (Người dùng, on_delete = models.DO_NOTHING)' – rhunwicks

2

Từ Django Official Documentation, bạn có thể gọi quan điểm như thế này:

#import library 
from django.db import connection 

#Create the cursor 
cursor = connection.cursor() 

#Write the SQL code 
sql_string = 'SELECT * FROM myview' 

#Execute the SQL 
cursor.execute(sql_string) 
result = cursor.fetchall() 

Hy vọng nó giúp ;-)

9

tôi chỉ thực hiện một mô hình sử dụng một cái nhìn với postgres 9.4 và django 1.8.

Tôi tạo ra các lớp học di chuyển tùy chỉnh như thế này:

# -*- coding: utf-8 -*- 
from __future__ import unicode_literals 

from django.db import migrations 


class Migration(migrations.Migration): 

    dependencies = [ 
     ('myapp', '0002_previousdependency'), 
    ] 

    sql = """ 
    create VIEW myapp_myview as 
    select your view here 
    """ 

    operations = [ 
     migrations.RunSQL("drop view if exists myapp_myview;"), 
     migrations.RunSQL(sql) 
    ] 

tôi đã viết các mô hình như tôi bình thường. Nó hoạt động cho mục đích của tôi.

Lưu ý - Khi tôi chạy quảng cáo, một tệp di chuyển mới đã được tạo cho mô hình mà tôi đã xóa theo cách thủ công.

Công bố đầy đủ - chế độ xem của tôi chỉ được đọc vì tôi đang sử dụng chế độ xem có nguồn gốc từ loại dữ liệu jsonb và chưa viết quy tắc BẬT UPDATE.

+0

thông tin bổ sung tuyệt vời, thực sự hữu ích, cảm ơn –

+0

Nếu bạn không muốn cài đặt 'sqlparse', bạn có thể đưa đối số vào 'RunSQL' trong '[]'. – Dan

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