2016-05-06 6 views
10

私たちはDjango 1.9アプリで使用するサードパーティのlibを持っています。私たちは元のアプリケーションにないいくつかの機能(MongoDBを対象とする)でそのアプリケーションを修正したいと思います。現在のところ、元のlibのフォークを使用してこれを行いますが、最終的にアップストリームに引き込まれるように、変更を少し直交させたいと考えています。Monkeyは別のアプリにDjangoアプリをパッチします

私たちは、アプリconfig ready()中にパッチを適用しようとしましたが、モデルの輸入がdjango.apps.registry.populate()にこの呼び出しの前に処理され、そしてapps_ready == Falseから\__init__被るでそれを実行します。これを実行するライフサイクルの最善の部分は何ですか?

class MongoConfig(AppConfig): 
    def __init__(self, app_name, app_module): 
     super(MongoConfig, self).__init__(app_name, app_module) 

     for p in patches: 
      patch(*p) 

def patch(old, new): 
    old_module, old_item = split_mod(old) 
    new_module, new_item = split_mod(new) 

    print('patching {0} with {1}'.format(old, new)) 

    old_module = import_module(old_module) 
    new_module = import_module(new_module) 
    setattr(old_module, old_item, getattr(new_module, new_item)) 
+2

私はパッチの両方で '__init __。実装のアプリと' AppConfig.ready'コールバックでpy'てきました。私は誰かがあなたに純粋な推測ではない答えをどのように与えることができないのか分かりません。何がうまくいくのかは、あなたの質問に与えていない詳細に依存します。 – Louis

+0

既存のアプリケーション(django-allauth)をMongoDBで使用するように変更しています。これには、元のライブラリと直交するようにしているモデル、ビュー、およびフォームの変更が必要です。他にどんな情報がありますか? – mwjackson

答えて

-1

モンキーパッチは、ハックであり、維持しにくいので避けるべきです。

原則として、Django自体が読み込まれる前にコードをインポートする前にパッチを適用することが原則です。エントリポイントに応じて、コードを修正する適切な場所を見つけることができます。

私は約2エントリポイントと考えることができますDjangoの1.9を使用する:

  1. wsgi.pyを - あなたのコードはmanage.py
  2. WSGIコンテナ上で実行されている間 - ながら、任意の管理コマンド(シェル、runserver、migrate)が実行されています。
1

私は本当に猿のパッチはありません(テストケースを除いて、私はモックが良いと信じています)。

もっと簡単なオプションをお試しください。あなたのプロジェクト(これはPythonのルックアップシステムのために最初に呼び出される)内のアプリケーションのプロキシを作成し、単純にあなたが望むメソッドにパッチを当て、元のアプリケーションにないメソッドをバイパスします。

ように、コンポーネントが「FooProject」と呼ばれている場合は、このアプリの__init__.pyで、プロジェクト内の「FooProject」と呼ばれる別のアプリを作成します。

from originalproject import FooProject as OriginalFoo 

class FooProject(OriginalFoo): 
    def override_method_here(self, foo): 
     return my_own_magic(foo) 
+0

私は質問にコメントしたときにこの可能性について言及するのを忘れました。私は['cmsplugin-iframe'](https://github.com/satyrius/cmsplugin-iframe/issues/5)の制限を回避するためにこれを使用しました。この方法は、猿のパッチ適用よりも好ましいが、a)猿のパッチのみが機能するか、またはb)猿のパッチを適用すると、*もっと簡単な解決策が可能になる場合がある。私は、インストールされたアプリケーションごとに1つのプロキシを作成しなければならない場合がありました.20以上のプロキシです。 OPは、特定の問題を解決するために何が最善のものかを知る手段を私たちに与えていない。 – Louis

+0

私たちが修正しようとしているアプリはかなり大きいです(django-allauth)。私が何かを見逃していない限り、このアプローチは、モデル、フォーム、ビューにパッチを当てる必要があるという事実によって、実際には実現可能ではありません。 – mwjackson

0

を私は猿に似必要がdjango-allauth/django-invitationアダプタにパッチを適用ました同じ制限につまずいた(apps_ready == False)。

私は部分的に何を言及し、manage.pyを編集し、修正する必要があったアダプタを部分的に書き換えて必要な動作を追加する方法を挿入しました。 がロードされて、django-invitationsがロードされるまで、その方法は既に書き換えられていた。

シンプルで汚れていて、おそらくお勧めしない検索&は、ライブラリ構造に属するファイル.pyを書き換えたメソッドを置き換えます。

将来のバージョンとの互換性があると思われますが、それはバグや問題の原因と認めます。

乾杯

関連する問題