2012-08-14 7 views
39

मैं GenericForeignKey का उपयोग करने में नया हूं, और मैं इसे एक क्वेरी कथन में काम नहीं कर सका। टेबल मोटे तौर पर निम्नलिखित की तरह कर रहे हैं:django: GenericForeignKey के फ़ील्ड के आधार पर मैं क्वेरी कैसे करूं?

class Ticket(models.Model): 
    issue_ct = models.ForeignKey(ContentType, related_name='issue_content_type') 
    issue_id = models.PositiveIntegerField(null=True, blank=True) 
    issue = generic.GenericForeignKey('issue_ct', 'issue_id') 

class Issue(models.Model): 
    scan = models.ForeignKey(Scan) 

एक स्कैन एक मुद्दा बनाता है, एक मुद्दा कुछ टिकट उत्पन्न करता है, और मैं टिकट तालिका के लिए एक विदेशी कुंजी के रूप में जारी करना बना दिया। अब मेरे पास स्कैन ऑब्जेक्ट है, और मैं इस स्कैन से संबंधित सभी टिकटों के लिए पूछना चाहता हूं। मैंने पहले यह कोशिश की:

tickets = Tickets.objects.filter(issue__scan=scan_obj) 

जो काम नहीं करता है। फिर मैंने यह कोशिश की:

issue = Issue.objects.get(scan=scan_obj) 
content_type = ContentType.objects.get_for_model(Issue) 
tickets = Tickets.objects.filter(content_type=content_type, issue=issue) 

अभी भी काम नहीं करता है। मुझे पता होना चाहिए कि django में इस तरह के प्रश्न कैसे करें? धन्यवाद।

उत्तर

57

Ticket.issue फ़ील्ड जिसे आपने परिभाषित किया है, आपको Ticket उदाहरण से Issue पर संलग्न करने में मदद मिलेगी, लेकिन यह आपको पीछे की ओर जाने नहीं देगा। आप अपने दूसरे उदाहरण के करीब हैं, लेकिन आपको issue_id फ़ील्ड का उपयोग करने की आवश्यकता है - आप GenericForeignKey पर क्वेरी नहीं कर सकते हैं (यह आपके पास Ticket उदाहरण होने पर ऑब्जेक्ट को पुनर्प्राप्त करने में सहायता करता है)। एक दूसरे मॉडल है कि Ticket साथ db_table शेयरों बनाने के द्वारा एक GenericForeignKey कर सकते हैं भर में

from django.contrib.contenttypes.models import ContentType 

issue = Issue.objects.get(scan=scan_obj) 
tickets = Ticket.objects.filter(issue_id=issue.id, issue_ct=ContentType.objects.get_for_model(issue)) 
+3

मेरा दिन बचाया, मेरे दोस्त, मैं इसे समझने की कोशिश करने के बाद मूल रूप से बेकार हूं। धन्यवाद :) । –

+0

@girasquid issue_id बहुत भ्रमित है क्योंकि यह प्रश्न में फ़ील्ड issue_id या प्रश्न में समस्या फ़ील्ड की आईडी विशेषता का संदर्भ दे सकता है, क्या हम उन्हें अलग-अलग बना सकते हैं? – rohanagarwal

14

छनन: इस प्रयास करें। पहले एक अमूर्त मॉडल और ठोस मॉडल में टिकट विभाजित करें।

class TicketBase(models.Model): 
    issue_ct = models.ForeignKey(ContentType, related_name='issue_content_type') 
    issue_id = models.PositiveIntegerField(null=True, blank=True) 

    class Meta: 
     abstract = True 

class Ticket(models.Model): 
    issue = generic.GenericForeignKey('issue_ct', 'issue_id') 

फिर एक मॉडल है कि यह भी उपवर्गों TicketBase पैदा करते हैं। इस सबक्लास में issue को छोड़कर सभी समान फ़ील्ड होंगे जिन्हें इसके बजाय ForeignKey के रूप में परिभाषित किया गया है। कस्टम Manager जोड़ने से इसे केवल एक ContentType पर फ़िल्टर किया जा सकता है।

चूंकि इस सबक्लास को सिंक या माइग्रेट करने की आवश्यकता नहीं है, इसलिए इसे type() का उपयोग करके गतिशील रूप से बनाया जा सकता है।

def subclass_for_content_type(content_type): 
    class Meta: 
     db_table = Ticket._meta.db_table 

    class Manager(models.Manager): 
     """ constrain queries to a single content type """ 
     def get_query_set(self): 
      return super(Manager, self).get_query_set().filter(issue_ct=content_type) 

    attrs = { 
     'related_to': models.ForeignKey(content_type.model_class()), 
     '__module__': 'myapp.models', 
     'Meta': Meta, 
     'objects': Manager() 
    } 
    return type("Ticket_%s" % content_type.name, (TicketBase,), attrs) 
+0

यह बहुत ही चालाक है .. –

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