Berhati-hatilah untuk menyadari bahwa ada beberapa perbedaan antara OneToOneField(SomeModel)
dan ForeignKey(SomeModel, unique=True)
. Sebagaimana dinyatakan dalam The Definitive Guide to Django :
OneToOneField
Hubungan satu-ke-satu. Secara konseptual, ini mirip dengan ForeignKey
dengan unique=True
, tetapi sisi "terbalik" dari relasi akan langsung mengembalikan satu objek.
Berbeda dengan OneToOneField
relasi "mundur", relasi ForeignKey
"terbalik" mengembalikan a QuerySet
.
Contoh
Misalnya, jika kita memiliki dua model berikut (kode model lengkap di bawah):
Car
menggunakan model OneToOneField(Engine)
Car2
menggunakan model ForeignKey(Engine2, unique=True)
Dari dalam python manage.py shell
jalankan yang berikut:
OneToOneField
Contoh
>>> from testapp.models import Car, Engine
>>> c = Car.objects.get(name='Audi')
>>> e = Engine.objects.get(name='Diesel')
>>> e.car
<Car: Audi>
ForeignKey
dengan unique=True
Contoh
>>> from testapp.models import Car2, Engine2
>>> c2 = Car2.objects.get(name='Mazda')
>>> e2 = Engine2.objects.get(name='Wankel')
>>> e2.car2_set.all()
[<Car2: Mazda>]
Kode model
from django.db import models
class Engine(models.Model):
name = models.CharField(max_length=25)
def __unicode__(self):
return self.name
class Car(models.Model):
name = models.CharField(max_length=25)
engine = models.OneToOneField(Engine)
def __unicode__(self):
return self.name
class Engine2(models.Model):
name = models.CharField(max_length=25)
def __unicode__(self):
return self.name
class Car2(models.Model):
name = models.CharField(max_length=25)
engine = models.ForeignKey(Engine2, unique=True, on_delete=models.CASCADE)
def __unicode__(self):
return self.name
e.car
juga berfungsi?ForeignKey
denganunique=True
bukanOneToOneField
? Saya melihat dalam pertanyaan-pertanyaan lain bahwa Django bahkan memperingatkan bahwaOneToOneField
kepentingan yang biasanya terbaik adalah kepentingan seseorang. KebalikannyaQuerySet
tidak akan pernah memiliki lebih dari satu elemen, kan?ForeignKey adalah untuk satu-ke-banyak, jadi objek Mobil mungkin memiliki banyak Roda, setiap Roda memiliki ForeignKey untuk Mobil miliknya. OneToOneField akan seperti Engine, di mana objek Mobil dapat memiliki satu dan hanya satu.
sumber
Cara terbaik dan paling efektif untuk mempelajari hal-hal baru adalah dengan melihat dan mempelajari contoh-contoh praktis dunia nyata. Misalkan sesaat Anda ingin membangun blog di Django di mana wartawan dapat menulis dan menerbitkan artikel berita. Pemilik surat kabar online ingin mengizinkan masing-masing reporternya menerbitkan sebanyak mungkin artikel yang mereka inginkan, tetapi tidak ingin reporter yang berbeda mengerjakan artikel yang sama. Ini berarti bahwa ketika pembaca pergi dan membaca artikel mereka hanya akan melihat satu penulis dalam artikel tersebut.
Misalnya: Artikel oleh John, Artikel oleh Harry, Artikel oleh Rick. Anda tidak dapat memiliki Artikel oleh Harry & Rick karena bos tidak ingin dua atau lebih penulis mengerjakan artikel yang sama.
Bagaimana kita bisa memecahkan 'masalah' ini dengan bantuan Django? Kunci untuk pemecahan masalah ini adalah Django
ForeignKey
.Berikut ini adalah kode lengkap yang dapat digunakan untuk menerapkan gagasan bos kami.
Jalankan
python manage.py syncdb
untuk mengeksekusi kode sql dan membangun tabel untuk aplikasi Anda di database Anda. Kemudian gunakanpython manage.py shell
untuk membuka shell python.Buat objek Reporter R1.
Buat objek Artikel A1.
Kemudian gunakan potongan kode berikut untuk mendapatkan nama reporter.
Sekarang buat objek Reporter R2 dengan menjalankan kode python berikut.
Sekarang coba tambahkan R2 ke objek Artikel A1.
Itu tidak bekerja dan Anda akan mendapatkan sebuah AttributeError yang mengatakan objek 'Reporter' tidak memiliki atribut 'tambah'.
Seperti yang Anda lihat objek Artikel tidak dapat dikaitkan dengan lebih dari satu objek Reporter.
Bagaimana dengan R1? Bisakah kita melampirkan lebih dari satu artikel objek ke dalamnya?
Contoh praktis ini menunjukkan kepada kita bahwa Django
ForeignKey
digunakan untuk mendefinisikan banyak-ke-satu hubungan.OneToOneField
digunakan untuk membuat hubungan satu-ke-satu.Kita dapat menggunakan
reporter = models.OneToOneField(Reporter)
dalam file models.py di atas tetapi itu tidak akan berguna dalam contoh kita sebagai penulis tidak akan dapat memposting lebih dari satu artikel.Setiap kali Anda ingin memposting artikel baru, Anda harus membuat objek Reporter baru. Ini menghabiskan waktu, bukan?
Saya sangat merekomendasikan untuk mencoba contohnya dengan
OneToOneField
dan sadari perbedaannya. Saya cukup yakin bahwa setelah contoh ini Anda akan sepenuhnya mengetahui perbedaan antara DjangoOneToOneField
dan DjangoForeignKey
.sumber
OneToOneField (satu-ke-satu) menyadari, dalam orientasi objek, gagasan komposisi, sementara ForeignKey (satu-ke-banyak) berkaitan dengan persetujuan.
sumber
Patient
danOrgan
.Patient
dapat memiliki banyakOrgan
s, tetapiOrgan
kaleng hanya milik satuPatient
. KetikaPatient
dihapus, semuaOrgan
juga dihapus. Mereka tidak bisa eksis tanpa aPatient
.Juga
OneToOneField
berguna untuk digunakan sebagai kunci utama untuk menghindari duplikasi kunci. Seseorang mungkin tidak memiliki autofield implisit / eksplisittetapi gunakan
OneToOneField
sebagai kunci utama sebagai gantinya (bayangkanUserProfile
model misalnya):sumber
Ketika Anda mengakses OneToOneField Anda mendapatkan nilai dari bidang yang Anda tanyakan. Dalam contoh ini, bidang 'judul' model buku adalah OneToOneField:
Saat Anda mengakses ForeignKey, Anda mendapatkan objek model terkait, yang kemudian dapat Anda buat sebelumnya. Dalam contoh ini, bidang 'penerbit' model buku yang sama adalah ForeignKey (berkorelasi dengan definisi model kelas Penerbit):
Dengan bidang ForeignKey, kueri juga berfungsi sebaliknya, tetapi keduanya sedikit berbeda karena sifat hubungan yang tidak simetris.
Di belakang layar, book_set hanyalah QuerySet dan dapat difilter dan diiris seperti QuerySet lainnya. Nama atribut book_set dihasilkan dengan menambahkan nama model huruf kecil ke _set.
sumber
OneToOneField: jika tabel kedua terkait dengan
table2 hanya akan berisi satu record yang sesuai dengan nilai pk table1, yaitu table2_col1 akan memiliki nilai unik sama dengan pk tabel
table2 dapat berisi lebih dari satu record yang sesuai dengan nilai pk table1.
sumber
ForeignKey memungkinkan Anda menerima subclass apakah itu definisi kelas lain tetapi OneToOneFields tidak dapat melakukan ini dan tidak dapat dilampirkan ke beberapa variabel
sumber