20 Ekim 2008 Pazartesi

İlişkisel Alanlar (Relationship Fields)

ForeignKey
Aşağıda foreingkey'in kullanımını anlatmak amacıyla yazılmış ufak bir örnek göreceksiniz.

from django.db import models

class Yazar(models.Model):
isim = models.CharField(max_length=30) #[1]

class Makale(models.Model):
baslik = models.CharField(max_length=100) #[2]
yazar = models.ForeignKey(Yazar) #[3]


[1] Yazar tablosunda CharField veri türünde bir alan oluşturuyoruz.
[2] Makale tablosunda CharField veri türünde bir alan oluşturuyoruz.
[3] Bu alanda ise ForeignKey(Yazar) ifadesi djangoya Makale tablosuna Yazar tablosunun Primary_Key'i ni eklemesini söylüyor. Daha iyi anlaşılması için şöyle örneklendirebiliriz.


Yazar
id--|--isim--|
1 --|Mirat---|
2 --|Gokmen--|
3 --|Deniz---|

Makale
id--|--baslik--|--yazar_id--|
1---|Django----|-----1------|
2---|Python----|-----1------|
3---|PyQt------|-----3------|

Id ile gösterilene alanlar tablomuzun PrimaryKeyleri. Biz eklememiş olmamıza rağmen django otomatik olarak bir PrimaryKey alanı oluşturuyor.
Makale tablosunda ki yazar_id alanı ise bizim Makale sınıfını oluştururken kullandığımız ForeignKey(Yazar) ifadesiyle Makale tablosuna Yazar_id adında bir alan ekliyor ve bu alanlar arasında ilişki kurmamızı sağlıyor. Makale tablosundaki yazar_id alanını yazar tablosundaki id ile eşleştirmemizi sağlıyor.Yani Django ve Python yazılarının sahibi yazar id si 1 olan Mirat'a aitken PyQt yazısı yazar id'si 3 olan bana ait. (Aslında bu konu djangodan çok ilişkisel veri tabanıyla alakalı olduğu için daha ayrıntılı bilgi için google kullanabilirsiniz ;) )

Şimdi djangoyu ilgilendiren kısımlarına gelelim.

Eğer ForeignKey'imiz başka bir uygulamadan çağırılacaksa uygulama ismiyle beraber belirtmemiz gerekiyor. (Django 1.0 dan önceki versiyonlarda bu özelliği kullanamıyorsunuz)


class ornek(models.Model)
yazar = model.ForeignKey('uygulama.tabloadi')


ManyToManyField
Yukarıda foreignkey ile onetomany bir ilişkinin nasıl sağlanacağını gördük. Fakat bazı durumlar vardır ki One-to-Many ile işin içinden çıkamayız. Az önceki örneğimizi biraz değiştirelim ve kitap bilgilerini ve yazarlarını tutan bir uygulama haline çevirelim. İlk örneğimizde bir yazar (one) bir kaç makale(many) yazabiliyordu. Yani makale tablosunda aynı yazar id'sinden birden çok(many) bulunabiliyordu. Peki ya bir kitabın birden çok yazarı olduğu durumlarda ne yapacağız ? Bu gibi durumlarda manytomany ilişkilerini kullabiliriz.


from django.db import models

class Yazar(models.Model):
isim = models.CharField(max_length=30)

class Kitap(models.Model):
baslik = models.CharField(max_length=100)
yazar = models.ManyToMany(Yazar)


Böyle bir ifadeyle django bu manytomany türü ilişkiyi sağlayabilmek için ayrı bir tablo oluşturuyor ve gerekli olan ilişkileri kendisi kuruyor. Bu tablo genelde iki tablonun isimlerinin birleştirilmesiyle oluşuyor. Yani bizim örneğimizde yazar_kitap şeklinde bir tablo oluşturup içerisine yazar_id ve kitap_id alanlarını ekleyip gerekli olan ilişkileri kendisi sağlıyor. Yani yukarıda ki kod veritabanımıza şu şekilde yansıyor.

Yazar
id--|--isim--|
1 --|Mirat---|
2 --|Gokmen--|
3 --|Deniz---|

Kitap
id--|--baslik--|
1---|Django----|
2---|Python----|
3---|PyQt------|

yazarkitap
id--|--yazar_id--|--kitap_id--|
1---|----1------|-----1------|
2---|----1------|-----2------|
3---|----2------|-----3------|
4---|----3------|-----1------|

Şimdi bizden Django kitabının yazarları istediğinde kitap tablosundan 1'idsini alıp yazar kitap tablosundan karşılık gelen yazar idlerini alıyoruz(1 ve 3)
yazar tablosundan da o id'ye karşılık gelen değerleri öğreniyoruz.(Mirat ve Deniz).

İşte manytomany böyle birşey. Olabildiğince basitleştirmeye çalıştım. Eğer hala mantığı tam olarak anlayamadıysanız tek bir cümleyi aklınızdan çıkarmayın. "Eğer bir değer 2 tabloda da birden çok kez yer alıyorsa manytomany kullanmalısınız"

Manytomany ve diğer veritabanı incelikleriyle ilgili anlatılacak çok şey var ama şimdilik burda kesiyorum. Ayrıntılı bilgi için kaynaklar bölümündeki adresleri ziyaret edebilirsiniz. Fırsatım oldukça yeni yazılarda eklemeyi düşünüyorum.

Kaynaklar: http://docs.djangoproject.com/en/dev/ref/models/fields/
http://www.djangoproject.com/documentation/models/
http://docs.djangoproject.com/en/dev/topics/db/models/

3 yorum:

  1. Zor konu, iyi öğretmen.. :) teşekkürler çok yardımcı oldu bu yazı.

    YanıtlaSil
  2. Teşekkürler, dediğiniz gibi basit olmuş ama çok faydalı bir içerik olmuş.
    Yeniden teşekkür ederim.

    YanıtlaSil
  3. Faydalı bir yazı teşekkürler

    YanıtlaSil