Django

2012-02-13 5 views
5

में कई-से-अनेक संबंध में पहले आइटम आइटम हो रही है मैं Django में दो मॉडल इस तरह ManyToMany संबंध से एक साथ जुड़े है: मैं समूह में मुख्य व्यक्ति प्राप्त करने की आवश्यकताDjango

class Person(models.Model): 
    name = models.CharField(max_length=128) 

class Group(models.Model): 
    name = models.CharField(max_length=128) 
    members = models.ManyToManyField(Person) 

जो समूह में पहला व्यक्ति है। मैं पहला व्यक्ति कैसे प्राप्त कर सकता हूं?

यहाँ कैसे मैं सदस्यों को जोड़ने हूँ:

grp = Group.objects.create(name="Group 1") 
grp.save() 
prs = Person.objects.create(name="Tom") 
grp.members.add(prs) #This is the main person of the group. 
prs = Person.objects.create(name="Dick") 
grp.members.add(prs) 
prs = Person.objects.create(name="Harry") 
grp.members.add(prs) 

मुझे नहीं लगता कि मैं मेज group_members की आईडी के रूप में किसी भी अतिरिक्त कॉलम की ज़रूरत है एक चल अनुक्रम सही है।

यदि मैं समूह के मुख्य सदस्य को Group.objects.get(id=1).members[0] के माध्यम से लाने का प्रयास करता हूं तो Django का कहना है कि प्रबंधक अनुक्रमणीय नहीं है।

यदि मैं इस Group.objects.get(id=1).members.all().order_by('id')[0] को आजमाता हूं, तो मुझे Person तालिका में निम्नतम आईडी वाला सदस्य मिल जाता है।

मैं इसे कैसे हल कर सकता हूं?

धन्यवाद

+0

तुम कैसे निर्धारित करने के लिए समूह में "पहली" व्यक्ति है करना चाहते हैं? आईडी? वर्णक्रम? – Brandon

+0

तालिका 'group_members' तालिका में सबसे कम 'id' वाला वाला। वस्तुओं को इस तालिका से कभी भी हटाया नहीं जाता है, इसलिए मुख्य सदस्य हमेशा समूह के लिए समान होगा। –

+0

एलेक्स गेनर का जवाब सही है। समूह द्वारा क्रमबद्ध करने के लिए आपको एक अतिरिक्त फ़ील्ड जोड़ना होगा, क्योंकि आईडी कॉलम समूह के अनुक्रमिक होने की गारंटी नहीं है। – Brandon

उत्तर

4

Django add पर कॉल के आदेश पर ध्यान नहीं देते हैं।

class GroupMembers(models.Model): 
    group = models.ForeignKey(Group) 
    person = models.ForeignKey(Person) 

जाहिर है, वहाँ एक "आदेश" या जो आप पहली बार आना चाहिए के बारे में कुछ भी नहीं बताया गया है: अंतर्निहित तालिका Django रिश्ते के लिए निम्न अगर यह एक Django मॉडल था की तरह कुछ है। डिफ़ॉल्ट रूप से, यह संभवतः ऐसा करेगा जैसा कि आप सबसे कम पीके का वर्णन करते हैं और वापस करते हैं, लेकिन ऐसा इसलिए है क्योंकि इसमें से कुछ और नहीं है।

यदि आप ऑर्डर को लागू करना चाहते हैं, तो आपको तालिका के माध्यम से उपयोग करना होगा। असल में, Django को उस अंतर्निहित मॉडल को बनाने की बजाय, आप इसे स्वयं बनाते हैं। उसके बाद, आप आदेश हुक्म को order की तरह एक क्षेत्र जोड़ देंगे: फिर

class GroupMembers(models.Model): 
    class Meta: 
     ordering = ['order'] 

    group = models.ForeignKey(Group) 
    person = models.ForeignKey(Person) 
    order = models.PositiveIntegerField(default=0) 

, आप रिश्ते के लिए इस मॉडल का उपयोग करने के लिए Django कहता हूं, बजाय:

class GroupMembers(models.Model): 
    group = models.ForeignKey(Group) 
    person = models.ForeignKey(Person, through='GroupMembers') 

अब, जब आप जोड़ने के अपने सदस्य, आप अब add का उपयोग नहीं कर सकते हैं, क्योंकि रिश्ते को पूरा करने के लिए अतिरिक्त जानकारी की आवश्यकता है।इसके बजाय, आप के माध्यम से मॉडल का उपयोग करना चाहिए:

prs = Person.objects.create(name="Tom") 
GroupMembers.objects.create(person=prs, group=grp, order=1) 
prs = Person.objects.create(name="Dick") 
GroupMembers.objects.create(person=prs, group=grp, order=2) 
prs = Person.objects.create(name="Harry") 
GroupMembers.objects.create(person=prs, group=grp, order=3) 

फिर, बस का उपयोग करें:

class GroupMembers(models.Model): 
    group = models.ForeignKey(Group) 
    person = models.ForeignKey(Person) 
    is_main_user = models.BooleanField(default=False) 
:

Group.objects.get(id=1).members.all()[0] 

वैकल्पिक रूप से, आप बस मुख्य उपयोगकर्ता है जो निर्दिष्ट करने के लिए एक BooleanField जोड़ सकता है

फिर, "टॉम" जोड़ें:

prs = Person.objects.create(name="Tom") 
GroupMembers.objects.create(person=prs, group=grp, is_main_user=True) 

और अंत में, के माध्यम से "टॉम" पुनः प्राप्त:

Group.objects.get(id=1).members.filter(is_main_user=True)[0] 
3

संबंधपरक डेटाबेस डिफ़ॉल्ट रूप से, आदेश के किसी भी धारणा नहीं है। "पहली" जैसी कोई चीज़ नहीं है। आपको एक स्पष्ट "ऑर्डर" फ़ील्ड जोड़ना होगा जो ऑर्डर रखता है, और इसके द्वारा ऑर्डर करता है।

1

आप बहुत करीब थे:

Group.objects.get(id=1).members.all()[0] 

(लेकिन के रूप में एलेक्स Gaynor उसके जवाब में कहते हैं, उम्मीद के मुताबिक व्यवहार के लिए आप पर सॉर्ट करने के लिए एक उचित क्षेत्र की जरूरत है)

+0

मैं मेज whcih, रिश्ते अर्थात 'group_persons' (मुझे लगता है कि) शामिल हैं डेटाबेस में पर एक नज़र था और यह' group_id' और 'person_id' से अलग एक' id' स्तंभ था। चूंकि यह एक चल रहा अनुक्रम है, इसलिए मैं आइटम को सबसे कम 'id' के साथ नहीं प्राप्त कर सकता। उदाहरण जो आपने दिया था: क्या वह मुझे सेट में पहली वस्तु वापस नहीं करेगा लेकिन सेट का आदेश नहीं दिया जाएगा और इस तरह गलत होगा? धन्यवाद। –

+0

आपको दूसरी "ऑब्जेक्ट्स" की आवश्यकता नहीं है (क्या यह भी काम करता है?) बस 'members.all() '। –

+0

आप सही हैं, मेरी गलती। मैंने इसे संपादित किया है –

0

मज़बूती से है जो की एक रिकार्ड रखने के लिए एक समूह में "मुख्य" व्यक्ति, आप through तालिका का उपयोग करके इस मेटाडेटा