3

Django内のキャッシュの問題に苦労しています。これまでのところ、この問題はtestsuiteを実行しているときにのみ発生しました。問題は、時々(これはコードの2回目の呼び出しで常に発生するようです)、Djangoがキャッシュを更新しないか、一貫性がなくなることです。

いくつかのデバッグで抽出されたコードは次のとおりです。

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>]

ただし、への2回目の呼び出しでauto_create、Djangoは参照が1つあると考えていますが、それは私にはわかりません。

0 []
1 []

もちろん、この動作はそれ以上のコードを壊します。ここで何がうまくいかないのか、少なくともそれをデバッグする方法はありますか?

PS:クラスでの注文Referenceがこれを引き起こしているようです。しかし、その理由はまだはっきりしていません。

4

2 に答える 2

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)
于 2012-12-10T23:54:40.983 に答える
0

最後に、この問題の原因を突き止めました。これは、Django のものではなく、私自身のキャッシング コードでした。

カスタム ソース マネージャーを配置し、標準ソースを返してキャッシュしました。

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、下にある JOIN SELECT が一致するSourceオブジェクトを見つけることができなかったため、並べ替え中にエラーが後で表示されたことです。

于 2012-12-11T08:11:46.237 に答える