8

Django 単体テストで GenericRelations を使用するにはどうすればよいですか?

私はインターネットで数え切れないほどの提案を読んで試しましたが、役に立ちませんでした。

これは、Django でフィクスチャをロードするときの contenttypes に関する問題を約束していました

しかし、「リセット」コマンドは Django 1.6 にはもうありません。

私のプロジェクトでは、GenericForeign キーを ContentType に使用し、Foreign キーを auth.Users に使用しています。--natural オプションを使用してアプリのデータのみをダンプしましたが、テスト データベースにユーザーが存在しないという問題が発生しました。--natural オプションを削除し、代わりに myApp、auth、contenttypes の 3 つのアプリすべてのデータをダンプしました。テストを実行すると、「contenttypes.ContentType(pk=50) を読み込めませんでした: 列 app_label、モデルが一意ではありません」というメッセージが表示されます。これは、モデルのインポート時に contenttypes が動的に作成されるためだと思います。

使用したコマンド:

python manage.py dumpdata auth myApp contenttypes --natural --indent=4 > auhtmtmnatural.json

次に myApp をダンプし、auth は contenttypes を除外しました。ContentTypes app db は動的に作成され、フィクスチャには自然なキーがあるため、これは機能するはずです。そうではありません。

今私は得ています:

DeserializationError: Problem installing fixture 'auhtmtmnatural.json': ContentType matching query does not exist.

contetypes を使用して fixutres を機能させるにはどうすればよいですか? テストでセットアップを使用してオブジェクトを作成する方が良いですか?

4

3 に答える 3

2

この質問が出されてから 1 年以上経っていることは承知していますが、あなた (または他の誰か) は、ContentType への一般的な外部キーを持つモデルをテストする際にフィクスチャを使用できたことを知りたいと思うかもしれません。ただし、これには注意点があります。テスト フィクスチャで content_type_id をハードコードする必要があり、データベースで ContentType が作成される順序が少し不安定になる可能性があります。(@Laraが言及した理由により、factory_boyでテストを書き直し始めています)

現在、Django 1.8.3、Python 2.7.9 を使用しています。

重要な機能は、フィクスチャをロードする順序のようです。私のtests.pyには次のものがあります:

tests.py:

class MyModelViewTests(TestCase):
    fixtures = [
        'auth_user.json',
        'gfk_model.json',
        'my_model.json',
    ]

    def test_something(self):
        # your tests

上記の gfk_model.json には、ContentType への一般的な外部キーを含むモデルのフィクスチャが含まれています。my_model.json には、Django プロジェクトまたはアプリが必要とするあらゆるモデルのフィクスチャが含まれています。そのため、最初に汎用外部キーを含むモデル インスタンスをインスタンス化します。それらの object_id エントリが、まだ存在していない my_model のデータベース行を参照していることは事実ですが、my_model.json フィクスチャが読み込まれるとすぐに存在します。

MyModel/models.py

class MyModel(models.Model):
    book_title = models.TextField()
    book_isbn = models.CharField(max_length=13)

GFKModel/models.py

class GFKModel(models.Model):
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey()
    your_field = models.TextField()

一般的な外部キーを 1 つの特定の ContentType に関連付ける場合、コンテンツ タイプの ID を SQL データベースから取得するかcontent_type_id = ContentType.objects.get_for_model(MyModel).pk、django シェルで実行します ( python manage.py shell)。次に、こうして取得した ID (私の場合は 13) をフィクスチャにハードコーディングしました (わかりません!)。

最終的にフィクスチャ (ダンプデータから取得して編集) は次のようになります。

gfk_model.json

[
{
    "fields": {
        "your_field": "Stuff you need to associate with my_model",
        "object_id": 1,
        "content_type": 13,
    },
    "model": "myapp.gfk_model",
    "pk": 1
},
{
    "fields": {
        "your_field": "Stuff you need to associate with my_model",
        "object_id": 2,
        "content_type": 13,
    },
    "model": "gfk_app.gfk_model",
    "pk": 2
}
]

my_model.json

[
{
  "pk": 1, 
  "model": "myapp.my_model", 
  "fields": {
    "book_name": "How to bath your cat", 
    "book_isbn": "123456", 
  }
},
{
  "pk": 2, 
  "model": "myapp.my_model", 
  "fields": {
    "book_name": "How About Wednesday?", 
    "book_isbn": "654321", 
  }
}
]

gfk_model.json では、1 と 2 の object_id は、my_model.json の PK 1、2 にそれぞれ対応します。gkf_model インスタンスにも PK を提供しました (おそらく必要ないかもしれませんが、それらを削除しようとはしていません)。

全体として、この記事を書くよりも実際に動作させる方がはるかに速かったです!

また、テスト setUp() で ORM を使用するだけで、GFK テストを機能させるのも非常に簡単です。factory_boy でも問題ありません。

いくつかの異なる ContentTypes があり、特にそれらが contenttypes テーブルの pk を変更する可能性がある場合、フィクスチャはあまり成功しないと思います。

于 2015-08-26T22:54:53.157 に答える
-4

フィクスチャを使用しない理由はいくつかあります。

  • 遅いです
  • 更新/保守が困難です。
  • 練習じゃないですよ~

備品の代わりに、factory boy のような「モック」アプリを使用する必要があります。

http://factoryboy.readthedocs.org/en/latest/

https://pypi.python.org/pypi/factory_boy/

于 2014-07-11T12:07:37.537 に答える