Django'da Model İlişkileri: Veritabanı Tasarımının Temelleri
Django'nun en güçlü yanlarından biri olan ORM (Object-Relational Mapping) yapısını ve veritabanı ilişkilerini öğrencilere veya blog okurlarına aktarmak için oldukça yapılandırılmış, bol örnekli bir makale taslağı hazırladım.
Modern web uygulamaları geliştirirken, veriler nadiren tek başlarına, izole bir şekilde dururlar. Tıpkı gerçek hayatta olduğu gibi, veriler de birbirleriyle ilişki içindedir. Bir blog sistemindeki makalelerin kategorilerle, bir e-ticaret sitesindeki ürünlerin siparişlerle bağlantılı olması buna en güzel örnektir.
Django, veritabanı ilişkilerini kurmayı ve yönetmeyi ORM (Object-Relational Mapping) yapısı sayesinde son derece kolaylaştırır. Bu makalede, Django'da kullanılan üç temel veritabanı ilişkisini ve bunların projelerimizde nasıl uygulanacağını detaylıca inceleyeceğiz.
1. Bire Çok İlişki (One-to-Many) - ForeignKey
Bire çok ilişki, veritabanı tasarımında en sık karşılaştığımız ilişki türüdür. Bu yapıda, A tablosundaki bir kayıt, B tablosundaki birden fazla kayıtla eşleşebilir; ancak B tablosundaki bir kayıt, A tablosundaki yalnızca bir kayda aittir.
Gerçek Hayattan Örnek: Bir "Kategori" altında birden fazla "Makale" bulunabilir. Ancak bir makale (genellikle) tek bir ana kategoriye aittir.
Django'da Kullanımı:
Bu ilişkiyi kurmak için, "çok" olan tarafa models.ForeignKey alanını ekleriz.
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=100, verbose_name="Kategori Adı")
def __str__(self):
return self.name
class Article(models.Model):
title = models.CharField(max_length=200, verbose_name="Makale Başlığı")
content = models.TextField(verbose_name="İçerik")
# ForeignKey ile Kategori modeline bağlanıyoruz
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='articles')
def __str__(self):
return self.title
Önemli Parametreler:
on_delete=models.CASCADE: Bir kategori silindiğinde, o kategoriye ait olan tüm makalelerin de silinmesini sağlar. Eğer makalelerin silinmesini istemiyorsakmodels.SET_NULLkullanabilir venull=Trueparametresini ekleyebiliriz.related_name='articles': Bu, kategoriden makalelere tersine sorgu yapmamızı sağlar (örn:kategori_objesi.articles.all()).
2. Çoka Çok İlişki (Many-to-Many) - ManyToManyField
Çoka çok ilişkilerde, A tablosundaki bir kayıt B tablosundaki birden fazla kayıtla eşleşebilir ve tam tersi de geçerlidir. Veritabanı mantığında bu işlem arka planda üçüncü bir "köprü" tablosu (junction table) oluşturularak çözülür, ancak Django bu karmaşıklığı bizden gizler.
Gerçek Hayattan Örnek: Bir makalenin birden fazla "Etiket"i (Tag) olabilir ve bir etiket birden fazla makalede kullanılabilir.
Django'da Kullanımı:
Bu ilişkiyi kurmak için modellerden herhangi birine models.ManyToManyField eklemek yeterlidir.
class Tag(models.Model):
name = models.CharField(max_length=50, verbose_name="Etiket Adı")
def __str__(self):
return self.name
class Article(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
# ManyToManyField ile Etiket modeline bağlanıyoruz
tags = models.ManyToManyField(Tag, related_name='articles', blank=True)
def __str__(self):
return self.title
Not: blank=True parametresi, bir makale oluşturulurken etiket seçilmesini zorunlu olmaktan çıkarır.
3. Bire Bir İlişki (One-to-One) - OneToOneField
Bire bir ilişki, A tablosundaki bir kaydın B tablosundaki yalnızca bir kayıtla eşleştiği durumdur. Genellikle var olan bir modeli genişletmek, ona yeni detaylar eklemek istediğimizde kullanılır.
Gerçek Hayattan Örnek: Django'nun yerleşik User (Kullanıcı) modeline, profil fotoğrafı veya biyografi gibi ekstra alanlar eklemek için bir "Profil" modeli oluşturmak.
Django'da Kullanımı:
Bağlantıyı kurmak için models.OneToOneField kullanırız.
from django.contrib.auth.models import User
from django.db import models
class UserProfile(models.Model):
# User modelini bire bir bağlıyoruz
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
bio = models.TextField(verbose_name="Biyografi", blank=True, null=True)
website = models.URLField(verbose_name="Web Sitesi", blank=True, null=True)
def __str__(self):
return f"{self.user.username} Profili"
Bu yapı sayesinde, herhangi bir kullanıcı objesi üzerinden profiline direkt erişebiliriz: user.profile.bio.
Özet ve En İyi Uygulamalar
Veritabanı Şemasını Çizin: Modelleri yazmaya başlamadan önce, projenizin ihtiyaçlarını bir kağıda veya diyagram aracına çizmek her zaman hata yapma payını azaltır.
on_deleteKuralına Dikkat Edin: Veri bütünlüğü için silme davranışlarını (CASCADE,PROTECT,SET_NULL) projenizin iş mantığına göre dikkatlice seçin.PROTECT, bağlı verisi olan bir ebeveyn kaydın silinmesini engeller ve kazara veri kayıplarının önüne geçer.related_nameKullanımını Alışkanlık Haline Getirin: Django varsayılan olarakmodeladi_setşeklinde bir geri dönüş ismi oluşturur, ancak kendi isimlendirmelerinizi yapmak (örneğinrelated_name='comments') kodunuzun okunabilirliğini büyük ölçüde artırır.
Gerçek hayattaki veriler çoğu zaman birbirleriyle ilişkilidir.
Örneğin:
| Öğrenci | Sınıf | Öğretmen |
|---|---|---|
| Ali | 11A | Ahmet |
| Ayşe | 11A | Ahmet |
| Mehmet | 12B | Fatma |
Burada:
Bir sınıfta birden fazla öğrenci olabilir
Bir öğretmen birden fazla sınıfa girebilir
Bu ilişkileri veritabanında doğru kurmak için ilişkisel veritabanı mantığı kullanılır.
Django bu ilişkileri model içinde şu alanlarla sağlar:
| Django Alanı | İlişki Türü |
|---|---|
| ForeignKey | Bire Çok (One to Many) |
| OneToOneField | Bire Bir (One to One) |
| ManyToManyField | Çoka Çok (Many to Many) |
Bu makalede bu ilişkilerin mantığını, SQL karşılığını ve Django kullanımını ayrıntılı inceleyeceğiz.
2. ForeignKey (Bire Çok İlişki)
Tanım
Bir modelin birden fazla kaydı başka bir modelin tek kaydıyla ilişkili olabilir.
Buna One to Many ilişkisi denir.
Örnek
Bir sınıfta birçok öğrenci olabilir.
Sinif 1 ------ n Ogrenci
SQL Mantığı
Veritabanında bu ilişki şu şekilde kurulur:
SINIF
-----
id
sinif_adi
OGRENCI
-------
id
ad
soyad
sinif_id
sinif_id alanı foreign key olur.
Django Model Örneği
from django.db import models
class Sinif(models.Model):
ad = models.CharField(max_length=10)
def __str__(self):
return self.ad
class Ogrenci(models.Model):
ad = models.CharField(max_length=50)
soyad = models.CharField(max_length=50)
sinif = models.ForeignKey(Sinif, on_delete=models.CASCADE)
def __str__(self):
return f"{self.ad} {self.soyad}"
Parametrelerin Açıklaması
ForeignKey
sinif = models.ForeignKey(Sinif, on_delete=models.CASCADE)
| Parametre | Açıklama |
|---|---|
| Sinif | Bağlanılacak model |
| on_delete | Ana kayıt silinince ne olacak |
on_delete Seçenekleri
| Seçenek | Açıklama |
|---|---|
| CASCADE | Ana kayıt silinirse bağlı kayıtlar da silinir |
| SET_NULL | ForeignKey alanı NULL yapılır |
| PROTECT | Silmeye izin vermez |
| SET_DEFAULT | Varsayılan değer verir |
CASCADE Örneği
Eğer bir sınıf silinirse:
Sinif: 11A silindi
O sınıftaki öğrenciler de silinir.
Veri Ekleme
Admin Panelden
Önce sınıf eklenir
Sonra öğrenci eklenirken sınıf seçilir
Python Shell
python manage.py shell
sinif = Sinif.objects.create(ad="11A")
Ogrenci.objects.create(
ad="Ali",
soyad="Yılmaz",
sinif=sinif
)
Veri Okuma
Öğrencinin Sınıfını Öğrenme
ogrenci = Ogrenci.objects.get(id=1)
ogrenci.sinif
Bir Sınıftaki Öğrencileri Listeleme
sinif = Sinif.objects.get(id=1)
sinif.ogrenci_set.all()
related_name Kullanımı
Varsayılan isim:
ogrenci_set
Ama bunu değiştirebiliriz.
sinif = models.ForeignKey(
Sinif,
on_delete=models.CASCADE,
related_name="ogrenciler"
)
Artık:
sinif.ogrenciler.all()
3. OneToOneField (Bire Bir İlişki)
Tanım
Bir kayıt sadece bir kayıtla ilişkili olabilir.
Kullanıcı 1 ----- 1 Profil
Örnek Senaryo
Bir kullanıcıya ait tek profil olabilir.
Model
from django.contrib.auth.models import User
class Profil(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
telefon = models.CharField(max_length=15)
adres = models.TextField()
def __str__(self):
return self.user.username
SQL Mantığı
USER
----
id
username
PROFIL
------
id
user_id UNIQUE
telefon
adres
user_id alanı unique olur.
Kullanım
Profil Oluşturma
user = User.objects.get(username="ali")
Profil.objects.create(
user=user,
telefon="55555555",
adres="Ankara"
)
Profil Okuma
user.profil
veya
profil.user
4. ManyToManyField (Çoka Çok İlişki)
Tanım
Bir kayıt birden fazla kayıtla ilişkili olabilir ve tersi de geçerlidir.
Öğrenci ---- n Ders
n ---- Ders
Örnek
Bir öğrenci:
Matematik
Fizik
Kimya
derslerini alabilir.
SQL Mantığı
Arada ara tablo oluşur.
OGRENCI
-------
id
ad
DERS
----
id
ad
OGRENCI_DERS
------------
ogrenci_id
ders_id
Django Model
class Ders(models.Model):
ad = models.CharField(max_length=50)
def __str__(self):
return self.ad
class Ogrenci(models.Model):
ad = models.CharField(max_length=50)
dersler = models.ManyToManyField(Ders)
def __str__(self):
return self.ad
Kullanım
Ders Ekleme
ogrenci = Ogrenci.objects.get(id=1)
matematik = Ders.objects.get(ad="Matematik")
ogrenci.dersler.add(matematik)
Birden Fazla Ders
ogrenci.dersler.add(matematik, fizik)
Ders Silme
ogrenci.dersler.remove(matematik)
Tüm Dersleri Listeleme
ogrenci.dersler.all()
Dersi Alan Öğrenciler
ders.ogrenci_set.all()
5. İlişkilerin Karşılaştırması
| Özellik | ForeignKey | OneToOne | ManyToMany |
|---|---|---|---|
| ilişki | 1 → n | 1 → 1 | n → n |
| SQL | FK | FK + Unique | Ara tablo |
| kullanım | öğrenci-sınıf | kullanıcı-profil | öğrenci-ders |
6. Gerçek Bir Django Senaryosu
Okul Sistemi
Modeller
class Ogretmen(models.Model):
ad = models.CharField(max_length=100)
class Ders(models.Model):
ad = models.CharField(max_length=100)
ogretmen = models.ForeignKey(Ogretmen, on_delete=models.CASCADE)
class Ogrenci(models.Model):
ad = models.CharField(max_length=100)
dersler = models.ManyToManyField(Ders)
İlişki Diyagramı
OGRETMEN
|
| 1
|
n
DERS
|
| n
|
n
OGRENCI
7. Migration Sonrası Veritabanı Yapısı
ogretmen
---------
id
ad
ders
-----
id
ad
ogretmen_id
ogrenci
-------
id
ad
ogrenci_ders
-------------
ogrenci_id
ders_id
8. Django ORM ile Sorgular
Öğrencinin dersleri
ogrenci.dersler.all()
Bir dersin öğrencileri
ders.ogrenci_set.all()
Öğretmenin dersleri
ogretmen.ders_set.all()
9. İlişkilerde En Çok Yapılan Hatalar
Hata 1
ForeignKey yerine CharField kullanmak.
❌
sinif = models.CharField(max_length=10)
✔
sinif = models.ForeignKey(Sinif, on_delete=models.CASCADE)
Hata 2
ManyToMany alanına veri atarken .add() kullanmamak.
❌
ogrenci.dersler = ders
✔
ogrenci.dersler.add(ders)
10. Sonuç
Django'da model ilişkileri üç temel yapı ile kurulur:
ForeignKey → Bire çok
OneToOneField → Bire bir
ManyToManyField → Çoka çok
Bu ilişkiler sayesinde:
veri tekrarını önler
veritabanını düzenli tutar
güçlü sorgular yapmayı sağlar
Django Mini Proje
🕌 Dua Paylaşım Sistemi
Proje Amacı
Kullanıcılar:
Dua ekleyebilir
Dua kategorisi seçebilir
Duaları favorilerine ekleyebilir
Bu projede şu ilişkiler kullanılacak:
| İlişki | Kullanım |
|---|---|
| ForeignKey | Dua → Kategori |
| ForeignKey | Dua → Kullanıcı |
| ManyToMany | Kullanıcı → Favori Dualar |
1️⃣ ER Diyagram
KULLANICI
|
| 1
|
N
DUA
|
| N
|
1
KATEGORI
KULLANICI
|
| N
|
N
FAVORI_DUALAR
|
|
N
DUA
2️⃣ Django Model Tasarımı
Kategori Modeli
from django.db import models
class Kategori(models.Model):
ad = models.CharField(max_length=100)
def __str__(self):
return self.ad
Dua Modeli
Burada iki ForeignKey var.
from django.contrib.auth.models import User
class Dua(models.Model):
baslik = models.CharField(max_length=200)
icerik = models.TextField()
kategori = models.ForeignKey(
Kategori,
on_delete=models.CASCADE
)
kullanici = models.ForeignKey(
User,
on_delete=models.CASCADE
)
tarih = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.baslik
3️⃣ Favori Dua Sistemi (ManyToMany)
Bir kullanıcı birçok duayı favori yapabilir.
class Profil(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
favori_dualar = models.ManyToManyField(
Dua,
blank=True
)
def __str__(self):
return self.user.username
4️⃣ İlişki Mantığı
Dua → Kategori
Kategori 1 ------ N Dua
Örnek:
| Kategori | Dua |
|---|---|
| Sabah | Sabah Duası |
| Yemek | Yemek Duası |
Kullanıcı → Dua
User 1 -------- N Dua
Bir kullanıcı birçok dua ekleyebilir.
Favori Dua
User N -------- N Dua
Bu yüzden ManyToMany kullanılır.
5️⃣ Migration
python manage.py makemigrations
python manage.py migrate
Oluşan tablolar:
kategori
dua
profil
profil_favori_dualar
Son tablo ManyToMany ara tablosudur.
6️⃣ ORM Kullanımı
Dua ekleme
from django.contrib.auth.models import User
user = User.objects.get(username="ali")
kategori = Kategori.objects.get(ad="Sabah")
Dua.objects.create(
baslik="Sabah Duası",
icerik="Allahümme bika esbahna...",
kategori=kategori,
kullanici=user
)
Favori dua ekleme
profil = Profil.objects.get(user=user)
dua = Dua.objects.get(id=1)
profil.favori_dualar.add(dua)
Favori duaları listeleme
profil.favori_dualar.all()
Bir duayı favori yapan kullanıcılar
dua.profil_set.all()
7️⃣ Django Admin
Admin'e ekleyelim:
from django.contrib import admin
from .models import Kategori, Dua, Profil
admin.site.register(Kategori)
admin.site.register(Dua)
admin.site.register(Profil)
Admin panelde artık:
kategori ekleme
dua ekleme
favori dua seçme
mümkün olur.
8️⃣ Proje Klasör Yapısı
dua_sistemi
│
├── dua
│ ├── models.py
│ ├── views.py
│ ├── admin.py
│ ├── urls.py
│
├── templates
│ ├── dua_list.html
│ ├── dua_ekle.html
│
├── db.sqlite3
└── manage.py
9️⃣ Öğrenciler İçin LAB Sorusu
Bu proje şu şekilde sorulabilir:
Soru
Django kullanarak bir Dua Paylaşım Sistemi geliştiriniz.
Aşağıdaki özellikler bulunmalıdır:
Kategori modeli oluşturunuz.
Dua modeli oluşturunuz.
Dua modeli kategori ile ForeignKey ilişkisi kurmalıdır.
Kullanıcılar dua ekleyebilmelidir.
Kullanıcılar duaları favorilerine ekleyebilmelidir (ManyToMany).
Admin panelde veri yönetimi yapılabilmelidir.
🔥 Django Model İlişkilerini Öğrenmek İçin En İyi 3 Proje
Eğer istersen sana ayrıca şu projeleri de hazırlayabilirim:
1️⃣ Ramazan Uygulaması
ForeignKey + ManyToMany içerir
Tarif
Kategori
Kullanıcı
Favoriler
2️⃣ Okul Yönetim Sistemi
Öğrenci
Ders
Öğretmen
Sınıf
Tüm ilişki tiplerini öğretir.
3️⃣ Blog Sistemi
Yazar
Kategori
Yazı
Etiket
Bu projede ManyToMany (etiket) kullanılır.
Gerçek dünyadan, somut ve kültürel olarak tanıdık bir örnek üzerinden gitmek, öğrencilerin veya blog okurlarının veritabanı mantığını çok daha hızlı kavramasını sağlayacaktır.
Bu ilişkileri anlatmak için bir "Ramazan Rehberi" uygulaması tasarlayalım. Uygulamamızda kullanıcıların Ramazan profilleri, şehirlere göre imsakiye vakitleri ve iftar menüleri olacak.
Projeye ramazan_projesi, uygulamaya ise ramazan_app adını verdiğimizi varsayarak ilerliyoruz.
1. Proje Kurulumu (Terminal / Uçbirim)
Öncelikle sanal ortamı oluşturup Django projemizi başlatalım:
# Sanal ortam oluşturma ve aktifleştirme
python3 -m venv venv
source venv/bin/activate
# Django kurulumu ve proje başlatma
pip install django
django-admin startproject ramazan_projesi
cd ramazan_projesi
python manage.py startapp ramazan_app
Not: ramazan_projesi/settings.py dosyasındaki INSTALLED_APPS listesine 'ramazan_app', satırını eklemeyi unutmayın.
2. Modeller: ramazan_app/models.py
Bir önceki adımda kurguladığımız, ilişkileri barındıran veritabanı şemamız.
from django.db import models
from django.contrib.auth.models import User
class RamazanProfili(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='ramazan_profili')
tutulan_oruc_sayisi = models.PositiveIntegerField(default=0, verbose_name="Tutulan Oruç Sayısı")
favori_cami = models.CharField(max_length=100, blank=True, verbose_name="Teravih İçin Favori Cami")
def __str__(self):
return f"{self.user.username} Profili"
class Sehir(models.Model):
isim = models.CharField(max_length=50, verbose_name="Şehir Adı")
def __str__(self):
return self.isim
class ImsakiyeVakti(models.Model):
sehir = models.ForeignKey(Sehir, on_delete=models.CASCADE, related_name='vakitler')
tarih = models.DateField(verbose_name="Tarih")
imsak = models.TimeField(verbose_name="İmsak Vakti")
iftar = models.TimeField(verbose_name="İftar Vakti")
def __str__(self):
return f"{self.sehir.isim} - {self.tarih}"
class Yemek(models.Model):
isim = models.CharField(max_length=100, verbose_name="Yemek Adı")
kategori = models.CharField(max_length=50, verbose_name="Kategori")
def __str__(self):
return self.isim
class IftarMenusu(models.Model):
gun_adi = models.CharField(max_length=50, verbose_name="Ramazan Günü")
yemekler = models.ManyToManyField(Yemek, related_name='bulundugu_menuler')
def __str__(self):
return f"{self.gun_adi} Menüsü"
3. Yönetim Paneli: ramazan_app/admin.py
Veri girişini kolaylaştırmak için modellerimizi Django Admin paneline kaydediyoruz.
from django.contrib import admin
from .models import RamazanProfili, Sehir, ImsakiyeVakti, Yemek, IftarMenusu
# Admin panelinde daha şık görünmesi için sınıflar oluşturuyoruz
@admin.register(ImsakiyeVakti)
class ImsakiyeVaktiAdmin(admin.ModelAdmin):
list_display = ('sehir', 'tarih', 'imsak', 'iftar')
list_filter = ('sehir', 'tarih')
@admin.register(Yemek)
class YemekAdmin(admin.ModelAdmin):
list_display = ('isim', 'kategori')
search_fields = ('isim',)
@admin.register(IftarMenusu)
class IftarMenusuAdmin(admin.ModelAdmin):
filter_horizontal = ('yemekler',) # Çoka çok ilişki seçimini kolaylaştırır
admin.site.register(RamazanProfili)
admin.site.register(Sehir)
4. Görünümler (Views): ramazan_app/views.py
Veritabanındaki ilişkili verileri çekip şablona (template) göndereceğimiz mantık kısmı.
from django.shortcuts import render
from .models import Sehir, IftarMenusu
from django.contrib.auth.models import User
def ana_sayfa(request):
# Tüm şehirleri ve onlara bağlı imsakiye vakitlerini çekiyoruz
sehirler = Sehir.objects.prefetch_related('vakitler').all()
# Tüm menüleri ve içindeki yemekleri çekiyoruz
menuler = IftarMenusu.objects.prefetch_related('yemekler').all()
# Örnek olarak sistemdeki ilk kullanıcıyı alıyoruz (Bire-Bir ilişkiyi göstermek için)
ornek_kullanici = User.objects.first()
context = {
'sehirler': sehirler,
'menuler': menuler,
'ornek_kullanici': ornek_kullanici
}
return render(request, 'ramazan_app/index.html', context)
5. Yönlendirmeler (URLs)
Uygulama İçi URL (ramazan_app/urls.py):
Bu dosyayı ramazan_app klasörünün içine sizin oluşturmanız gerekir.
from django.urls import path
from . import views
urlpatterns = [
path('', views.ana_sayfa, name='ana_sayfa'),
]
Ana Proje URL'si (ramazan_projesi/urls.py):
Uygulamamızın URL'lerini ana projeye dahil ediyoruz.
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('ramazan_app.urls')), # ramazan_app rotalarını bağladık
]
6. Şablon (Template): ramazan_app/templates/ramazan_app/index.html
Bu dosyayı oluşturmak için ramazan_app klasörü içinde sırasıyla templates ve onun içinde ramazan_app klasörlerini açın. HTML kodumuz ilişkilerin ekrana nasıl basılacağını gösteriyor.
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<title>Ramazan Rehberi Uygulaması</title>
<style>
body { font-family: Arial, sans-serif; margin: 40px; line-height: 1.6; }
.bolum { margin-bottom: 40px; padding: 20px; border: 1px solid #ccc; border-radius: 8px; }
h1, h2, h3 { color: #2c3e50; }
ul { list-style-type: square; }
</style>
</head>
<body>
<h1>Ramazan Rehberi - Model İlişkileri Örneği</h1>
<div class="bolum">
<h2>Bire Bir İlişki (OneToOneField): Kullanıcı Profili</h2>
{% if ornek_kullanici %}
<p><strong>Kullanıcı Adı:</strong> {{ ornek_kullanici.username }}</p>
{% if ornek_kullanici.ramazan_profili %}
<p><strong>Tutulan Oruç:</strong> {{ ornek_kullanici.ramazan_profili.tutulan_oruc_sayisi }}</p>
<p><strong>Favori Cami:</strong> {{ ornek_kullanici.ramazan_profili.favori_cami }}</p>
{% else %}
<p>Bu kullanıcının henüz bir Ramazan profili oluşturulmamış.</p>
{% endif %}
{% else %}
<p>Sistemde henüz kayıtlı kullanıcı yok.</p>
{% endif %}
</div>
<div class="bolum">
<h2>Bire Çok İlişki (ForeignKey): Şehirler ve İmsakiye</h2>
{% for sehir in sehirler %}
<h3>{{ sehir.isim }} İmsakiyesi</h3>
<ul>
{% for vakit in sehir.vakitler.all %}
<li>{{ vakit.tarih }} - İmsak: <strong>{{ vakit.imsak }}</strong> | İftar: <strong>{{ vakit.iftar }}</strong></li>
{% empty %}
<li>Bu şehre ait vakit verisi bulunamadı.</li>
{% endfor %}
</ul>
{% endfor %}
</div>
<div class="bolum">
<h2>Çoka Çok İlişki (ManyToManyField): İftar Menüleri</h2>
{% for menu in menuler %}
<h3>{{ menu.gun_adi }}</h3>
<p>Günün Menüsü:</p>
<ul>
{% for yemek in menu.yemekler.all %}
<li>{{ yemek.isim }} <em>({{ yemek.kategori }})</em></li>
{% empty %}
<li>Bu menüye henüz yemek eklenmemiş.</li>
{% endfor %}
</ul>
{% endfor %}
</div>
</body>
</html>
Son Adım: Veritabanını Hazırlama ve Çalıştırma
Kodları yerleştirdikten sonra, terminalde sırasıyla şu komutları çalıştırarak veritabanı tablolarını oluşturun ve sunucuyu başlatın:
python manage.py makemigrations
python manage.py migrate
# Admin paneline girmek için bir süper kullanıcı oluşturalım
python manage.py createsuperuser
# Sunucuyu başlatalım
python manage.py runserver
Şimdi tarayıcıdan http://127.0.0.1:8000/admin/ adresine gidip birkaç şehir, yemek, menü ve profil ekleyin. Ardından http://127.0.0.1:8000/ adresine girerek ilişkili verilerin ekrana nasıl yansıdığını görebilirsiniz.
Yorumlar
Yorum Gönder