-1

Djangoには、次のmodels.pyがあります

class Product(RandomPrimaryIdModel):
  feature1 = models.CharField(max_length=20, blank=True, null=True)
  feature2 = models.CharField(max_length=20, blank=True, null=True)
  feature3 = models.CharField(max_length=20, blank=True, null=True)

class Mattress(Product):
  category_type = models.CharField(max_length=50)
  size = models.CharField(max_length=5)

  def category(self):
    return "bedding"
  category = property(category)

次のviews.pyファイルがあります

def update(request, id):
  product = Product.objects.get(id=id)
  ...

このメソッド update では、「Mattress」モデルで定義されたメソッドを Product モデルから呼び出すことができますか。たとえば、次のように記述します。 if product.type == "mattress" ここで、type は Mattress モデルで定義されており、Mattress は Product のサブモデルです。

4

2 に答える 2

3

あなたの例は、あなたが行くことができる2つの異なる方法の間にあるようですが、現在は正しくありません。Product と Mattress という 2 つのテーブルを作成していますが、これらはまったく関係がありません。Mattress が Product のサブクラスであるにもかかわらず、その構造を継承しているだけです。マットレスはマットレス テーブルにあるため、マットレスについて Product テーブルでクエリを実行することはできません。

1 つの方法は、Product を単に抽象化し、実際の製品によってサブクラス化されると見なすことです。

class Product(RandomPrimaryIdModel):
    class Meta:
        abstract=True

これにより、Product テーブルが作成されなくなります。次に、次の方法でマットレスを直接クエリします。Mattress.objects.filter()

しかし、これは、多くの種類の製品を導入し、それらのために異なるテーブルを管理する必要があるという点で、少し制限があるようです. もう 1 つの方法は、Product テーブルを使用することですが、ジェネリック リレーションを使用して、他のタイプのテーブルをコンテンツ オブジェクトとしてアタッチすることをサポートします。

from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic

class Product(RandomPrimaryIdModel):

    feature1 = models.CharField(max_length=20, blank=True, null=True)
    feature2 = models.CharField(max_length=20, blank=True, null=True)
    feature3 = models.CharField(max_length=20, blank=True, null=True)

    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

content_objectこれにより、 をMattress インスタンスに設定できるようになります。その後、ContentType を使用してクエリを実行できます。

p_type = ContentType.objects.get(name="mattress")
Product.objects.filter(content_type=p_type)
于 2012-08-10T00:35:27.950 に答える
0

これは自動ダウンキャストの場合のように見えます。一般的な「ProductBase」インスタンスを保持するショッピングカートにも同様のアプローチが必要でしたが、ProductDownloadable、ProductShippedなどの実際の製品である子の特定の機能にアクセスする必要がありました。

Djangoはこれをネイティブにサポートしていませんが、イントロスペクションを介してコーディングするか、django-model-utilsを使用して、インストールすると次のことができます。

# return a list 'child' classes of Product - in your case Mattresses
mattress_list = Product.objects.all().select_subclasses() 

# return the direct 'child' class of Product - in your case Mattress class
mattress = Product.get_subclass(id=some_id) # returns the 'child' subclass
mattress.foo() # executes method on foo on Mattress class (not on Product class)
于 2012-08-10T04:22:45.083 に答える