2012-10-01 39 views
8

के बजाय आईडी असाइन करें, अगर मेरा प्रश्न मूर्खतापूर्ण साबित हो जाता है, तो मैं क्षमा चाहता हूं, लेकिन मैं Django के लिए नया हूं, और मुझे कहीं भी जवाब नहीं मिला। अबDjango मॉडल - ऑब्जेक्ट

class BlackListEntry(models.Model): 
    user_banned = models.ForeignKey(auth.models.User,related_name="user_banned") 
    user_banning = models.ForeignKey(auth.models.User,related_name="user_banning") 

, जब मैं इस तरह एक वस्तु बनाने की कोशिश:

मैं निम्नलिखित मॉडल है

BlackListEntry.objects.create(user_banned=int(user_id),user_banning=int(banning_id)) 

मैं एक निम्न त्रुटि मिलती है:

Cannot assign "1": "BlackListEntry.user_banned" must be a "User" instance. 
के

बेशक, अगर मैं इसे इस तरह से बदलता हूं:

user_banned = User.objects.get(pk=user_id) 
user_banning = User.objects.get(pk=banning_id) 
BlackListEntry.objects.create(user_banned=user_banned,user_banning=user_banning) 

सबकुछ ठीक काम करता है। सवाल यह है:

क्या मेरा समाधान डेटाबेस दोनों उपयोगकर्ताओं को पुनर्प्राप्त करने के लिए हिट करता है, और यदि हां, तो क्या इससे बचना संभव है, बस आईडी को पास करना?

उत्तर

10

आपके प्रश्न का उत्तर है: हाँ।

Django दो उपयोगकर्ता ऑब्जेक्ट्स को पुनर्प्राप्त करने के लिए डेटाबेस (कम से कम) 3 बार, 2 को दबाएगा और आपकी वांछित जानकारी को पूरा करने के लिए तीसरा होगा। यह एक निरपेक्ष अनावश्यक उपरि का कारण बन जाएगा।

बस कोशिश:

BlackListEntry.objects.create(user_banned_id=int(user_id),user_banning_id=int(banning_id)) 

ये Django ORM द्वारा उत्पन्न FK क्षेत्रों के लिए डिफ़ॉल्ट नाम पैटर्न है। इस तरह आप सीधे जानकारी सेट कर सकते हैं और प्रश्नों से बच सकते हैं।

आप पहले से ही बचाया BlackListEntry वस्तुओं के लिए क्वेरी करने के लिए चाहते हैं तो आपके गुण एक डबल अंडरस्कोर के साथ, इस तरह नेविगेट कर सकते हैं:

BlackListEntry.objects.filter(user_banned__id=int(user_id),user_banning__id=int(banning_id)) 

इस तरह आप Django क्वेरीसमूहों में गुण का उपयोग। एक डबल अंडरस्कोर के साथ। फिर आप विशेषता के मूल्य की तुलना कर सकते हैं।

हालांकि बहुत समान है, वे पूरी तरह से अलग काम करते हैं। पहला व्यक्ति सीधे एट्रिब्यूट सेट करता है जबकि दूसरे को डीजेंगो द्वारा पार्स किया जाता है, जो इसे '__' पर विभाजित करता है, और डेटाबेस को सही तरीके से पूछता है, दूसरा भाग एक विशेषता का नाम होता है।

आप हमेशा अपने आईडी के बजाय वास्तविक उपयोगकर्ता ऑब्जेक्ट्स के साथ user_banned और user_banning की तुलना कर सकते हैं। लेकिन इसके लिए इसका कोई उपयोग नहीं है यदि आपके पास पहले से ही उन वस्तुओं को नहीं है।

उम्मीद है कि यह मदद करता है।

+0

यह मुझे देता है: 'user_banning__id' इस फ़ंक्शन के लिए एक अवैध कीवर्ड तर्क है –

+0

मुझे खेद है, मुझे अभी एहसास हुआ कि आप ऑब्जेक्ट बना रहे हैं। तो, आपको एक अंडरस्कोर के साथ उपयोग करने की आवश्यकता है। मैं स्पष्टीकरण के लिए अपना जवाब संपादित करूंगा क्यों। – Francisco

+0

धन्यवाद, अब यह काम करता है। मैं आपको +1 जोड़ूंगा, लेकिन मैं अभी तक ऐसा करने के लिए बहुत n00bly हूँ। –

0

मुझे विश्वास है कि जब आप उपयोगकर्ताओं को लाने, यह डाटाबेस हिट करने के लिए जा रहा है कि ...

यह बचने के लिए आप विधि यहाँ वर्णित का उपयोग कर अद्यतन करने के लिए कच्चे एसक्यूएल लिखने के लिए होगा:

https://docs.djangoproject.com/en/dev/topics/db/sql/

आप उस मार्ग से जाने के लिए निर्णय लेते हैं तो यह ध्यान रखें कि आप अपने आप एसक्यूएल इंजेक्शन हमलों से रक्षा करने के लिए जिम्मेदार हैं।

उपयोगकर्ता विकल्प और उपयोगकर्ता_बैनिंग ऑब्जेक्ट्स को कैश करना एक और विकल्प होगा।

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

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