2009-07-21 32 views
80

Chỉ đường từ người giám sát của tôi: "Tôi muốn tránh đặt bất kỳ lôgic nào trong models.py. Từ đây, hãy sử dụng lớp đó để truy cập cơ sở dữ liệu và giữ tất cả logic trong các lớp bên ngoài sử dụng các lớp mô hình hoặc quấn chúng lại. "models.py trở nên to lớn, cách tốt nhất để phá vỡ nó là gì?

Tôi cảm thấy như đây là cách đi sai. Tôi cảm thấy rằng giữ logic ra khỏi các mô hình chỉ để giữ cho các tập tin nhỏ là một ý tưởng tồi. Nếu logic là tốt nhất trong mô hình, đó là nơi nó thực sự nên đi bất kể kích thước tập tin.

Vì vậy, có cách đơn giản để sử dụng bao gồm? Trong PHP-nói, tôi muốn đề xuất với người giám sát rằng chúng tôi chỉ có models.py bao gồm() các lớp mô hình từ những nơi khác. Về mặt khái niệm, điều này sẽ cho phép các mô hình có tất cả logic mà chúng ta muốn, nhưng vẫn giữ kích thước tệp bằng cách tăng số tệp (dẫn đến các vấn đề kiểm soát sửa đổi ít hơn như xung đột, v.v.).

Vì vậy, có cách đơn giản để xóa lớp mô hình khỏi tệp models.py, nhưng vẫn có các mô hình hoạt động với tất cả các công cụ Django không? Hoặc, là có một giải pháp hoàn toàn khác biệt nhưng thanh lịch cho vấn đề chung của một tập tin models.py "lớn"? Mội thông tin đầu vào đều sẽ được xem xét kĩ.

+6

Bạn biết báo cáo nhập, đúng không? – balpha

+6

PS. Tôi không có ý nói rằng, tôi chỉ muốn biết bạn đang ở đâu. – balpha

+0

Có, nhưng tôi không biết liệu các công cụ quản trị của django có hoạt động chỉ bằng cách sử dụng các câu lệnh nhập để lấy các Mô hình hay không. Tôi thà yêu cầu ở đây hơn là dành rất nhiều thời gian thử bằng cách sử dụng nhập khẩu ole đồng bằng chỉ để tìm ra các công cụ của django không chơi tốt với họ. Tôi thừa nhận tôi mới hơn để python và django, vì vậy tôi có lẽ chỉ ở một sự hiểu biết đơn giản của các báo cáo nhập khẩu ... – Eddified

Trả lời

61

Django được thiết kế để cho phép bạn xây dựng nhiều ứng dụng nhỏ thay vì một ứng dụng lớn.

Bên trong mỗi ứng dụng lớn đều có nhiều ứng dụng nhỏ đang gặp khó khăn để được miễn phí.

Nếu bạn models.py cảm thấy to lớn, bạn đang làm quá nhiều. Dừng lại. Thư giãn. Phân hủy.

Tìm các thành phần, phần hoặc ứng dụng nhỏ có khả năng sử dụng lại nhỏ hơn, có khả năng tái sử dụng. Bạn không cần phải thực sự sử dụng lại chúng. Chỉ cần nghĩ về chúng như khả năng tái sử dụng.

Xem xét đường dẫn nâng cấp của bạn và phân tách các ứng dụng mà bạn có thể muốn thay thế một số ngày. Bạn không cần phải thực sự thay thế chúng, nhưng bạn có thể xem chúng là một "mô-đun" độc lập của chương trình có thể được thay thế bằng thứ gì đó mát mẻ hơn trong tương lai.

Chúng tôi có khoảng một chục ứng dụng, mỗi ứng dụng model.py không nhiều hơn 400 dòng mã. Tất cả chúng đều tập trung vào ít hơn khoảng nửa tá định nghĩa lớp rời rạc. (Đây không phải là giới hạn khó, chúng là những quan sát về mã của chúng tôi.)

Chúng tôi phân hủy sớm và thường xuyên.

+1

ngay trên điểm. mọi ứng dụng web không tầm thường sẽ là một số 'ứng dụng' nhỏ. có một gợi ý về sự đóng góp và các ứng dụng phổ biến khác, xác thực người dùng là một ứng dụng, gắn thẻ là một ứng dụng khác, hồ sơ người dùng, v.v. – Javier

+4

Mặc dù đây là cách "đúng" và hữu ích khi biết, nó không hoàn toàn là gì Tôi đang tìm kiếm. Tôi xin lỗi nếu không có cách nào để biết tôi đang tìm kiếm loại câu trả lời nào.:) – Eddified

+0

@Được xác định: nếu bạn không làm điều này, nó sẽ chỉ trở nên tồi tệ hơn. Bắt đầu tách ngay bây giờ. –

93

Điều này là tự nhiên đối với các lớp mô hình chứa các phương thức hoạt động trên mô hình. Nếu tôi có một mô hình Book, với phương thức book.get_noun_count(), đó là nơi nó thuộc về - tôi không muốn phải viết "get_noun_count(book)", trừ khi phương thức này thực sự thuộc về một số gói khác. (Ví dụ: nếu tôi có một gói để truy cập API của Amazon bằng "get_amazon_product_id(book)".)

Tôi co lại khi tài liệu của Django đề xuất đặt mô hình trong một tệp và tôi đã dành vài phút ngay từ đầu để tìm ra cách tách nó thành một gói con thích hợp.

site/models/__init__.py 
site/models/book.py 

__init__.py trông giống như:

from .book import Book 

vì vậy tôi vẫn có thể viết "từ site.models nhập Book".


Sau đây là chỉ cần thiết cho các phiên bản trước Django 1,7, xem https://code.djangoproject.com/ticket/3591

Bí quyết duy nhất là bạn cần phải thiết lập một cách rõ ràng ứng dụng của từng mô hình, do một lỗi trong Django : nó giả định rằng tên ứng dụng là mục nhập thứ ba đến cuối cùng trong đường dẫn mô hình. "site.models.Book" dẫn đến "trang web", đó là chính xác; "site.models.book.Book" làm cho nó nghĩ rằng tên ứng dụng là "mô hình". Đây là một hack khá khó chịu trên một phần của Django; nó có lẽ nên tìm kiếm danh sách các ứng dụng đã cài đặt cho một kết quả tiền tố.

class Book(models.Model): 
    class Meta: app_label = "site" 

Bạn có thể sử dụng lớp cơ sở hoặc metaclass để khái quát hóa điều này, nhưng tôi chưa hề bận tâm đến điều đó.

+2

+1 Tôi đã sử dụng thành công này. Trong khi S. Lott là đúng trong nhiều ứng dụng là một ý tưởng tốt, đây là giải pháp ở đây và bây giờ. –

+0

Đây là cách để làm điều đó. Có thêm thông tin tại trang web Django: http://code.djangoproject.com/wiki/CookBookSplitModelsToFiles –

+0

@ Alexander Ljungberg: Tôi không dễ dàng tin rằng điều này đơn giản hơn việc tách các ứng dụng ra. Ứng dụng có thể được tách ra từ 'models.py' ban đầu khá đơn giản. Thông thường, nó chỉ cắt giảm và dán một chút so với urls.py, views.py, tests.py và models.py. –

4

Tôi hoàn toàn không thể gặp phải nhiều vấn đề có thể xảy ra. Dưới đây là một số khả năng kèm đáp án:

  • nhiều mô hình trong cùng một tệp

    Đặt chúng vào các tập tin riêng biệt. Nếu có phụ thuộc, hãy sử dụng tính năng nhập để lấy các mô hình bổ sung .

  • chức năng logic/tiện ích liên quan trong models.py

    Đặt logic thêm vào các tập tin riêng biệt.

  • phương pháp tĩnh để lựa chọn một số trường hợp mô hình từ cơ sở dữ liệu

    Tạo mới Manager trong một file riêng biệt.

  • phương pháp rõ ràng liên quan đến mô hình

    lưu, __unicode__ và get_absolute_url là những ví dụ.

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