2016-02-19 8 views
5

मेरे पास 3 मॉडल हैं जो एक-दूसरे से जुड़े संबंधों के साथ एक दूसरे से संबंधित हैं।डीजेगो रेस्ट फ्रेमवर्क में मॉडल विधि में व्यवसाय तर्क कहां जाता है?

  • मॉडल ए सी
  • मॉडल एक मॉडल सी
  • मॉडल बी के कई उदाहरणों मॉडल के कई उदाहरण हो सकते हैं हो सकता है मॉडल बी के कई उदाहरण हो सकते हैं

विचार यह है कि कोई उपयोगकर्ता मॉडल ए (स्टॉक पोर्टफोलियो की तरह) का उदाहरण देगा और फिर स्टॉक होल्डिंग्स (मॉडल सी) दर्ज करेगा। जहां मॉडल बी फिट बैठता है यह है कि मैं पोर्टफोलियो (मॉडल ए) में स्टॉक (मॉडल सी) के आधार पर गणना/तर्क चलाने के लिए और चीजों का ट्रैक रखने के लिए एक और वर्ग/मॉडल का उपयोग करना आसान बनाता है, इसलिए मॉडल बी

मूल रूप से मुझे Django दृश्य में इन गणनाओं के लिए तर्क था लेकिन में पढ़ें Django के दो स्कूप्स जो व्यवसाय तर्क को विचारों से अलग किया जाना चाहिए। नतीजतन मैंने तर्क को मॉडल ए (पोर्टफोलियो) की विधि में स्थानांतरित कर दिया और अब उस विधि को एक दृश्य से कॉल करें। यह लॉजिक स्टॉक होल्डिंग्स के माध्यम से loops और मॉडल बी, नतीजे के नए उदाहरण बनाता है।

अब मैं जावास्क्रिप्ट फ्रंटएंड (जैसे कोणीय) के लिए एक एपीआई प्रदान करने के लिए django-rest-framework की खोज में रूचि रखता हूं। मुझे लगता है कि मैं अपने आरईएसटी इंटरफेस के भीतर इस तरह के डेटा मैनिपुलेशन नहीं कर पाऊंगा। हालांकि, इस तर्क का परिणाम (मॉडल बी में डेटा) को आरईएसटी के माध्यम से दिखाना आवश्यक है। इसलिए, इस प्रकार की गणना/तर्क कहां जाता है?

उत्तर

11

Django Rest Framework मुख्य टुकड़े दृश्य (व्यूसेट्स, एपीवीव्स, आदि) और सीरियलाइज़र हैं। उनमें से कोई भी तर्क लिखने के लिए आदर्श जगह नहीं है। जैसा कि आपने बताया है, किसी भी दृश्य में तर्क लिखना अच्छा नहीं है। क्यूं कर?

  1. कोई रास्ता नहीं तर्क संपुटित करने के लिए कोई रास्ता नहीं एप्लिकेशन
  2. के किसी अन्य भाग से एक ही तर्क का उपयोग करने के
  3. इकाई परीक्षण करने के लिए कोई रास्ता नहीं है (यदि आप चलाने के लिए तर्क के लिए दृश्य कॉल करने की आवश्यकता) तर्क क्योंकि

आईएमएचओ, मॉडल तर्क लिखने के लिए एक अच्छी जगह नहीं है। मॉडल को अपनी डेटाबेस परिभाषा के रूप में सोचें। मैं उन्हें यथासंभव सरल रखूंगा। आप छोटे कार्यों को करने के लिए "सेव" और अन्य विधियों को ओवरराइड कर सकते हैं। किसी भी अन्य उन्नत कार्यक्षमता इसके बाहर रहना चाहिए।

मैं आपको क्या चाहिए के लिए दो बेहतर स्थानों के बारे में सोच सकते हैं:

उनमें से एक एक django signal

एक बेहतर एक एक कस्टम वर्ग है। Encapsulate/अपनी खुद की कक्षा में तर्क दसगुणा (आप स्थिर या उदाहरण के तरीकों का उपयोग कर सकते हैं, यह बात नहीं करता), और फिर आप में सक्षम हो जाएगा:

  1. यूनिट परीक्षण उन तरीकों/उस वर्ग नकली
  2. पुन: उपयोग इस तर्क कहीं और
  3. KISS सिद्धांत के अनुसार
  4. एक संशोधित किए बिना संकेत कोड सरल
  5. एक अजवाइन कार्य से यह प्रयोग करें (यदि आप भविष्य में यह लागू) रखने एक संकेत से यह प्रयोग कर अपने कोड को सरल बनाएँ आपकी एक पंक्ति कोड

अद्यतन कोड व्यवस्थित करने का एक उदाहरण।

टिप्पणियों से यह स्पष्ट है कि एक संकेत काम नहीं करेगा क्योंकि विश्लेषण ऑपरेशन उपयोगकर्ता अनुरोध पर चलाएगा। यदि कोई विशिष्ट मॉडल सहेजते समय उस ऑपरेशन को स्वचालित रूप से चलाना चाहिए तो एक सिग्नल उपयोगी होगा।

मैं आप यह सोचते हैं कि कैसे Django-आराम-फ़्रेमवर्क API विचार या viewsets, serializers, आदि मैं उपयोग करने के लिए आप नहीं है कि के बारे में, बेहतर पूछते हैं कि एक और सवाल पता है। यह किसी और

कुछ भी अपने अनुप्रयोग मॉड्यूल में अधिक से अधिक एक अजगर स्पष्टीकरण होने जा रहा है, एक फ़ाइल app_business_logic.py या जो भी आप इसे कॉल करना चाहते हैं पैदा करते हैं। आप उदाहरण के लिए models.py के समान स्तर पर रख सकते हैं, लेकिन नहीं अनिवार्य है यह:

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 

अब, एक Django-आराम-फ़्रेमवर्क API दृश्य या viewset में, होने के लिए एक POST विधि बनाने जब ग्राहक एप्लिकेशन को उपयोगकर्ता प्रेस बटन (उस बटन विश्लेषण उत्पन्न करने के लिए) कहा जाता है:

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) 
कुछ

इस के लिए यूआरएल होगा http://server.com/api_path/stockportfolio/21/run_analysis/, जहां 21 वर्ष की StockPortfolio

+0

के लिए @xleon धन्यवाद आईडी होगा की तरह प्रतिक्रिया। मुझे अभी भी यह सुनिश्चित नहीं है कि यह सब (सिग्नल या कस्टम क्लास) एक परियोजना में फिट बैठता है। मैं कल्पना कर रहा हूं कि उपयोगकर्ता अपने पोर्टफोलियो (मॉडल ए) में अपने होल्डिंग्स (मॉडल सी) को देखेगा। फिर वे 'विश्लेषण' बटन पर क्लिक करके विश्लेषण (प्रत्येक होल्डिंग के माध्यम से लूपिंग और मॉडल बी उदाहरण बना सकते हैं) चलाने में सक्षम होंगे। आखिरकार, सभी 3 मॉडल एक आरईएसटी एपीआई के माध्यम से उपलब्ध होंगे। यदि उपयोगकर्ता विश्लेषण नहीं चला है तो मॉडल बी के लिए एपीआई खाली होगा। यदि विश्लेषण तर्क सिग्नल या कस्टम क्लास में है, तो इसे मॉडल बी एपीआई को पॉप्युलेट करने के लिए कहा जाता है? – shudoh

+0

यदि आप किसी उपयोगकर्ता क्रिया के माध्यम से विश्लेषण चलाते हैं, तो एक django सिग्नल एक विकल्प नहीं है (केवल तभी अनुशंसा की जाती है जब अन्य मॉडल को सहेजते समय उस विश्लेषण को स्वचालित रूप से चलाना चाहिए)। मैं आपके वर्कफ़्लो – xleon

+0

वाह के लिए कुछ छद्म कोड के साथ उत्तर अपडेट कर दूंगा। उत्कृष्ट उदाहरण मैं हमेशा models.py में व्यापार तर्क रखने के बारे में सोच रहा था। कुछ लोकप्रिय प्रकाशनों से पता चलता है कि इसे रखने का स्थान है, लेकिन मुझे हमेशा संदेह है। –

संबंधित मुद्दे