Phần khung Django Rest là các khung nhìn (ViewSets, ApiViews, vv) và serializers. Không ai trong số đó là những nơi lý tưởng để viết logic. Như bạn đã đề cập, viết logic trong bất kỳ khung nhìn nào cũng không tốt. Tại sao?
- Không có cách nào để sử dụng cùng một logic từ một phần khác của ứng dụng
- Không có cách nào để đóng gói logic (bạn cần phải gọi quan điểm cho logic để chạy)
- Không có cách nào để kiểm tra đơn vị logic vì được ghép với chế độ xem
IMHO, các mô hình không phải là nơi tốt để viết logic. Hãy nghĩ về một mô hình làm định nghĩa cơ sở dữ liệu của bạn. Tôi sẽ giữ chúng càng đơn giản càng tốt. Bạn có thể ghi đè "lưu" và các phương pháp khác để thực hiện các tác vụ tầm thường. Bất kỳ chức năng nâng cao nào khác đều phải ở bên ngoài nó.
tôi có thể nghĩ đến hai nơi tốt hơn cho những gì bạn cần:
Một trong số đó là một django signal
Một một tốt hơn là một lớp tùy chỉnh. Encapsulate/tách logic trong lớp học riêng của bạn (bạn có thể sử dụng phương pháp tĩnh hoặc dụ, nó doesn't vấn đề), và sau đó bạn sẽ có thể:
- Đơn vị thi các phương pháp/nhạo báng lớp
- Tái sử dụng logic này ở một nơi khác
- đơn giản hóa mã của bạn theo KISS nguyên tắc
- Sử dụng nó từ một tín hiệu giữ mã tín hiệu đơn giản
- Sử dụng nó từ một nhiệm vụ cần tây (nếu bạn thực hiện điều này trong tương lai) mà không sửa đổi một một dòng của bạn mã
CẬP NHẬT Ví dụ về cách sắp xếp mã.
Từ nhận xét, rõ ràng là tín hiệu sẽ không hoạt động vì hoạt động phân tích sẽ chạy theo yêu cầu của người dùng. Một tín hiệu sẽ hữu ích nếu thao tác đó sẽ tự động chạy khi lưu một mô hình cụ thể.
Tôi giả sử bạn biết cách sử dụng chế độ xem khung cảnh django-rest-api hoặc lượt xem, serializers, v.v. Tôi không làm thế nào về điều đó, tốt hơn hãy hỏi một câu hỏi khác. Đây sẽ là giải thích về python nhiều hơn bất kỳ điều gì khác
Trong mô-đun ứng dụng của bạn, tạo một tệp app_business_logic.py
hoặc bất kỳ điều gì bạn muốn gọi. Bạn có thể đặt nó ở cùng một mức độ các models.py ví dụ, nhưng đó là không bắt buộc:
class HoldingsAnalyser:
# static method sample. Call it like this: "HoldingsAnalyser.run(..)"
@staticmethod
def run(holding_list):
# do your model generation here or whatever you need
return True # or whatever you need to return
# instance method sample. Create an instance first and then call the method:
# analyser = HoldingsAnalyser()
# analyser.run(...)
def run(self, holding_list):
# do your model generation here or whatever you need
return True # or whatever you need to return
Bây giờ, trong một cái nhìn api django-nghỉ ngơi-framework hoặc viewset, tạo ra một phương thức POST được gọi khi báo chí khách hàng sử dụng ứng dụng vào nút (nút đó để tạo ra phân tích):
from yourapp.app_business_logic import HoldingsAnalyser
class StockPortfolioViewSet(WhatEverMixingYouNeedToInheritFrom):
serializer_class = whatever # look at the docs
@detail_route(methods=['post'])
def run_analysis(self, request, pk):
stock_portfolio = get the object based on the pk
holdings = make your query to get the holdings
analysis_result = HoldingsAnalyser.run(holdings)
if analysis_result:
# everything ok
return Response(status=status.HTTP_204_NO_CONTENT)
else:
return Response(a useful error for your client)
url này sẽ là một cái gì đó giống như http://server.com/api_path/stockportfolio/21/run_analysis/
, nơi 21 sẽ là id của StockPortfolio
Cảm ơn @xleon cho Phản hồi. Tôi vẫn không chắc chắn về nơi mà tất cả điều này (tín hiệu hoặc các lớp tùy chỉnh) phù hợp với một dự án. Tôi đang hình dung người dùng sẽ xem xét phần lưu trữ của họ (Mẫu C) trong danh mục đầu tư của họ (Mẫu A). Sau đó, họ sẽ có thể chạy phân tích (lặp qua từng lần giữ và tạo các phiên bản Model B) bằng cách nhấp vào nút 'phân tích'. Cuối cùng, tất cả 3 mô hình sẽ có sẵn thông qua một API REST. Nếu người dùng không chạy phân tích thì API cho Mô hình B sẽ trống. Nếu logic phân tích nằm trong lớp tín hiệu hoặc lớp tùy chỉnh khi nào nó được gọi để điền vào API Mô hình B? – shudoh
Nếu bạn chạy phân tích thông qua hành động của người dùng, tín hiệu django không phải là tùy chọn (chỉ được khuyến nghị nếu phân tích đó sẽ chạy tự động khi lưu mô hình khác). Tôi sẽ cập nhật câu trả lời với một số mã giả cho quy trình làm việc của bạn – xleon
Chà. Ví dụ tuyệt vời. Tôi luôn tự hỏi về việc đặt logic nghiệp vụ trong models.py. Một số ấn phẩm phổ biến cho rằng đó là nơi để đặt nó, nhưng tôi đã luôn luôn có những nghi ngờ của tôi. –