2011-10-25 16 views
15

मैं खुद को प्रशिक्षित करने के लिए डीजेगो के साथ एक निजी परियोजना का निर्माण कर रहा हूं (क्योंकि मुझे Django पसंद है, लेकिन मुझे कौशल याद आती है)। मेरे पास मूलभूत आवश्यकताएं हैं, मुझे पाइथन पता है, मैं तीन बार नहीं तो Django पुस्तक को दो बार ध्यान से पढ़ता हूं।अमूर्त वर्ग (सामान्य संबंध) के लिए विदेशीकी

मेरा लक्ष्य एक साधारण निगरानी सेवा बनाना है, एक Django- आधारित वेब इंटरफेस के साथ मुझे अपने "नोड्स" (सर्वर) की स्थिति की जांच करने की इजाजत दी गई है। प्रत्येक नोड में कई "सेवाएं" होती हैं। आवेदन प्रत्येक नोड के लिए प्रत्येक सेवा की उपलब्धता की जांच करता है।

मेरी समस्या यह है कि मुझे नहीं पता कि मेरे डेटाबेस में विभिन्न प्रकार की सेवाओं का प्रतिनिधित्व कैसे किया जाए। मैं दो "समाधान" के बारे में सोचा:

  • एकल सेवा मॉडल को "ServiceType" क्षेत्र के साथ, और खेतों के साथ एक बड़ी गड़बड़। (मुझे डेटाबेस मॉडलिंग में कोई अच्छा अनुभव नहीं है, लेकिन ऐसा लगता है ... मुझे "बुरा")
  • एकाधिक सेवा मॉडल। मुझे यह समाधान पसंद है, लेकिन फिर मुझे नहीं पता कि मैं इन क्षेत्रों में अलग-अलग सेवाओं का संदर्भ कैसे दे सकता हूं।

यह मेरा models.py फ़ाइल से कुछ ही अंश है:

from django.db import models 

# Create your models here.                               
class service(models.Model): 
    port = models.PositiveIntegerField() 
    class Meta: 
     abstract = True 

class sshService(service): 
    username = models.CharField(max_length=64) 
    pkey = models.TextField() 

class telnetService(service): 
    username = models.CharField(max_length=64) 
    password = models.CharField(max_length=64) 

class genericTcpService(service): 
    pass 

class genericUdpService(service): 
    pass 

class node(models.Model): 
    name = models.CharField(max_length=64) 
    # various fields                                 
    services = models.ManyToManyField(service) 
बेशक

, ManyToManyField के साथ लाइन फर्जी है (मैं सब कुछ है कि इस समस्या से संबंधित नहीं है निकाला गया)। मुझे नहीं पता कि "* सेवा" के स्थान पर क्या रखा जाए। मैंने ईमानदारी से इस बारे में समाधान की खोज की, मैंने "सामान्य संबंध", ट्रिपल-जॉइन टेबल के बारे में सुना, लेकिन मैंने वास्तव में इन चीजों को समझ नहीं लिया।

इसके अलावा, अंग्रेजी मेरी मूल भाषा नहीं है, तो डेटाबेस संरचना और अर्थ विज्ञान, मैं क्या पढ़ के अपने ज्ञान और समझ में आने के लिए सीमित है (लेकिन है कि मेरी समस्या नहीं है)

उत्तर

13

शुरुआत के लिए, वर्तमान में आपके समेकित मॉडल के बजाय, Django के multi-table inheritance का उपयोग करें।

आपका कोड तो बन गयी:

from django.db import models 

class Service(models.Model): 
    port = models.PositiveIntegerField() 

class SSHService(Service): 
    username = models.CharField(max_length=64) 
    pkey = models.TextField() 

class TelnetService(Service): 
    username = models.CharField(max_length=64) 
    password = models.CharField(max_length=64) 

class GenericTcpService(Service): 
    pass 

class GenericUDPService(Service): 
    pass 

class Node(models.Model): 
    name = models.CharField(max_length=64) 
    # various fields                                 
    services = models.ManyToManyField(Service) 

डेटाबेस स्तर पर, यह एक 'सेवा' तालिका, पंक्तियाँ जिनमें से प्रत्येक बच्चे को सेवा के लिए अलग तालिकाओं के साथ एक के बाद एक को संबंधों के माध्यम से लिंक कर दिया जाएगा पैदा करेगा ।

node = Node.objects.get(pk=node_id) 

for service in node.services.all(): 
    # Do something with the service 

'सेवा' पाश में आप का उपयोग वस्तुओं पेरेंट प्रकार के हो जाएगा:

इस दृष्टिकोण के साथ केवल कठिनाई जब आप निम्नलिखित की तरह कुछ करना है। आप जानते हैं कि बच्चे को टाइप इन पहले से होगा, तो आप सिर्फ बच्चे वर्ग निम्नलिखित तरीके से उपयोग कर सकते हैं:

from django.core.exceptions import ObjectDoesNotExist 

try: 
    telnet_service = service.telnetservice 
except (AttributeError, ObjectDoesNotExist): 
    # You chose the wrong child type! 
    telnet_service = None 

आप बच्चे प्रकार पहले से पता नहीं है, तो यह थोड़ा जटिल काम हो जाता है। माता-पिता मॉडल पर 'सेवा टाइप' फ़ील्ड समेत कुछ हैकी/गन्दा समाधान हैं, लेकिन एक बेहतर तरीका है, जैसा कि जो जे ने उल्लेख किया है, 'सबक्लासिंग क्वेरीसेट' का उपयोग करना है। Django-model-utils से विरासत प्रबंधक वर्ग शायद उपयोग करने में सबसे आसान है। here के लिए प्रलेखन पढ़ें, यह कोड का वास्तव में बहुत अच्छा है।

+0

विस्तृत, कोड से भरा, उत्तर के लिए धन्यवाद। @ जो जे में से एक के साथ, मुझे पूरा यकीन है कि यह मेरे आवेदन के मॉडलिंग में मेरी मदद करेगा। यह साइट बहुत बढ़िया है, इसके उपयोगकर्ता भी :) – pistache

+0

ठीक है, यह एक अच्छा समाधान था जिसे आपने यहां दिया था, विशेष रूप से इनहेरिटेंस मैनेजर चाल, और पूरे django-model-utils पैकेज। एक बार फिर धन्यवाद – pistache

6

मुझे लगता है कि एक दृष्टिकोण है कि आप विचार कर सकते है एक "सबक्लासिंग क्वेरीसेट"। असल में, यह आपको मूल मॉडल से पूछताछ करने की अनुमति देता है और यह परिणाम क्वेरीसेट में बाल मॉडल के उदाहरण वापस कर देगा।

models.service.objects.all() 

और वह ऐसा आप परिणामों पर वापस लौटने के लिए है:

[ <sshServiceInstance>, <telnetServiceInstance>, <telnetServiceInstance>, ...] 

ऐसा करने के तरीके पर कुछ उदाहरणों के लिए, ब्लॉग पोस्ट पर लिंक की जाँच यह आप जैसे प्रश्नों करते हैं जाएगा नीचे लिंक

http://jazstudios.blogspot.com/2009/10/django-model-inheritance-with.html

हालांकि, अगर आप इस दृष्टिकोण का उपयोग, आप अपनी सेवा मॉडल सार के रूप में के रूप में आप उदाहरण में क्या घोषणा नहीं करना चाहिए। अनुमोदित, आप एक अतिरिक्त जुड़ाव पेश करेंगे, लेकिन कुल मिलाकर मैंने सबक्लासिंग क्वेरीसेट को क्वेरीसेट में ऑब्जेक्ट्स के मिश्रित सेट को वापस करने के लिए बहुत अच्छी तरह से काम करने के लिए पाया है।

वैसे भी,, जो

+1

धन्यवाद, वास्तव में आपका जवाब, @ वोइटकैम्पफ में से एक के साथ मुझे मॉडल विरासत को समझने में मदद मिली और मुझे मेरे मॉडल डेटा संरचना को सोचने का एक नया तरीका दिया। एक तरफ नहीं, यह stackoverflow.com में मेरा पहला प्रश्न था, और मैं वेबसाइट, इंटरफ़ेस, उपयोगकर्ताओं, उत्तरों से वास्तव में खुश हूं और अब भी मुझे अपना ज्ञान साझा करने में खुशी होगी। :) – pistache

0

उम्मीद है कि इस मदद करता है आप देख रहे हैं सामान्य विदेशी कुंजी संबंधों के लिए आप Django contenttypes framework (Django में निर्मित) की जाँच करनी चाहिए। दस्तावेज़ों में काफी जानकारी है कि इसका उपयोग कैसे करें और सामान्य संबंधों के साथ कैसे काम करें।

+1

धन्यवाद, लेकिन जैसा कि मैंने कहा, मैंने इसे पहले से ही चेक किया है, लेकिन मैं वास्तव में समझ में नहीं आया था और न ही मैं अपने उपयोग के मामले में इंटरनेट पर उदाहरणों को मैप कर सकता था। – pistache

0

एक वास्तविक सेवा केवल एक नोड पर हो सकती है, है ना? उस मामले में जब एक क्षेत्र

node = models.ForeignKey('node', related_name='services') 
service कक्षा में

नहीं?

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