3

私はdjangoに2つのモデルを持っていますが、それらをどのように書くか(抽象モデルと継承など...または2つの異なるモデルを持つかどうか)はわかりませんが、一般的に2つのタイプのオブジェクトAとBがあります.

A と B は単なるアイテムなのでまったく同じです。どちらも次の属性を持っています。

名前、価格

ここで、A と B のすべての類似のアイテムを比較し (類似のアイテムは同じ名前のアイテムです)、それらの間の価格の違いを確認したいと思います (注: 重複はないと仮定しますが、交差点には存在しない可能性のあるアイテムが含まれていると仮定します)。 A または B またはその両方。つまり、A と B は同一のデータ セットではないため、A には 20 個の項目があり、B には 643 個の項目がある可能性があります)

モデルなどを使用してDjangoでこれを行うにはどうすればよいですか...

4

3 に答える 3

2

vendorあなたのコメントから、それらを区別するためのフィールドを備えた単一のモデルのみが必要だと思います

class Product(models.Model):
    VENDOR_CHOICES = (
        ('a', 'Vendor A'),
        ('b', 'Vendor B')
    )
    # you may find it more appropriate to have a ForeignKey to
    # a Vendor model instead of this choice field:
    vendor = models.CharField(max_length=16, choices=VENDOR_CHOICES)
    name = models.CharField(max_length=255)
    price = models.DecimalField(max_digits=6, decimal_places=2)

次に、任意の 2 つのベンダー間の価格差を取得できます (Django 1.8):

from django.db.models import Func, F

prices = (
    Product.objects
    .filter(vendor__in=('a', 'b'))
    .order_by('name', 'vendor')  # order rows within each group
    .values('name')  # GROUP BY `name`
    .annotate(
        first_vendor_price=Func(F('price'), function='FIRST'),
        second_vendor_price=Func(F('price'), function='LAST')
    )
)

price_diffs = {
    group['name']: group['first_vendor_price'] - group['second_vendor_price']
    for group in prices
}
于 2015-04-24T16:08:38.570 に答える
0

抽象クラスを使用して、ポリモーフィックな関係を実装します。Django の ContentType フレームワークを介してクエリを実行します。

Model Aこの解決策は、が とは異なる属性を持っていることを前提としていますModel B。それ以外の場合は、 を持つ単一のモデルChoiceFieldが最も適切です。

Django のポリモーフィズム

    ModelManager(models.Manager):
        def get_intersection_on_name_for(self, name):
            model = Model.objects.filter(model_object__name=name).distinct()
            return model


    Model(models.Model):
        content_type = models.ForeignKey(ContentType, null=True)
        object_id = models.PositiveIntegerField(null=True)
        model_object = generic.GenericForeignKey('content_type', 'object_id') # this gets the actual field obj

        objects = ModelManager()


    ModelBase(models.Model):
        name = models.CharField(max_length=255)
        price = models.CharField(max_length=255)

        class Meta:
            abstract = True

    ModelA(ModelBase):
        weight = models.CharField(max_length=255)


    ModelB(ModelBase):
        url = models.UrlField(max_length=255)

使用中で:

    name = "Test Name"
    Model.objects.get_intersection_on_name_for(name)

参考文献:

ポリモーフィズム: http://en.wikipedia.org/wiki/Polymorphism_(computer_science)

サブタイプ多型: http://en.wikipedia.org/wiki/Subtyping

Django ContentTypes フレームワーク: https://docs.djangoproject.com/en/1.8/ref/contrib/contenttypes/

Django カスタム マネージャー: https://docs.djangoproject.com/en/1.8/topics/db/managers/

Django クエリセット.distinct(): https://docs.djangoproject.com/en/1.8/ref/models/querysets/#django.db.models.query.QuerySet.distinct

django のより強力なポリモーフィズムについては、django-polymorphicをご覧ください。

于 2015-04-24T17:25:42.417 に答える
0

これがまさにあなたが求めているものかどうかはわかりませんが、共有フィールドでクエリを実行するには 2 つの方法が考えられます。

オプション1

まず、モデルの継承を使用して、両方のモデル タイプのオブジェクトを含む 1 つの QuerySet を取得できます。

コード:

class ModelBase(models.Model):
    name = models.CharField(max_length=10)
    price = models.FloatField()

class ModelA(ModelBase):
    field_a = models.BooleanField()

class ModelB(ModelBase):
    field_b = models.BooleanField()

それをテストする:

[4]: test_app.models から ModelA、ModelB、ModelBase をインポート

[5]: マッチ = ModelBase.objects.filter(name='Product1')

[6]: マッチ.カウント()

アウト[6]: 2

[7]: 一致する m の場合:

...: print "%s - %s" % (m.name, m.price)

...:

製品1 - 10.5

製品1 - 3.5

オプション 2

または、継承が不要で、QuerySet 全体を評価することを気にしない場合は、itertools を使用できます。

コード

class ModelX(models.Model):
    name = models.CharField(max_length=10)
    price = models.FloatField()
    field_x = models.BooleanField()

class ModelY(models.Model):
    name = models.CharField(max_length=10)
    price = models.FloatField()
    field_y = models.BooleanField()

テストしてみる

from test_app.models import ModelX, ModelY

itertools インポート チェーンから

full_set = chain(ModelX.objects.filter(name='Product2'), Model.Y.objects.filter(name='Product2'))

[5]: full_set = chain(ModelX.objects.filter(name='Product2'), > ModelY.objects.filter(name='Product2'))

[6]: full_set の m の場合:

...: print "%s - %s" % (m.name, m.price)

...:

製品 2 - 14.0

製品 2 - 30.0

于 2015-04-24T13:40:35.030 に答える