2012-10-12 13 views
6

मैं पाइथन और डीजेगो में नया हूं, इसलिए कृपया मेरे साथ धैर्य रखें।Django (सभी दोस्तों की पोस्ट) के साथ जटिल क्वेरी

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

class User(models.Model): 
    name = models.CharField(max_length = 50) 
    ... 

class Post(models.Model): 
    userBy = models.ForeignKey(User, related_name='post_user') 
    userWall = models.ForeignKey(User, related_name='receive_user') 
    timestamp = models.DateTimeField() 
    post = models.TextField() 

class Friend(models.Model): 
    user1 = models.ForeignKey(User, related_name='request_user') 
    user2 = models.ForeignKey(User, related_name='accept_user') 
    isApproved = models.BooleanField() 
    class Meta: 
     unique_together = (('user1', 'user2'),) 

मुझे पता है कि यह सबसे अच्छा/सबसे आसान तरीका है Django के साथ संभाल करने के लिए नहीं हो सकता है, लेकिन मैं इसे इस तरह से सीखा है और मैं इसे इस तरह रखना चाहते हैं।

अब, मैं बस इतना करना चाहता हूं कि एक व्यक्ति से सभी पोस्ट प्राप्त करें और उसके दोस्तों हैं। सवाल यह है कि Django फ़िल्टर के साथ इसे कैसे किया जाए?

मैं एसक्यूएल में लगता है कि यह कुछ इस तरह दिखेगा:

SELECT p.* FORM Post p, Friend f 
WHERE p.userBy=THEUSER OR (
    (f.user1=THEUSER AND f.user2=p.userBy) OR 
    (f.user2=THEUSER AND f.user1=p.userBy) 
) 

शुद्धता की कोई गारंटी नहीं के साथ, बस परिणाम मैं तलाश कर रहा हूँ की एक विचार देने के लिए।

उत्तर

8
from django.db.models import Q 

Post.objects.filter(\ 
    Q(userBy=some_user) | \ 
    Q(userBy__accept_user__user1=some_user) | \ 
    Q(userBy__request_user__user2=some_user)).distinct() 

अद्यतन

क्षमा करें, कि मेरी गलती थी। मैंने आपके related_name मानों पर ध्यान नहीं दिया। ऊपर अद्यतन कोड देखें। userBy__accept_user या userBy__request_user अकेले काम नहीं करेगा क्योंकि यह Friend का संदर्भ होगा, जिसका आप User से तुलना नहीं कर सकते। हम यहां क्या कर रहे हैं Friend पर रिवर्स रिलेशनशिप का पालन कर रहे हैं और फिर एक बार हम वहां हैं, यह देखते हुए कि अन्य उपयोगकर्ता अनुरोध पर उपयोगकर्ता प्रश्न में उपयोगकर्ता हैं।

यह रिवर्स रिश्तों को उचित रूप से वर्णित करने के महत्व को भी दर्शाता है। बहुत से लोग वही गलती करते हैं जो आपने यहां बनाया है और related_name का नाम मॉडल के बाद एफके (User) बनाते समय, जब हम एफके को वापस करने के बारे में बात कर रहे हैं, तो हम अब Friend के बारे में बात कर रहे हैं। बस, आपके संबंधित नाम कुछ और समझेंगे: friend_requests और accepted_friends

+0

क्या उपयोगकर्ता से कोई विदेशी कुंजी है जिसे मित्रों को इंगित करना है? – cesar09

+0

नहीं। "__friend" बिट रिश्ते के पीछे पीछे आता है, क्योंकि 'मित्र' के पास 'उपयोगकर्ता' के लिए एफके है। –

+0

अधिक जानकारी के लिए प्रलेखन देखें [लुकअप जो संबंधों को फैलाता है] (https://docs.djangoproject.com/en/dev/topics/db/queries/#lookups-that-span-relationships)। –

0
(with User u) 
friends_u1 = Friend.objects.filter(user1 = u).getlist('user2_id', flat=True) 
friends_u2 = Friend.objects.filter(user2 = u).getlist('user1_id', flat=True) 
friends_and_user = friends_u1+friends_u2+u.id 

Post.objects.filter(userBy__id__in = friends_and_user) 
+0

मानक दृष्टिकोण 'Q' ऑब्जेक्ट का उपयोग करना है। क्या आप अलग-अलग दृष्टिकोण चुनने के लिए _why_ को स्पष्ट कर सकते हैं? – Tadeck

+0

आपको "क्यू ऑब्जेक्ट का उपयोग करने के लिए मानक दृष्टिकोण" कहां मिल रहा है? दस्तावेज़ीकरण में कहीं भी यह नहीं कहता है। इसके अलावा, एक django नौसिखिया के लिए, यह टूटा हुआ दृष्टिकोण अधिक आसानी से समझने योग्य हो सकता है। अनुभव से – Colleen

+4

। आप पहले सभी आईडी एकत्र कर रहे हैं, तो आप इसे एक क्वेरी के लिए उपयोग कर रहे हैं। उस मामले पर विचार करें जहां आपके पास 500 दोस्त होंगे, क्वेरी बहुत बड़ी हो सकती है। हां, इस समाधान का उपयोग Django नौसिखिया द्वारा किया जा सकता है (या किसी व्यक्ति द्वारा _why_ और _when_ यह बेहतर हो सकता है), लेकिन यह समझना आसान नहीं है, बल्कि सबसे अच्छा (या कम से कम "अच्छा") क्या है। जब "मानक दृष्टिकोण" भाग की बात आती है: [Django में जटिल प्रश्नों पर दस्तावेज़ पढ़ें] (https://docs.djangoproject.com/en/dev/topics/db/queries/#complex-lookups-with-q- वस्तुओं)। – Tadeck

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