2009-07-28 14 views
13

यहाँ एक उदाहरण है:Django में कई क्षेत्रों को कैसे अपडेट करें?

अगर मैं इन कक्षाओं

class Author(models.Model): 
    name = models.CharField(max_length=45) 

class Book(models.Model): 
    name = models.CharField(max_length=45) 
    authors = models.ManyToManyField(Author) 

डेटाबेस में मैं नाम "जॉर्ज" और नाम "Georfe" के साथ एक और एक के साथ एक लेखक होता है। आखिरी एक गलती है। तो मैं जो चाहता हूं वह हर पुस्तक में है जिसमें "जॉर्ज" है क्योंकि उसके लेखक में से एक लेखक "जॉर्ज" द्वारा प्रतिस्थापित किया गया है।

एसक्यूएल में करना वास्तव में आसान है। "जॉर्ज" = 3 की आईडी और "Georfe" = 7 की आईडी और संबंध तालिका नाम "author_book" है:

UPDATE author_book SET id=3 WHERE id=7; 

यह करने के लिए है कि Django ORM के साथ संभव है? गलत लिखे गए लेखक की सभी संबंधित पुस्तकें मैं पाश गर्त और कार्य करें::

मैं यह करने के लिए एक रास्ता मिल गया

book.authors.add(Author.objects.get(id=3)) 
book.authors.remove(Author.objects.get(id=7)) 

लेकिन मैं इस समाधान वास्तव में सुंदर और कुशल नहीं मिल रहा है। लूप के बिना कोई समाधान है?

+0

यदि यह कुछ टाइपो को ठीक करने का एक बार सौदा है, तो कच्चे एसक्यूएल को क्यों न चलाएं? – thedz

+0

डेटाबेस में डेटा पुराने फाइलमेकर डीबी से आ रहा है और ठीक करने के लिए बहुत सारे टाइपो हैं। मैं अपने द्वारा सभी टाइपो को ठीक नहीं करना चाहता हूं। मेरी इच्छा है कि मेरा ग्राहक इसे व्यवस्थापक इंटरफ़ेस में कर सके। – Etienne

उत्तर

14

नोट: यह कोड हटा देगा खराब 'georfe' लेखक, साथ ही सही लेखक को इंगित करने के लिए पुस्तकों को अपडेट करना। यदि आप ऐसा नहीं करना चाहते हैं, तो .remove() का उपयोग @ jcdyer के उत्तर उल्लेख के रूप में करें।

क्या आप ऐसा कुछ कर सकते हैं?

george_author = Author.objects.get(name="George") 
for book in Book.objects.filter(authors__name="Georfe"): 
    book.authors.add(george_author.id) 
    book.authors.filter(name="Georfe").delete() 

मुझे लगता है कि यह आसान है, तो आप एक स्पष्ट तालिका दो मॉडल में शामिल होने के लिए किया था हो सकता है (उस कीवर्ड का आर्ग "के माध्यम से") - उस स्थिति में, आप संबंध तालिका के लिए उपयोग सीधे, के लिए होता है और बस उस पर .update(id=george_author.id) कर सकता है।

+0

जेसीडी पर मेरी टिप्पणी देखें, आपका समाधान अधिकतर समान है (हटाए जाने के अलावा, लेकिन मैं गलत टाइप किए गए लेखक को मिटाना नहीं चाहता हूं इसलिए मेरे मामले में हटाएं बेहतर है)। मुझे लगता है कि अद्यतन के साथ आपका समाधान इसे करने का सही तरीका है। मैं यह जवाब स्वीकार करता हूं।दुर्भाग्यवश मेरा मामला अधिक जटिल है क्योंकि मैं ModelAdmin का विस्तार करता हूं और सबकुछ सामान्य होना चाहिए और मुझे नहीं लगता कि मैं सीधे संबंध तालिका का उपयोग कर सकता हूं (क्योंकि मुझे यकीन नहीं था कि "trough" arguemnt सेट है या नहीं)। मैं सही हूँ? – Etienne

+0

एक उदाहरण पर, आप 'through' तर्क देख सकते हैं: book.authors.through = 'ModelName' - मुझे यकीन नहीं है कि यदि आप कक्षा के माध्यम से इसे प्राप्त कर सकते हैं, हालांकि। –

+0

मैं एक उदाहरण पर "through" तर्क की जांच करता हूं और यदि यह ManyToManyField में सेट नहीं है, तो कोई भी नहीं है। तो इस पल के लिए मैं लूप का समाधान जोड़/निकालने (या हटाएं) के साथ रखूंगा। शायद यह सुंदर और कुशल नहीं है लेकिन यह हमारी आवश्यकताओं के लिए पर्याप्त रूप से काम करता है। धन्यवाद इयान, जेसीडी – Etienne

14

तालिका के माध्यम से स्वत: जेनरेट किए जाने के साथ, आप दो-चरण सम्मिलित कर सकते हैं और हटा सकते हैं, जो पठनीयता के लिए अच्छा है।

george = Author.objects.get(name='George') 
georfe = Author.objects.get(name='Georfe') 

book.authors.add(george) 
book.authors.remove(georfe) 
assert george in book.authors 

आप एक स्पष्ट रूप से तालिका के माध्यम से निर्धारित किया है तो (लेखकों = models.ManyToManyField (लेखक, = BookAuthors) तो आप BookAuthor पर स्पष्ट रूप से संबंध बदल सकते हैं। एक अल्पज्ञात तथ्य यह है कि इस मॉडल पहले से मौजूद है, इसके माध्यम से Django द्वारा उत्पन्न होता है स्वचालित रूप से। आम तौर पर आप केवल एक स्पष्ट मॉडल के माध्यम से बनाने चाहिए अतिरिक्त डेटा आप (उदाहरण के लिए अध्याय एक विशेष लेखक ने लिखा है, एक बहु लेखक पुस्तक में) स्टोर करने के लिए इच्छा है।

# This line is only needed without a custom through model. 
BookAuthor = Book.authors.through 
book_author = BookAuthor.objects.get(author=georfe, book=great_american_novel) 
book_author.author = george 
book_author.save() 
assert george in book.authors 
+0

हा, हम ज्यादातर एक ही समय में एक ही चीज़ लिखते हैं! लेकिन मुझे ManyToManyField के "गड़बड़" तर्क के बारे में पता नहीं था। मुझे इस पर गौर करना होगा। लेकिन जिस तरह से इयान अद्यतन के साथ संबंध तालिका का उपयोग करता है, वह अधिक प्रभावशाली प्रतीत होता है। – Etienne

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