Djangoモデルを今定義していますが、モデルフィールドタイプにOneToManyField
がないことに気付きました。これを行う方法があると確信しているので、何が欠けているのかわかりません。私は本質的に次のようなものを持っています:
class Dude(models.Model):
numbers = models.OneToManyField('PhoneNumber')
class PhoneNumber(models.Model):
number = models.CharField()
この場合、各Dude
は複数のPhoneNumber
を持つことができますが、PhoneNumber
を所有する多くの異なるオブジェクトがあるため、Dude
からそれを所有しているPhoneNumber
を知る必要がないため、関係は単方向でなければなりません。たとえば、Business
など:
class Business(models.Model):
numbers = models.OneToManyField('PhoneNumber')
このような関係を表すために、モデル内でOneToManyField
(存在しない)を置き換えるものは何ですか?私はHibernate/JPAから来ています。ここでは、1対多の関係を宣言するのは簡単でした。
@OneToMany
private List<PhoneNumber> phoneNumbers;
Djangoでこれをどのように表現できますか?
Djangoで1対多の関係を処理するには、ForeignKey
を使用する必要があります。
ForeignKeyのドキュメントは非常に包括的であり、あなたが持っているすべての質問に答えるべきです。
https://docs.djangoproject.com/en/dev/ref/models/fields/#foreignkey
この例の現在の構造では、各Dudeに1つの番号を割り当て、各番号を複数のDudesに属させることができます(Businessと同じ)。
逆の関係が必要な場合は、2つのForeignKeyフィールドをPhoneNumberモデルに追加する必要があります(1つはDudeに、もう1つはBusinessに)。これにより、各番号が1つのDudeまたは1つのBusinessに属し、DudeとBusinessesが複数のNumberを所有できるようになります。これはあなたが望んでいることだと思います。
class Business(models.Model):
...
class Dude(models.Model):
...
class PhoneNumber(models.Model):
dude = models.ForeignKey(Dude)
business = models.ForeignKey(Business)
Djangoでは、1対多の関係はForeignKeyと呼ばれます。ただし、一方向にしか機能しないため、クラスnumber
のDude
属性を使用するのではなく、
class Dude(models.Model):
...
class PhoneNumber(models.Model):
dude = models.ForeignKey(Dude)
多くのモデルは、他の1つのモデルに対してForeignKey
を持つことができるため、次のようなPhoneNumber
の2番目の属性を持つことが有効です
class Business(models.Model):
...
class Dude(models.Model):
...
class PhoneNumber(models.Model):
dude = models.ForeignKey(Dude)
business = models.ForeignKey(Business)
d.phonenumber_set.objects.all()
を使用してPhoneNumber
オブジェクトDude
のd
sにアクセスし、Business
オブジェクトに対して同様にアクセスできます。
OneToMany
関係の多くの側で外部キー(つまり、ManyToOne
関係)を使用するか、一意の制約でManyToMany
(任意の側で)を使用できます。
より明確にするために-DjangoにはOneToManyはなく、ManyToOneだけがあります-これは上記のForeignkeyです。 Foreignkeyを使用してOneToMany関係を記述できますが、それは非常に表現力に欠けています。
それに関する良い記事: https://amir.rachum.com/blog/2013/06/15/a-case-for-a-onetomany-relationship-in-Django/
Django
は十分にスマートです。実際、oneToMany
フィールドを定義する必要はありません。 Django
によって自動的に生成されます:-)。関連するテーブルでforeignKey
を定義するだけです。言い換えると、ManyToOne
を使用してforeignKey
関係を定義するだけです。
class Car(models.Model):
// wheels = models.oneToMany() to get wheels of this car [**it is not required to define**].
class Wheel(models.Model):
car = models.ForeignKey(Car, on_delete=models.CASCADE)
特定の車の車輪のリストを取得したい場合。 python's
自動生成オブジェクトwheel_set
を使用します。車c
には、c.wheel_set.all()
を使用します
「多くの」モデルがモデル自体の作成を正当化しない場合(ここではそうではありませんが、他の人に利益をもたらす可能性があります)、別の選択肢は Django Contribパッケージ
Postgresは Array または JSON のデータ型を処理できますが、これはmany -iesは、oneの単一のエンティティにのみ関連付けることができます。
Postgresでは、配列の単一の要素にアクセスできます。つまり、クエリは非常に高速であり、アプリケーションレベルのオーバーヘッドを回避できます。そしてもちろん、 DjangoはクールなAPIを実装しています この機能を活用します。
明らかに、他のデータベースバックエンドに移植できないという欠点がありますが、まだ言及する価値はあります。
アイデアを探している人の助けになることを願っています。
ローリングストーン の答えは優れており、簡単で機能的ですが、解決されないことが2つあると思います。
コンテンツタイプフレームワーク を導入します。これにより、PhoneNumberモデルで「汎用外部キー」を作成できるオブジェクトが公開されます。次に、DudeとBusinessの逆の関係を定義できます
from Django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from Django.contrib.contenttypes.models import ContentType
from Django.db import models
class PhoneNumber(models.Model):
number = models.CharField()
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
owner = GenericForeignKey()
class Dude(models.Model):
numbers = GenericRelation(PhoneNumber)
class Business(models.Model):
numbers = GenericRelation(PhoneNumber)
詳細については docs を参照してください。簡単なチュートリアルについては この記事 をご覧ください。
また、こちらは 記事 Generic FKの使用をagainstと主張しています。