1

他のアプリが Foo アプリからモデル、ビュー、およびテンプレートを「継承」する方法で、他のアプリと連携できる Foo アプリを作成したいと考えています。

設定

一般的なfoo用のDjangoアプリを作成しています。80% の場合、ジェネリックFoo(および関連する) モデルでデータを格納するのに十分であり、残りの 20% の場合、単純な複数テーブルの継承でジェネリック モデルを拡張するのに十分です。ただし、99% の場合、一般的なビューでは十分ではなく、foo のタイプによって、その foo とそれに関連するすべてのモデルの両方に使用するビューが決まります。基本的に、新しいクライアントを取得するたびに新しい foo 型が作成されるため、ビジネス ロジックを別のアプリに保持することが不可欠です [1]。

次のように、すべてのモデルがモデルに関連していることに注意してくださいFoo

from django.db import models
class Foo(models.Model):
  # ... model fields and generic business logic
class Bar(models.Model):
  foo = models.ForeignKey(Foo)
  # ... other model fields and generic business logic
class Baz(models.Model):
  bar = models.ForeignKey(Bar)
  # ... other model fields and generic business logic

提案された解決策

モデルには、そのFoofoo 型に関連付けられたデータと動作を記述するカスタム コードを含むアプリの文字列名が含まれます。そのような各 foo タイプのプラグインは、そのモデルとビュー モジュールにfrom generic-foo.models import *orのような行を持ちますfrom generic-foo.views import *。次に、ジェネリックFooコードに次のコードを含めます。

import sys
import importlib
from django.db import models
from myproject import settings
class Foo(models.Model):
  FOO_APPS = [(app_name, app_name) for app_name in
              settings.INSTALLED_APPS if 'foo' in app_name]
  app_name = models.CharField(max_length=256, choices=FOO_APPS)
  # ... other model fields and generic business logic
  def get_app(self):
    "Return the app from which to get the right models or views for this object."
    return importlib.import_module(self.app_name)

次に、インスタンス (またはサブクラスのインスタンス)gvを使用するジェネリック ビューは、最初に を呼び出し、次に を呼び出します。クラスベースのビューは、残りの作業を処理できます。(いずれにせよ、サブアプリによってビューが提供されるのが一般的なケースであることを思い出してください。) アスタリスクのインポートにより、 query を実行してテーブルから子(または関連するモデル) を検索できます。FooFooobjapp = obj.get_app()app.views.gv()FooContentTypeContentType.objects.get(app=obj.app_name, model=obj.__type__.__name__)

質問

私はこれを難しい方法でやっていますか?(また、私が見ていないここにセキュリティ ホールはありますか?)

関連する質問

[1] 他のクライアントのコードを明らかにすることなく、クライアントとコードを共有できる必要があります。

4

0 に答える 0