1

新しい関連フィールド タイプを作成したいと思います。簡単な例を次に示します。

class CustomQuerySet(QuerySet):
    def current(self):
        return self.filter(invalid_date__isnull=True)

class CustomManager(Manager):
    def get_query_set(self):
        return CustomQuerySet(self.model, using=self._db)
    def current(self):
        return self.get_query_set().current()

class Item(models.Model):
    objects = CustomManager()

    row_id = models.IntegerField(primary_key=True)
    id = models.IntegerField()
    name = models.CharField(max_length=100)
    change_date = models.DateTimeField(auto_now_add=True)
    invalid_date = models.DateTimeField(null=True, blank=True)


class Collection(models.Model):
    item = MultipleRelatedField(Item, related_field='id', related_name='collections')
    name = models.CharField(max_length=100)

与えられたc = Collection()

  • c.itemに相当するクエリセットを返す必要がありItem.objects.filter(id=c.item_id)ます。
  • そのクエリセットは CustomQuerySet のインスタンスである必要があります
  • Item.objects.filter(collections__name='SomeName')期待どおりに動作するはずです。
  • 操作Collection.objects.filter(item__name='OtherName', item__invalid_date__isnull=True)は期待どおりに機能するはずです。

これはaで実装できることはわかっManyToManyFieldていますが、アイテムオブジェクトをc.itemに手動で追加/削除したくありません。c.item は常に単一の id 値を使用するため、結合テーブルは必要ありません。コレクションの主キーではないだけです。またc.item、異なる ID 値を持つアイテム オブジェクトを含む/含まない場合があります。

これには、サブクラス化django.db.models.fields.related.ForeignRelatedObjectsDescriptorおよび/またはdjango.db.models.fields.related.ForeignObject(または、場合によっては ManyToMany に相当するもの) が必要になる可能性が高いことを認識しています。

4

1 に答える 1

1

あなたが本当に望んでいるのは、 のフィールドの値に基づいて、モデルからA別のモデルに対してクエリセットを自動的に生成する方法であるように思えます。BA

最終的に、そのクエリセットをフィールドの値として返すことは、A実際には最善の解決策ではないのではないかと思います。これは、ORM の粒度に実際に反し、たとえば、そのモデルを管理者またはその他の一般的な場所。

代わりに、Django が set を使用してフィールドをどのように処理するかを理解することをお勧めしchoicesます。モデルにフィールドがある場合は、派生情報を返すモデル クラスでメソッドを自動的に生成します。

item = MultipleRelatedField(Item, related_field='id', related_name='collections')

指定したクエリセットを返すようなメソッドが自動的に取得get_item_querysetされます。

それを構築するには、既存のフィールドをサブクラス化し (IntegerFieldおそらく出発点としてはよいでしょう)、__init__メソッド (追加の引数を受け入れるため) とcontribute_to_classメソッド (新しいメソッドが生成される場所) をオーバーライドします。インスピレーションを得るため、choices派生get_FIELD_displayメソッドでこれが発生する場所をここで確認できます。

于 2014-02-14T20:28:25.433 に答える