2012-05-21 72 views
2

基本上,我想要做的是過濾出一個查詢內部的公司,而這段代碼是很多調試的結果。我們已經儘可能簡化了它,並且無法確定爲什麼「Company.objects.filter(pk =」E0433CAE-1756-11E1-A97B-7071BC08AB6F「)中的公司」失敗。其他任何地方都可以完美地工作:s爲什麼此查詢集默認過濾失敗?

Autovivification,是自動嵌套字典。見Best way to automatically nest dictionaries

代碼來運行:

def run_code(code, query_dict): 
    code = code.replace('\r\n', '\n') 
    import jmsdirectory.advert.models 
    import jmsdirectory.boughtin.models 
    import jmsdirectory.contacts.models 
    import jmsdirectory.generic.models 
    import jmsdirectory.joinerysoft.models 
    import jmsdirectory.scheduler.models 
    import jmsdirectory.suppliers.models 
    # g = {'__builtins__': False } 
    # try: 
    print "WOOPS" 
    # print g 
    print query_dict 
    class AutoVivification(dict): 
     print "AutoVivification: 1" 
     """Implementation of perl's autovivification feature.""" 
     def __getitem__(self, item): 
      try: 
       return dict.__getitem__(self, item) 
      except KeyError: 
       value = self[item] = type(self)() 
       return value 
    print "AutoVivification: 69" 
    models = AutoVivification() 
    print "AutoVivification: 71" 

    for company in Company.objects.filter(pk="E0433CAE-1756-11E1-A97B-7071BC08AB6F"): 
     print "AutoVivification: 74" 
     for address in Address.objects.filter(company=query_dict['company']).exclude(allow_download=0): 
      print "AutoVivification: 76" 
      for contact in Contact.objects.filter(address=address.uuid).exclude(allow_download=0): 
       print "AutoVivification: 78" 
       for supplier in Supplier.objects.filter(company=query_dict['company']): 
        print "AutoVivification: 80" 
        for supplies in Supplies.objects.filter(supplier=supplier.uuid): 
         print "AutoVivification: 82" 
         models[company][address][contact][supplier] = supplies 
         print "AutoVivification: 84" 
         print models 
    print "Rage!" 
    result = models 
    # exec code in locals() 
    print "MEH!" 
    # except: 
     # print "Error in query set" 
     # print traceback.print_exc() 
     # return False 
    return result 

輸出:

Django version 1.2.7, using settings 'jmsdirectory.settings' 
Development server is running at http://127.0.0.1:8002/ 
Quit the server with CTRL-BREAK. 
[21/May/2012 12:22:18] "POST /transfer/server/ HTTP/1.0" 200 162 
[21/May/2012 12:22:18] "POST /transfer/server/ HTTP/1.0" 200 531 
[21/May/2012 12:22:18] "POST /transfer/server/ HTTP/1.0" 200 162 
1 
2 
3 
4 
5 
6 
7 
8 
9 
WOOPS 
{'company': u'E0433CAE-1756-11E1-A97B-7071BC08AB6F', 'contact': u'E047B1A8-1756-11E1-A97B-7071BC08AB6F', 'address': u'E0452488-1756-11E1-A97B-7071BC08AB6F'} 
AutoVivification: 1 
AutoVivification: 69 
AutoVivification: 71 
[21/May/2012 12:22:18] "POST /transfer/server/ HTTP/1.0" 200 129 

模型公司:

class Company(models.Model): 
    uuid = UUIDField(primary_key=True) 
    name = models.CharField(null=True, blank=True,max_length=255,verbose_name=_('Company Name')) 
    internal_name = models.CharField(null=True, blank=True,max_length=255,verbose_name=_('Internal Name')) 
    reference = models.CharField(null=True, blank=True,max_length=255,verbose_name=_('Reference')) 
    company_status = models.ForeignKey(CompanyStatus, null=True, db_column='company_status_uuid',verbose_name=(_('Company Status')), serialize=False) 
    vat_number = models.CharField(null=True, blank=True,max_length=255,verbose_name=(_('Vat Number'))) 
    registration_number = models.CharField(null=True, blank=True,max_length=255,verbose_name=(_('Company Number'))) 
    discount = models.FloatField(null=True, blank=True) 
    notes = models.TextField(null=True, blank=True,max_length=255) 
    jms_code = models.TextField(null=True, blank=True,max_length=255) 
    logo = models.TextField(null=True, blank=True,max_length=255) 
    date_created = models.DateTimeField(null=True, blank=True, auto_now_add=True,verbose_name=_('Date Time'), serialize=False) 
    date_modified = models.DateTimeField(null=True, blank=True, auto_now=True,verbose_name=_('Date Time Updated'), serialize=False) 
    hidden = models.NullBooleanField(null=True, blank=True,default=0, serialize=False) 
    user = UserField(null=True, blank=True, serialize=False) 
    allow_download = models.NullBooleanField() 
    is_modified = ModifiedField(serialize=False) 
    companyid = models.IntegerField(null=True, blank=True, serialize=False) 
    seqno = models.IntegerField(null=True, blank=True, serialize=False) 

    def __unicode__(self): 
     return self.name 

    def advertiser_uuid(self): 
     uuid = self.uuid 
     today = date.today() 

     from jmsdirectory.advert.models import Advertiser 
     a=Advertiser.objects.filter(company=self,start_date__lte=today,end_date__gte=today) 
     if len(a) > 0: 
      return a[0].uuid 
     else: 
      return '' 

    def advertiser(self): 
     if self.advertiser_uuid() != '': 
      return True 
     else: 
      return False 

    def get_sequence (self) : 

     if self.seqno is None : 
      from django.db.models import Max 
      max = Company.objects.all().aggregate(Max('seqno'))['seqno__max'] 
      if max is None : 
        self.companyid = 1 
      else : self.companyid = max + 1 
      self.seqno = 1 
     else : 
      self.seqno += 1 

     self.save() 
     return self.companyid, self.seqno 

    class Meta: 
     verbose_name_plural = ('Companies') 
     ordering = ('name',) 
     db_table = 'company' 

修正:

def run_code(code, query_dict): 
    code = code.replace('\r\n', '\n') 

    class AutoVivification(dict): 
     """Implementation of perl's autovivification feature.""" 
     def __getitem__(self, item): 
      try: 
       return dict.__getitem__(self, item) 
      except KeyError: 
       value = self[item] = type(self)() 
       return value 

    models = AutoVivification() 


    companies = Company.objects.filter(pk="E0433CAE-1756-11E1-A97B-7071BC08AB6F") 
    addresses = Address.objects.filter(company=query_dict['company']).exclude(allow_download=0) 
    suppliers = Supplier.objects.filter(company=query_dict['company']) 
    for company in companies: 
     for address in addresses: 
      for contact in Contact.objects.filter(address=address.uuid).exclude(allow_download=0): 
       for supplier in suppliers: 
        for supply in Supplies.objects.filter(supplier=supplier.uuid): 
         models[company][address][contact][supplier] = supply 
    result = models 

    return result 
+3

您是否可以進一步縮小范例並仍然重現該問題? –

+0

您確定擁有該PK的公司存在嗎? –

+3

另外請注意,當你確實得到這個工作時,它會**非常低效。 –

回答

1

簡短的回答是 - 它不會崩潰,它不會返回任何內容,因此您正在遍歷空集,因此沒有任何內容被打印出來。

長的答案:

我會盡力幫助你出了一點,但我的第一個建議是,以減少你的問題的基礎。例如,使用defaultdict而不是您的autovivi類。

你也有,我可以看到一些其他的問題,例如:

for address in Address.objects.filter(company=query_dict['company'])

您試圖在絃樂的一個PK篩選,我覺得你的意思是:

for address in Address.objects.filter(company__uuid=query_dict['company'])

由您判斷其他型號,我懷疑您的初始查詢應該是:

for company in Company.objects.filter(uuid="E0433CAE-1756-11E1-A97B-7071BC08AB6F")

同樣,您應該解決您的其他查詢:

contact in Contact.objects.filter(address__uuid=address.uuid)甚至更​​好 contact in Contact.objects.filter(address=address)如果你有適當的FK關係。

但是,即使你這樣做,正如丹尼爾所暗示的,這是非常低效的。您應該利用filter chainingforeign key lookups

+0

哦,但它是崩潰,無論它的方式,至少打印一些東西。即使我不希望它打印它,每一行都有打印語句圍繞它,所以我可以在控制檯中跟蹤執行路徑。另一件事,這是/已經使用了許多外鍵查找。我已經在uuid中努力嘗試縮小故障的位置。 – Jharwood

+0

如果它會崩潰,你已經得到一個例外;它沒有在你的循環中打印任何東西的原因是你正在遍歷一個空集。它相當於'for i in []:print i'',它不會打印任何東西,但它是完全有效的Python。 –

+0

那麼爲什麼不在for循環後面打印行? 'print'Rage!「' – Jharwood