0

テスト中にこれが見つかりました。1 台のマシンはデフォルト エンジンとして MyISAM を使用してセットアップされ、もう 1 台はデフォルト エンジンとして InnoDB を使用してセットアップされました。次のようなコードがあります

class StudyManager(models.Manager):
    def scored(self, school=None, student=None):
        qset = self.objects.all()
        if school:
            qset = qset.filter(school=school)
        if student:
            qset = qset.filter(student=student)
        return qset.order_by('something')

問題のコードは次のようになります。

print Study.objects.scored(student).count()

つまり、「学生」は学校として扱われていました。これは、MyISAM がロールバックを実行できず、テストごとに完全に再作成されるため (autoincrement id フィールドをリセットする)、student.id == school.id であるため、MyISAM でのテストを通じて得られました。ロールバックは明らかに自動インクリメント フィールドをリセットしないため、InnoDB はこれらのエラーを検出しました。

id問題は、テスト中に、すべてのモデルにフィールドがあるため、ダックタイピングが原因で他の多くのエラーが検出されない可能性があることです。オブジェクトのIDが(本番またはテストで)並んでいることと、それが問題を引き起こしている/バグを見つけられないことが心配です。

次のようにアサートを追加できます。

class StudyManager(models.Manager):
    def scored(self, school=None, student=None):
        qset = self.objects.all()
        if school:
            assert(isinstance(school, School))
            qset = qset.filter(school=school)
        if student:
            assert(isinstance(student, Student))
            qset = qset.filter(student=student)
        return qset.order_by('something')

しかし、これは見栄えが悪く、大変な作業です (元に戻して改造する必要があります)。デバッグモードでも遅くなります。

モデルの id フィールドを強制的に model_id (学生の場合は学生 ID、学校の場合は school_id)、学校が学生 ID を持たないようにするというアイデアについて考えました。これには主キー フィールドの指定のみが含まれますが、ジャンゴには.pk のショートカットなので、すべての場合に役立つとは限りません。

この種のバグをキャッチするためのよりエレガントなソリューションはありますか? C++ の経験が長いので、タイプ セーフが恋しいです。

4

1 に答える 1

0

これは Python の特徴であり、Django自体とは何の関係もありません。

関数パラメーターのデフォルト値を定義しても、位置引数の概念がなくなるわけではありません。関数を呼び出すときにすべてのパラメーターを指定しなくても済むようにするだけです。@mVChr は、ルーチンを呼び出すときにパラメーター名を使用する習慣を身に付ける必要があると言っているのは正しいです。特に、呼び出し元に固有のあいまいさがある場合はそうです。

また、quiet という名前が期待されるパラメーターの型を明確に識別する 2 つの別個のルーチンを用意することも検討してください。

于 2013-01-26T00:58:14.623 に答える