2016-09-26 6 views
1

私が作成したアプリケーションを再利用できるように変更しようとしています。これは、アプリケーションを使用するサイトがサブクラス化する単一のモデルに基づいています。再利用できないバージョンは、次のような構造をしています。Djangoの基本クラスを使うには

# models.py 
class Document(models.Model): 
    contents = models.TextField() 
    date = models.DateTimeField() 

# views.py 
from .models import SiteModel 
# ... 
class MyView(ListView): 
    def some_method(self, list_of_pks): 
     model_vals = Document.objects.filter(pk__in = list_of_pks).values() 

def perform_action(request): 
    obj_pk = request.POST.get('obj_pk') 
    obj = Document.objects.filter(pk = obj_pk) 

    MySignal.send(sender=Document, instance = obj) 

#etc, etc 

これは十分です。しかし、私のユースケースでは、サイトごとに1つずつ異なるタイプのDocumentが必要です。これには、事前にわかっていない追加フィールドがあります。私は理解していない何

# models.py for the app 
class BaseDocument(models.Model): 
    contents = models.TextField() 

    class Meta: 
     abstract = True 

# models.py for a hypothetical site using the app 
class SiteDocument(myapp.BaseDocument): 
    date = models.DateTimeField() 
    # other site-specific fields 

はその後、アプリのviews.pyforms.py、など私がBaseDocument.objects.all()を知っているモデルを参照する方法である:abstract base classes上のドキュメントを読むに基づいて、私は合理的な解決策がどのように見えるだろうと思いましたたとえば、データベースに接続されていないため何も返されません。逆にDocumentはまだ作成されておらず、各サイトに固有のものであるため、Document.objects.all()を持つことはできません。抽象基本クラスは正しい解決法ではないか、もしそうであれば、それは何ですか?

編集:それはスーパークラスからメソッドを継承排除し、そのBaseDocument.objects.all()は、そのすべての子を一覧表示しませんように見えるが、それは、私のユースケースに最適かもしれOneToOneFieldを使用してのように見えます

のスタイルで、抽象基本クラスにget_document_model()メソッドを追加することができますか?

答えて

0

をご覧ください。私の編集は、に触発されたget_document_model()メソッドの作成です。これは、私に希望の振る舞いを正確に与えます。

# models.py in app1 
from django.db import models 
from django.apps import apps as django_apps 

class BaseDocument(models.Model): 
    contents = models.TextField() 

    class Meta: 
     abstract = True 

    def get_document_model(): 
     # exception handling removed for concision's sake 
     return django_apps.get_model(settings.DOCUMENT_MODEL) 

# models.py in app2 
from django.db import models 
from app1.models import BaseDocument 

class SiteDocument(BaseDocument): 
    date = models.DateTimeField() 
views.pyを通じて

と他の場所では、私はBaseDocument().get_document_model().objects.all()にフォームDocument.objects.all()であったであろう事を変更しました。

0

あなたは抽象クラスを直接クエリすることはできません。マネージャには継承されたクラスだけがありません。継承を本当に行う必要がある場合は、具体的な基底モデルを使用し、それをすべてのクエリの結合の代償で継承できます。

これが本当に必要かどうか、より一般的な方法でデータを表現できるかどうかを考えてください。モデルは継承を簡単に見せるが、魔法ではない。非常に実際的なパフォーマンスと複雑さの考慮事項があります。

それは、あなたのモデルに具象クラスと照会対抽象化の詳細については

class Document(models.Model): 
    DOCUMENT_TYPES = ['site', 'another', 'whatever'] 

    document_type = models.CharField(choices=DOCUMENT_TYPES) 
    ... 

typeフィールドを追加するのと同じくらい簡単かもしれない私が言及した解決策と一緒に行くことになったHow to query abstract-class-based objects in Django?

+0

私は特に継承や抽象基底クラスにコミットしていませんが、私はちょうど適切な解決策であるという印象を受けていました。これはXYの問題かもしれませんが、私はユースケースを明確にすることに失敗しています。アプリを使用しているサイトでは、1つの「ドキュメント」しか使用されませんが、そのフィールドは事前にわかりません。私の質問は次のように言い換えることができると思います:特定のサイトがサブクラス化してそのモデルを拡張することを知って、どのように私のアプリでモデルを参照するのですか? – HoHo

+0

私は 'BaseDocument'を具体的にする必要がないことを知っています。そうすれば結合は不要です。ForeignKeyを使用して子を参照できますか?' views'では 'BaseDocument.doc_child.objects.all () '? – HoHo

+0

ドキュメントは実際の階層にありますか、疑似継承を行う方法を探しているだけですか?あなたが本当にそれを正当化することができない限り、あなたはおそらく継承を全く必要としません。 – Soviut

関連する問題