2012-12-07 2 views
3

Django에서 캐싱 문제로 고심하고 있습니다. 지금까지 나는 testsuite를 실행할 때만이 문제를 보았습니다. 문제는 때로는 (이것은 코드의 두 번째 호출에서 항상 발생하는 것 같습니다) 장고는 캐시를 업데이트하지 않거나 일관성이 없어집니다.Django의 ManyToManyField에서 캐싱

디버깅과 추출 된 코드이다 : I가 정확하게 다음 출력을 얻는 제 호출에

class Source(models.Model): 
    name = models.CharField(max_length = 50) 
    quality = models.IntegerField(default = 0) 

class Reference(models.Model): 
    url = models.URLField() 
    source = models.ForeignKey(Source) 

    class Meta: 
     ordering = ['-source__quality'] 

class Issue(models.Model): 
    references = models.ManyToManyField(Reference) 
    master = models.ForeignKey(Reference, related_name = 'mastered_issue_set') 

def auto_create(instance): 
    issue = Issue.objects.create(master = instance) 
    print issue.references.count(), issue.references.all() 
    issue.references.add(instance) 
    print issue.references.count(), issue.references.all() 

:

0 [] 
1 [<Reference: test>] 

그러나 auto_create에 두 번째 호출 장고 한 참조가 생각

, 하지만 그것은 내게주지 않습니다 :

0 [] 
1 [] 

이 동작으로 인해 추가 코드가 분리됩니다. 어떤 아이디어가 여기에 잘못 될 수 있거나 적어도 디버깅하는 방법은 무엇입니까?

추신 : Reference 클래스에서 주문한 것으로 보이는 것 같습니다. 그러나 아직도 나에게 불분명하다.

+0

'auto_create()'에 대한 인수를 지정할 수 있습니까? – Oleksiy

+0

"참조"인스턴스 (새로 생성됨)입니다. –

답변

0

결국이 문제의 원인을 발견했습니다. 그것은 장고보다 내 자신의 캐싱 코드였습니다. 좀 표준 소스 반환 및 캐시 된 장소에서 사용자 정의 소스 관리자했다

:이 응용 프로그램에 완벽하게 잘 작동

class SourceManager(models.Manager): 
    url_source = None 
    def get_generic(self): 
     if self.url_source is None: 
      self.url_source, created = self.get_or_create(name = 'URL', quality = 0) 
     return self.url_source 

class Source(models.Model): 
    name = models.CharField(max_length = 50) 
    quality = models.IntegerField(default = 0) 

    objects = SourceManager() 

는 - 소스가 작성되면이 소스와 같은 존재가의를 들어, 관리자는 그것을 기억 평생 동안 바뀌지 마라. 그러나 테스트에서 전체 테스트가 단일 트랜잭션으로 실행 된 후 되돌아갑니다.

는 내가 이상한 찾으 models.ForeignKey가 아닌 기존 개체를 얻기에 대해 불평하지 않았다,하지만 오류가 기저의 같은 source__quality에 의해 정렬하는 동안, 나중에 나타난 SELECT가 Source 개체를 일치 찾을 수 없습니다 가입하세요.

0

sqlite3으로 재생할 수 없습니다. Reference의 인스턴스가 전달 된 것일 수 있습니까? 다음은 딸꾹질없이 달렸습니다 :

def auto_create(instance): 
    issue = Issue.objects.create(master = instance) 
    print issue.references.count(), issue.references.all() 
    assert issue.references.count()==0, "initial ref count is not null" 
    assert len(issue.references.all())==0, "initial ref array is not empty" 
    issue.references.add(instance) 
    print issue.references.count(), issue.references.all() 
    assert issue.references.count()==1, "ref count is not incremented" 
    assert len(issue.references.all())==1, "initial ref array is not populated" 


def test_auto(): 
    s = Source() 
    s.save() 
    r = Reference(source=s) 
    r.save() 
    auto_create(r) 
+0

참조가 저장되지 않으면''issue.references.add (...)'는 실패했을 것입니다. 그리고 실제로 추출 된 코드는 문제를 드러내지 않습니다. 전체 프로젝트를 게시 할 수 없습니다. 너무 거대합니다. 나는 코드에서 잘못 될 수있는 포인터를 찾고있다. 실제 응용 프로그램에서는 SQLite 및 PostgreSQL 백엔드에서 이러한 문제를 재현 할 수 있습니다. –