Django Admin Paneli: Özelleştirme İpuçları
Django'nun en güçlü yanlarından biri olan Admin paneli, özellikle veritabanı yönetimini ve içerik girişini inanılmaz derecede kolaylaştırır.
1. Admin Paneline Giriş ve Superuser Oluşturma
Django projenizi oluşturduğunuzda admin paneli varsayılan olarak gelir. Ancak panele giriş yapabilmek için en yetkili kullanıcı olan bir "superuser" oluşturmanız gerekir.
Terminalinizi açın ve proje dizinindeyken şu komutu çalıştırın:
python manage.py createsuperuser
Sizden bir kullanıcı adı, e-posta adresi ve şifre isteyecektir. Bilgileri girdikten sonra geliştirme sunucunuzu başlatın (python manage.py runserver) ve tarayıcınızdan http://127.0.0.1:8000/admin/ adresine giderek giriş yapın.
2. Modelleri Admin Paneline Kaydetmek
Admin panelinde kendi oluşturduğumuz veritabanı tablolarını (modelleri) görebilmek için onları kaydetmemiz gerekir. Örnek olarak bir eğitim sistemindeki Ogrenci modelini ele alalım.
models.py:
from django.db import models
class Ogrenci(models.Model):
ad = models.CharField(max_length=50)
soyad = models.CharField(max_length=50)
numara = models.CharField(max_length=10, unique=True)
kayit_tarihi = models.DateField(auto_now_add=True)
mezun_mu = models.BooleanField(default=False)
def __str__(self):
return f"{self.numara} - {self.ad} {self.soyad}"
Bu modeli admin panelinde görünür kılmak için uygulamanızın admin.py dosyasını düzenlemelisiniz:
admin.py (Temel Kayıt):
from django.contrib import admin
from .models import Ogrenci
admin.site.register(Ogrenci)
3. ModelAdmin ile Paneli Özelleştirme
Varsayılan görünüm işimizi görse de, kayıt sayısı arttıkça verileri yönetmek zorlaşır. İşte burada ModelAdmin sınıfı devreye girer.
admin.py (Gelişmiş Kayıt):
from django.contrib import admin
from .models import Ogrenci
@admin.register(Ogrenci)
class OgrenciAdmin(admin.ModelAdmin):
# Listeleme ekranında görünecek sütunlar
list_display = ('numara', 'ad', 'soyad', 'kayit_tarihi', 'mezun_mu')
# Sağ tarafa filtreleme menüsü ekler
list_filter = ('mezun_mu', 'kayit_tarihi')
# Arama çubuğu ekler (ad, soyad veya numaraya göre aranabilir)
search_fields = ('ad', 'soyad', 'numara')
# Varsayılan sıralamayı belirler (numaraya göre artan)
ordering = ('numara',)
# Sayfa başına gösterilecek kayıt sayısı
list_per_page = 20
Önemli ModelAdmin Özellikleri:
list_display: Nesnelerin liste sayfasında hangi alanlarının tablo sütunu olarak gösterileceğini belirler.search_fields: Arama kutucuğu ekler ve aramanın hangi veritabanı alanlarında yapılacağını belirtir.list_filter: Belirli alanlara (özellikle Boolean, Date veya ForeignKey) göre filtreleme imkanı sunar.
4. Admin Paneline Özel Eylemler (Actions) Eklemek
Bazen birden fazla kaydı aynı anda güncellemek isteyebilirsiniz. Örneğin, seçili öğrencilerin hepsini tek tıkla "Mezun" durumuna getirmek isteyelim.
admin.py:
from django.contrib import admin
from .models import Ogrenci
@admin.register(Ogrenci)
class OgrenciAdmin(admin.ModelAdmin):
list_display = ('numara', 'ad', 'soyad', 'mezun_mu')
actions = ['mezun_yap']
@admin.action(description='Seçili öğrencileri mezun yap')
def mezun_yap(self, request, queryset):
guncellenen = queryset.update(mezun_mu=True)
self.message_user(request, f"{guncellenen} öğrenci başarıyla mezun edildi.")
Bu kodu eklediğinizde, admin panelindeki açılır eylem menüsüne "Seçili öğrencileri mezun yap" seçeneğinin eklendiğini göreceksiniz.
5. Başlık ve Site İsimlerini Değiştirme
Admin panelinin sol üst köşesinde yazan standart "Django yönetimi" yazısını kendi projenize uygun hale getirebilirsiniz. Bunun için genellikle ana projenin urls.py dosyasını kullanmak en pratik yoldur.
urls.py:
from django.contrib import admin
from django.urls import path
# Admin paneli başlık özelleştirmeleri
admin.site.site_header = "Okul Yönetim Sistemi"
admin.site.site_title = "Okul Admin Portalı"
admin.site.index_title = "Yönetim Paneline Hoş Geldiniz"
urlpatterns = [
path('admin/', admin.site.urls),
]
Sonuç
Django Admin paneli, veritabanı yönetimi için tekerleği yeniden icat etmenizi engeller. Birkaç satır kod ile arama, filtreleme, sayfalama ve toplu işlemler yapabileceğiniz profesyonel bir arayüz elde edersiniz. Bu makaledeki özelleştirmeler, projelerinizin yönetim arayüzünü hem sizin hem de son kullanıcılar için çok daha verimli hale getirecektir.
6. Admin Paneli HTML Şablonlarını (Templates) Özelleştirmek
Django Admin paneli arka planda klasik Django HTML şablonlarını kullanır. Kendi projemizde aynı isimde klasör ve dosyalar oluşturarak bu varsayılan şablonları "ezebiliriz" (override). Örneğin, admin panelinin en üstüne projenize özel bir geri dönüş butonu veya logonuzu eklemek isteyebilirsiniz.
Adım 1: Klasör Yapısını Kurmak
Öncelikle settings.py dosyanızdaki TEMPLATES ayarında şablon dizininizin tanımlı olduğundan emin olun:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'], # Bu satırın eklendiğinden emin olun
'APP_DIRS': True,
# ...
},
]
Adım 2: Şablon Dosyasını Oluşturmak
Projenizin ana dizininde sırasıyla templates ve onun içinde admin adında klasörler oluşturun. Daha sonra admin klasörünün içine base_site.html adında bir dosya açın.
Adım 3: Kodu Eklemek
Oluşturduğumuz templates/admin/base_site.html dosyasının içine şu kodları yapıştırarak orijinal şablonu genişletip kendi başlığımızı ekleyebiliriz:
{% extends "admin/base_site.html" %}
{% block branding %}
<h1 id="site-name">
<a href="{% url 'admin:index' %}">
<span style="color: #417690; font-weight: bold;">Okul Bilgi Sistemi Admin Portalı</span>
</a>
</h1>
<p style="margin: 5px 0 0 10px;">
<a href="/" style="color: #999;">← Siteye Geri Dön</a>
</p>
{% endblock %}
Artık sayfa yenilendiğinde sol üst köşede kendi tasarımınızın ve ana sayfaya dönüş linkinin yer aldığını göreceksiniz. change_form.html veya change_list.html gibi dosyaları ezerek form ve liste sayfalarına özel butonlar da ekleyebilirsiniz.
7. Üretim (Production) Ortamında Admin Statik Dosyalarını Yayınlamak
Projeyi geliştirirken her şey harika görünür ancak uygulamanızı bir Pardus sunucuya taşıyıp settings.py içinde DEBUG = False yaptığınızda büyük bir sürprizle karşılaşırsınız: Admin paneli tamamen bozulmuş, renksiz ve darmadağın bir HTML sayfasına dönüşmüştür.
Bunun sebebi, üretim ortamında Django'nun artık CSS, JavaScript ve görsel gibi statik dosyaları kendi başına sunmayı bırakmasıdır. Bu görevi Nginx veya Apache gibi güçlü bir web sunucusuna devretmemiz gerekir.
Adım 1: Statik Dosya Ayarlarını Yapılandırmak
settings.py dosyanızın en altına şu ayarları ekleyin:
STATIC_URL = '/static/'
# Sunucudaki tüm statik dosyaların toplanacağı ana dizin
STATIC_ROOT = BASE_DIR / 'staticfiles'
Adım 2: Dosyaları Toplamak (Collectstatic)
Terminalde aşağıdaki komutu çalıştırarak Django'nun (admin paneli dahil) kullandığı tüm statik dosyaları staticfiles klasörüne kopyalamasını sağlayın:
python manage.py collectstatic
Bu işlemden sonra admin panelinin CSS ve JS dosyalarının belirlediğiniz klasöre kopyalandığını göreceksiniz.
Adım 3: Pardus Üzerinde Nginx Yapılandırması
Son olarak, web sunucunuza (örneğin Nginx) /static/ uzantılı bir istek geldiğinde bu klasöre bakmasını söylemelisiniz. Nginx ayar dosyanızdaki (/etc/nginx/sites-available/projeniz) server bloğunun içine şu satırları ekleyin:
server {
# ... diğer ayarlar (listen, server_name vs.) ...
location /static/ {
# Projenizdeki staticfiles klasörünün tam yolu
alias /var/www/projeniz/staticfiles/;
}
location / {
# Gunicorn veya uWSGI yönlendirmeleri
proxy_pass http://127.0.0.1:8000;
# ...
}
}
Nginx'i yeniden başlattığınızda (sudo systemctl restart nginx), admin paneliniz Pardus sunucunuz üzerinde tüm stilleriyle birlikte eksiksiz ve güvenli bir şekilde çalışmaya başlayacaktır.
📌 1️⃣ Django Admin Paneli Nedir?
Django Admin, Django framework’ü ile birlikte hazır gelen bir yönetim panelidir.
👉 Veritabanındaki verileri:
Listeleyebiliriz
Ekleyebiliriz
Güncelleyebiliriz
Silebiliriz (CRUD)
Hem de hiç HTML yazmadan!
📌 2️⃣ Admin Paneli Aktif mi Kontrol Edelim
settings.py dosyasında şu satırların olduğundan emin olun:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
Bu uygulamalar Django’nun temel sistemleridir.
📌 3️⃣ Superuser (Yönetici) Oluşturma
Admin paneline giriş için yönetici hesabı gerekir.
Terminalde:
python manage.py createsuperuser
Sizden:
Kullanıcı adı
Email
Şifre
isteyecek.
📌 4️⃣ Admin Panelini Çalıştırma
Sunucuyu başlatalım:
python manage.py runserver
Tarayıcıdan:
http://127.0.0.1:8000/admin
🎉 Django’nun hazır admin paneli karşınızda!
📌 5️⃣ Modeli Admin Paneline Eklemek
Örnek model oluşturalım:
# models.py
from django.db import models
class Ogrenci(models.Model):
ad = models.CharField(max_length=50)
soyad = models.CharField(max_length=50)
yas = models.IntegerField()
aktif = models.BooleanField(default=True)
def __str__(self):
return f"{self.ad} {self.soyad}"
Migration yapalım:
python manage.py makemigrations
python manage.py migrate
📌 Admin’e Model Kaydı
admin.py dosyasına:
from django.contrib import admin
from .models import Ogrenci
admin.site.register(Ogrenci)
Artık admin panelinde Ogrenci modeli görünecek.
📌 6️⃣ Admin Panelini Özelleştirme
Django Admin’i güçlü yapan şey özelleştirilebilir olmasıdır.
🎯 Liste Görünümünü Düzenleme
@admin.register(Ogrenci)
class OgrenciAdmin(admin.ModelAdmin):
list_display = ("ad", "soyad", "yas", "aktif")
Açıklama:
list_display→ tabloda hangi sütunlar görünecek
🎯 Filtre Ekleme
list_filter = ("aktif", "yas")
Sağ tarafta filtre alanı oluşur.
🎯 Arama Özelliği
search_fields = ("ad", "soyad")
Arama kutusu ekler.
🎯 Sıralama
ordering = ("ad",)
🎯 Sayfa Başına Kayıt
list_per_page = 10
📌 7️⃣ Admin Form Alanlarını Gruplama
fieldsets = (
("Kişisel Bilgiler", {
"fields": ("ad", "soyad")
}),
("Durum Bilgisi", {
"fields": ("yas", "aktif")
}),
)
Bu kod formu başlıklarla ayırır.
📌 8️⃣ Salt Okunur Alan Yapma
readonly_fields = ("ad",)
📌 9️⃣ Otomatik Alan Ekleme (Tarih)
Modeli güncelleyelim:
created_at = models.DateTimeField(auto_now_add=True)
Admin’de:
readonly_fields = ("created_at",)
📌 🔟 Inline (İlişkili Modeller)
Örnek: Öğrenci ve Not modeli
class Not(models.Model):
ogrenci = models.ForeignKey(Ogrenci, on_delete=models.CASCADE)
ders = models.CharField(max_length=50)
puan = models.IntegerField()
Admin’de:
class NotInline(admin.TabularInline):
model = Not
extra = 1
@admin.register(Ogrenci)
class OgrenciAdmin(admin.ModelAdmin):
inlines = [NotInline]
👉 Artık öğrenci eklerken notları da ekleyebiliriz.
📌 11️⃣ Admin Panel Başlığını Değiştirme
admin.py içine:
admin.site.site_header = "Okul Yönetim Paneli"
admin.site.site_title = "Okul Admin"
admin.site.index_title = "Yönetim Sistemi"
📌 12️⃣ Yetkilendirme (Permission Sistemi)
Django otomatik olarak şunları oluşturur:
add
change
delete
view
Kullanıcıları:
Admin → Users → Permissions bölümünden ayarlayabilirsiniz.
📌 13️⃣ Admin Panel Güvenliği
Öneriler:
✅ Güçlü şifre kullan
✅ DEBUG = False (Canlı sunucuda)
✅ HTTPS kullan
✅ Admin URL değiştirilebilir
path("panelim/", admin.site.urls),
📌 14️⃣ Gerçek Hayatta Kullanım Senaryosu
Admin paneli şunlar için idealdir:
Okul otomasyonu
Kütüphane sistemi
Stok takip
Blog yönetimi
İçerik yönetim sistemi (CMS)
Ama genelde kullanıcıya açık arayüz için kullanılmaz.
📌 15️⃣ Mini Lab Uygulaması
🎯 Görev:
Ogrenci modeli oluştur
Admin’e ekle
list_display ekle
search_fields ekle
list_filter ekle
fieldsets kullan
Inline ile Not modeli bağla
🎯 Django Admin’in Avantajları
| Özellik | Açıklama |
|---|---|
| Hazır gelir | Ek kurulum yok |
| CRUD hazır | Kod yazmadan veri yönetimi |
| Güvenli | Yetkilendirme sistemi var |
| Hızlı geliştirme | Prototip için ideal |
🏁 Sonuç
Django Admin:
Hızlıdır
Güvenlidir
Özelleştirilebilir
Profesyonel projelerde backend yönetimi için idealdir
Şimdi Django Admin Paneli’ni modern ve şık bir görünüme kavuşturalım.
Admin paneli varsayılan olarak sade bir tasarıma sahiptir. Ancak istersek:
🎨 Renkleri değiştirebilir
🌙 Dark Mode yapabilir
🔲 Daha modern kart tasarımı ekleyebilir
📊 Dashboard görünümünü geliştirebiliriz
Bunu 2 farklı yöntemle yapacağız:
🚀 YÖNTEM 1: Hazır Modern Admin Teması (En Profesyonel Yöntem)
En popüler modern Django admin teması:
⭐ Django Jazzmin
Modern, responsive ve profesyonel görünümlüdür.
📌 1️⃣ Kurulum
Terminal:
pip install django-jazzmin
📌 2️⃣ settings.py Düzenleme
INSTALLED_APPS = [
"jazzmin", # EN ÜSTE
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
]
⚠️ Jazzmin mutlaka django.contrib.admin’dan önce olmalı.
📌 3️⃣ Çalıştır
python manage.py runserver
Admin paneline gir:
http://127.0.0.1:8000/admin
🎉 Artık modern bir admin panelin var!
📌 4️⃣ Jazzmin Özelleştirme
settings.py içine ekle:
JAZZMIN_SETTINGS = {
"site_title": "Okul Yönetim Sistemi",
"site_header": "Okul Admin",
"welcome_sign": "Yönetim Paneline Hoşgeldiniz",
"copyright": "Bilişim Bölümü",
"topmenu_links": [
{"name": "Ana Sayfa", "url": "admin:index"},
],
"show_sidebar": True,
"navigation_expanded": True,
}
🎨 Renk Değiştirme
JAZZMIN_SETTINGS = {
"theme": "flatly", # cerulean, cosmo, flatly, darkly vb.
}
Dark mode için:
"theme": "darkly",
🚀 YÖNTEM 2: Manuel CSS ile Modernleştirme (Öğretici Yöntem)
Bu yöntemle admin paneline kendi CSS dosyamızı ekleyeceğiz.
📌 1️⃣ Static Klasörü Oluştur
proje/
static/
css/
admin.css
📌 2️⃣ settings.py Static Ayarı
STATIC_URL = '/static/'
STATICFILES_DIRS = [
BASE_DIR / "static",
]
📌 3️⃣ Admin’e CSS Bağlama
admin.py içine:
from django.contrib import admin
class MyAdminSite(admin.AdminSite):
class Media:
css = {
"all": ("css/admin.css",)
}
admin.site.__class__ = MyAdminSite
📌 4️⃣ Modern CSS Örneği
static/css/admin.css
/* Genel Arka Plan */
body {
background-color: #f4f6f9;
}
/* Başlık Alanı */
#header {
background: linear-gradient(90deg, #1e3c72, #2a5298);
}
/* Butonlar */
.button, input[type=submit] {
background-color: #4CAF50 !important;
border-radius: 8px !important;
padding: 8px 15px !important;
}
/* Tablolar */
table {
border-radius: 10px;
overflow: hidden;
}
/* Hover efekti */
tr:hover {
background-color: #e6f2ff !important;
}
Sunucuyu yeniden başlat:
python manage.py runserver
🌙 BONUS: Admin Dark Mode
body {
background-color: #1e1e1e;
color: white;
}
.module h2 {
background-color: #333;
}
🚀 YÖNTEM 3: Profesyonel Dashboard (Alternatif Tema)
Bir diğer modern tema:
⭐ django-admin-interface
Kurulum:
pip install django-admin-interface
Bu tema renkleri admin panel içinden değiştirmenizi sağlar.
🎯 Hangisini Kullanmalıyım?
| Durum | Öneri |
|---|---|
| Hızlı ve profesyonel | Jazzmin |
| Öğrenmek istiyorum | Manuel CSS |
| Panelden renk değiştirmek | django-admin-interface |
🏫 Okul Projesi İçin Önerim
Sen okul projeleri yapıyorsun 👨💻
En temiz ve etkileyici sonuç için:
👉 Jazzmin + Darkly tema kullan
👉 Logo ekle
👉 Sidebar aktif yap
👉 Dashboard’a model ikonları ekle
Şimdi adım adım profesyonel seviyede modern bir Django Admin sistemi yapıyoruz.
Kullanacağımız temel yapı:
🎨 Tema: Django Jazzmin
📊 Grafik: Chart.js
🔐 Yetki: Django’nun built-in permission sistemi
🏫 Senaryo: Okul Otomasyon Admin Paneli
🎨 1️⃣ Admin’e Logo Ekleyelim
📌 Logo Dosyası
static/img/logo.png içine okul logosunu koy.
📌 settings.py
JAZZMIN_SETTINGS = {
"site_title": "Okul Yönetim Sistemi",
"site_header": "Bilişim Okulu",
"site_brand": "Okul Admin",
"site_logo": "img/logo.png",
"login_logo": "img/logo.png",
"site_logo_classes": "img-circle",
}
Artık:
Login ekranında logo var
Sidebar’da logo var
Profesyonel görünüm oluştu
📊 2️⃣ Dashboard’a Grafik Ekleyelim
Amaç:
Kaç öğrenci var?
Kaç öğretmen var?
Kaç aktif kayıt var?
📌 models.py
class Ogrenci(models.Model):
ad = models.CharField(max_length=50)
soyad = models.CharField(max_length=50)
aktif = models.BooleanField(default=True)
class Ogretmen(models.Model):
ad = models.CharField(max_length=50)
brans = models.CharField(max_length=50)
📌 admin.py Dashboard View Ekleyelim
from django.urls import path
from django.template.response import TemplateResponse
from django.db.models import Count
from .models import Ogrenci, Ogretmen
from django.contrib import admin
class MyAdminSite(admin.AdminSite):
site_header = "Okul Yönetim Paneli"
def get_urls(self):
urls = super().get_urls()
custom_urls = [
path("dashboard/", self.admin_view(self.dashboard))
]
return custom_urls + urls
def dashboard(self, request):
ogrenci_sayisi = Ogrenci.objects.count()
ogretmen_sayisi = Ogretmen.objects.count()
aktif_ogrenci = Ogrenci.objects.filter(aktif=True).count()
context = dict(
self.each_context(request),
ogrenci_sayisi=ogrenci_sayisi,
ogretmen_sayisi=ogretmen_sayisi,
aktif_ogrenci=aktif_ogrenci,
)
return TemplateResponse(request, "admin/dashboard.html", context)
admin_site = MyAdminSite(name="myadmin")
📌 templates/admin/dashboard.html
{% extends "admin/base_site.html" %}
{% block content %}
<h1>Okul Dashboard</h1>
<canvas id="myChart"></canvas>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
const ctx = document.getElementById('myChart');
new Chart(ctx, {
type: 'bar',
data: {
labels: ['Toplam Öğrenci', 'Aktif Öğrenci', 'Öğretmen'],
datasets: [{
label: 'Okul Verileri',
data: [{{ ogrenci_sayisi }}, {{ aktif_ogrenci }}, {{ ogretmen_sayisi }}],
}]
}
});
</script>
{% endblock %}
🎉 Admin içinde grafik çıktı.
🔐 3️⃣ Rol Bazlı Admin Tasarlayalım
Django otomatik permission üretir:
add
change
delete
view
📌 Rol 1: Müdür
Her şeyi görebilir
Silme yetkisi var
📌 Rol 2: Öğretmen
Sadece öğrenci görebilir
Silme yok
📌 Öğretmen Rolünü Sınırlandırma
class OgrenciAdmin(admin.ModelAdmin):
def has_delete_permission(self, request, obj=None):
if request.user.groups.filter(name="Ogretmen").exists():
return False
return True
📌 Group Oluşturma
Admin → Users → Groups
Yeni grup: Ogretmen
Permission olarak sadece:
view_ogrenci
change_ogrenci
ver.
🏫 4️⃣ TAM MODERN OKUL OTOMASYON ADMIN
🎯 Önerilen Modeller
class Sinif(models.Model):
ad = models.CharField(max_length=20)
class Ogrenci(models.Model):
ad = models.CharField(max_length=50)
soyad = models.CharField(max_length=50)
sinif = models.ForeignKey(Sinif, on_delete=models.CASCADE)
aktif = models.BooleanField(default=True)
class Ders(models.Model):
ad = models.CharField(max_length=50)
class Not(models.Model):
ogrenci = models.ForeignKey(Ogrenci, on_delete=models.CASCADE)
ders = models.ForeignKey(Ders, on_delete=models.CASCADE)
puan = models.IntegerField()
🎨 Admin Modern Görünüm
@admin.register(Ogrenci)
class OgrenciAdmin(admin.ModelAdmin):
list_display = ("ad", "soyad", "sinif", "aktif")
list_filter = ("sinif", "aktif")
search_fields = ("ad", "soyad")
list_per_page = 10
💎 Profesyonel Dokunuşlar
Jazzmin ayarına ikon ekleyelim:
JAZZMIN_SETTINGS = {
"icons": {
"app.Ogrenci": "fas fa-user",
"app.Ogretmen": "fas fa-chalkboard-teacher",
"app.Sinif": "fas fa-school",
"app.Ders": "fas fa-book",
}
}
🚀 Sonuç
Artık admin panelin:
✅ Modern tasarımlı
✅ Logo’lu
✅ Grafik dashboard’lu
✅ Rol bazlı yetkili
✅ Okul otomasyonu yapısında
Profesyonel seviyede 🎯
Şimdi okul otomasyonunu profesyonel seviyeye taşıyoruz.
Kullanacağımız yapılar:
Tema: Django Jazzmin
Grafik: Chart.js
Excel işlemleri: pandas
PDF üretimi: ReportLab
📊 1️⃣ Not Ortalaması Otomatik Hesaplama
📌 models.py
class Not(models.Model):
ogrenci = models.ForeignKey("Ogrenci", on_delete=models.CASCADE)
ders = models.ForeignKey("Ders", on_delete=models.CASCADE)
puan = models.IntegerField()
📌 Ogrenci Modeline Ortalama Property
from django.db.models import Avg
class Ogrenci(models.Model):
ad = models.CharField(max_length=50)
soyad = models.CharField(max_length=50)
def ortalama(self):
ort = self.not_set.aggregate(Avg("puan"))["puan__avg"]
return round(ort, 2) if ort else 0
📌 Admin’de Gösterelim
@admin.register(Ogrenci)
class OgrenciAdmin(admin.ModelAdmin):
list_display = ("ad", "soyad", "ortalama")
🎉 Artık admin listesinde ortalama görünüyor.
📥 2️⃣ Excel’den Öğrenci Import
📌 Kurulum
pip install pandas openpyxl
📌 admin.py içine import fonksiyonu
import pandas as pd
from django.shortcuts import render, redirect
from django.urls import path
from .models import Ogrenci
class OgrenciAdmin(admin.ModelAdmin):
def get_urls(self):
urls = super().get_urls()
custom_urls = [
path("import-excel/", self.admin_site.admin_view(self.import_excel))
]
return custom_urls + urls
def import_excel(self, request):
if request.method == "POST":
excel_file = request.FILES["excel_file"]
df = pd.read_excel(excel_file)
for _, row in df.iterrows():
Ogrenci.objects.create(
ad=row["ad"],
soyad=row["soyad"],
)
self.message_user(request, "Excel başarıyla yüklendi")
return redirect("..")
return render(request, "admin/import_excel.html")
📌 import_excel.html
{% extends "admin/base_site.html" %}
{% block content %}
<h2>Excel ile Öğrenci Yükle</h2>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="excel_file">
<button type="submit">Yükle</button>
</form>
{% endblock %}
Excel formatı:
| ad | soyad |
|---|
📤 3️⃣ PDF Karne Oluşturma
📌 Kurulum
pip install reportlab
📌 views.py
from reportlab.pdfgen import canvas
from django.http import HttpResponse
from .models import Ogrenci
def karne_pdf(request, ogrenci_id):
ogrenci = Ogrenci.objects.get(id=ogrenci_id)
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = f'attachment; filename="karne.pdf"'
p = canvas.Canvas(response)
p.drawString(100, 800, f"Öğrenci: {ogrenci.ad} {ogrenci.soyad}")
p.drawString(100, 780, f"Ortalama: {ogrenci.ortalama()}")
y = 750
for not_obj in ogrenci.not_set.all():
p.drawString(100, y, f"{not_obj.ders.ad} : {not_obj.puan}")
y -= 20
p.showPage()
p.save()
return response
🎉 Artık PDF karne indirilebilir.
🌙 4️⃣ Full Dark Mode Admin
Jazzmin ayarına:
JAZZMIN_SETTINGS = {
"theme": "darkly",
"dark_mode_theme": "darkly",
}
Ek CSS:
body {
background-color: #121212 !important;
}
.card {
background-color: #1e1e1e !important;
}
📱 5️⃣ Mobil Uyumlu Özel Dashboard
📌 dashboard.html
{% extends "admin/base_site.html" %}
{% block content %}
<div class="container-fluid">
<div class="row">
<div class="col-md-4 col-12">
<div class="card text-center">
<h3>{{ ogrenci_sayisi }}</h3>
<p>Öğrenci</p>
</div>
</div>
<div class="col-md-4 col-12">
<div class="card text-center">
<h3>{{ ogretmen_sayisi }}</h3>
<p>Öğretmen</p>
</div>
</div>
</div>
</div>
<canvas id="chart"></canvas>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
new Chart(document.getElementById("chart"), {
type: 'pie',
data: {
labels: ['Öğrenci', 'Öğretmen'],
datasets: [{
data: [{{ ogrenci_sayisi }}, {{ ogretmen_sayisi }}]
}]
}
});
</script>
{% endblock %}
✔ Responsive
✔ Mobil uyumlu
✔ Modern kart tasarımı
🎯 Sonuç
Artık sistemimiz:
✅ Otomatik not ortalaması
✅ Excel import
✅ PDF karne
✅ Full dark mode
✅ Mobil uyumlu dashboard
Bu artık basit proje değil — Gerçek bir okul otomasyonu admin paneli oldu 🚀
Artık sistemi gerçek bir okul otomasyonuna dönüştürüyoruz.
Altyapı yine:
Tema → Django Jazzmin
Grafik → Chart.js
🔔 1️⃣ Devamsızlık Sistemi
📌 models.py
class Devamsizlik(models.Model):
ogrenci = models.ForeignKey("Ogrenci", on_delete=models.CASCADE)
tarih = models.DateField()
durum = models.BooleanField(default=False) # True = Geldi, False = Gelmedi
aciklama = models.CharField(max_length=200, blank=True)
def __str__(self):
return f"{self.ogrenci} - {self.tarih}"
📌 Admin Ayarı
@admin.register(Devamsizlik)
class DevamsizlikAdmin(admin.ModelAdmin):
list_display = ("ogrenci", "tarih", "durum")
list_filter = ("tarih", "durum")
search_fields = ("ogrenci__ad", "ogrenci__soyad")
date_hierarchy = "tarih"
📌 Öğrenci Modeline Toplam Devamsızlık
def devamsizlik_sayisi(self):
return self.devamsizlik_set.filter(durum=False).count()
Admin’de:
list_display = ("ad", "soyad", "devamsizlik_sayisi")
🎉 Artık her öğrencinin devamsızlık sayısı görünüyor.
📅 2️⃣ Ders Programı Takvimi
📌 models.py
class DersProgrami(models.Model):
GUNLER = [
("Pzt", "Pazartesi"),
("Sal", "Salı"),
("Car", "Çarşamba"),
("Per", "Perşembe"),
("Cum", "Cuma"),
]
sinif = models.ForeignKey("Sinif", on_delete=models.CASCADE)
ders = models.ForeignKey("Ders", on_delete=models.CASCADE)
ogretmen = models.ForeignKey("Ogretmen", on_delete=models.CASCADE)
gun = models.CharField(max_length=3, choices=GUNLER)
saat = models.TimeField()
def __str__(self):
return f"{self.sinif} - {self.ders}"
📌 Admin
@admin.register(DersProgrami)
class DersProgramiAdmin(admin.ModelAdmin):
list_display = ("sinif", "ders", "ogretmen", "gun", "saat")
list_filter = ("sinif", "gun")
📌 Takvim Görünümü (Dashboard)
İstersen FullCalendar ekleyebiliriz ama basit liste için:
<table class="table">
<tr>
<th>Gün</th><th>Ders</th><th>Saat</th>
</tr>
{% for ders in ders_programlari %}
<tr>
<td>{{ ders.gun }}</td>
<td>{{ ders.ders }}</td>
<td>{{ ders.saat }}</td>
</tr>
{% endfor %}
</table>
Mobil uyumlu olur.
📊 3️⃣ Sınıf Bazlı İstatistik Grafik
Amaç:
Her sınıfın ortalaması
Devamsızlık oranı
📌 View
from django.db.models import Avg, Count
def sinif_istatistik(request):
veriler = Sinif.objects.annotate(
ortalama=Avg("ogrenci__not__puan"),
devamsizlik=Count("ogrenci__devamsizlik", filter=models.Q(ogrenci__devamsizlik__durum=False))
)
context = {
"siniflar": veriler
}
return TemplateResponse(request, "admin/sinif_chart.html", context)
📌 Chart.js Grafik
<canvas id="sinifChart"></canvas>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
new Chart(document.getElementById("sinifChart"), {
type: 'bar',
data: {
labels: [{% for s in siniflar %}"{{ s.ad }}",{% endfor %}],
datasets: [{
label: 'Ortalama',
data: [{% for s in siniflar %}{{ s.ortalama|default:0 }},{% endfor %}]
}]
}
});
</script>
🎉 Artık sınıf bazlı grafik var.
🔐 4️⃣ Öğretmen Sadece Kendi Öğrencilerini Görsün
Bu profesyonel bir özellik 👌
📌 Ogretmen Modeline User Bağlayalım
from django.contrib.auth.models import User
class Ogretmen(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
ad = models.CharField(max_length=50)
📌 Öğrenci Modeline Öğretmen Alanı
class Ogrenci(models.Model):
ogretmen = models.ForeignKey(Ogretmen, on_delete=models.CASCADE)
📌 Admin Filtreleme
class OgrenciAdmin(admin.ModelAdmin):
def get_queryset(self, request):
qs = super().get_queryset(request)
if request.user.is_superuser:
return qs
try:
ogretmen = Ogretmen.objects.get(user=request.user)
return qs.filter(ogretmen=ogretmen)
except Ogretmen.DoesNotExist:
return qs.none()
🎯 Sonuç:
Müdür → Tüm öğrencileri görür
Öğretmen → Sadece kendi öğrencilerini görür
🚀 Artık Sistemimiz
✅ Devamsızlık takibi
✅ Ders programı
✅ Sınıf grafikleri
✅ Rol bazlı veri güvenliği
✅ Modern admin tasarımı
Bu artık gerçek bir mini MEB otomasyonu seviyesinde 🎓
Artık sistemi Admin panelinden çıkarıp gerçek okul otomasyonuna dönüştürüyoruz.
Altyapı yine:
Backend → Django
Grafik → Chart.js
SMS → Twilio (örnek servis)
📱 1️⃣ Öğrenci Giriş Paneli (Ayrı Frontend)
Amaç:
Öğrenci giriş yapacak
Notlarını görecek
Devamsızlık durumunu görecek
Rozetlerini görecek
📌 Öğrenciye User Bağlama
from django.contrib.auth.models import User
class Ogrenci(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
ad = models.CharField(max_length=50)
soyad = models.CharField(max_length=50)
📌 Login Sistemi (views.py)
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
@login_required
def ogrenci_panel(request):
ogrenci = request.user.ogrenci
notlar = ogrenci.not_set.all()
devamsizlik = ogrenci.devamsizlik_set.filter(durum=False).count()
context = {
"ogrenci": ogrenci,
"notlar": notlar,
"devamsizlik": devamsizlik,
"ortalama": ogrenci.ortalama(),
}
return render(request, "ogrenci/panel.html", context)
📌 panel.html (Mobil Uyumlu)
<div class="container">
<h2>Hoşgeldin {{ ogrenci.ad }}</h2>
<div class="card">
<h4>Ortalama: {{ ortalama }}</h4>
<p>Devamsızlık: {{ devamsizlik }}</p>
</div>
<canvas id="notChart"></canvas>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
new Chart(document.getElementById("notChart"), {
type: 'bar',
data: {
labels: [{% for n in notlar %}"{{ n.ders.ad }}",{% endfor %}],
datasets: [{
label: 'Notlar',
data: [{% for n in notlar %}{{ n.puan }},{% endfor %}]
}]
}
});
</script>
🎉 Artık öğrenci kendi paneline sahip.
📩 2️⃣ Veli SMS Bildirim Sistemi
Amaç:
Devamsızlık olunca veliye SMS
Ortalama düşünce SMS
📌 Ogrenci Modeline Veli Telefon
veli_tel = models.CharField(max_length=15)
📌 SMS Gönderme Fonksiyonu
from twilio.rest import Client
def sms_gonder(numara, mesaj):
account_sid = "SID"
auth_token = "TOKEN"
client = Client(account_sid, auth_token)
client.messages.create(
body=mesaj,
from_="+123456789",
to=numara
)
📌 Devamsızlık Kaydedilince Otomatik SMS
from django.db.models.signals import post_save
from django.dispatch import receiver
@receiver(post_save, sender=Devamsizlik)
def devamsizlik_sms(sender, instance, created, **kwargs):
if created and instance.durum == False:
mesaj = f"{instance.ogrenci.ad} bugün okula gelmedi."
sms_gonder(instance.ogrenci.veli_tel, mesaj)
🎯 Artık veliye otomatik SMS gider.
📊 3️⃣ Karne Ortalamasına Göre Başarı Rozetleri
📌 Model
class Rozet(models.Model):
isim = models.CharField(max_length=50)
min_ortalama = models.FloatField()
📌 Öğrenciye Rozet Atama
def rozet_hesapla(self):
ort = self.ortalama()
if ort >= 90:
return "Altın Başarı"
elif ort >= 75:
return "Gümüş Başarı"
elif ort >= 60:
return "Bronz Başarı"
else:
return "Gelişim Gerekli"
Admin’de:
list_display = ("ad", "soyad", "ortalama", "rozet_hesapla")
Frontend’de rozet gösterilebilir:
<h3>Rozet: {{ ogrenci.rozet_hesapla }}</h3>
🔔 4️⃣ Otomatik Devamsızlık Uyarı Sistemi
Amaç:
3 gün üst üste gelmeyen öğrenciye SMS
5 gün devamsızlıkta müdüre bildirim
📌 Kontrol Fonksiyonu
def devamsizlik_kontrol(ogrenci):
devamsizlik_sayisi = ogrenci.devamsizlik_set.filter(durum=False).count()
if devamsizlik_sayisi >= 3:
sms_gonder(ogrenci.veli_tel, "3 gün devamsızlık yapıldı!")
if devamsizlik_sayisi >= 5:
print("Müdüre bildirildi")
📌 Signal İçine Ekleyelim
@receiver(post_save, sender=Devamsizlik)
def kontrol(sender, instance, created, **kwargs):
if created:
devamsizlik_kontrol(instance.ogrenci)
🚀 Şu An Sistemimiz
✅ Öğrenci giriş paneli
✅ Mobil uyumlu not grafiği
✅ Veli SMS sistemi
✅ Başarı rozetleri
✅ Otomatik devamsızlık alarmı
Bu artık mini e-Okul sistemi seviyesinde 🎓

Yorumlar
Yorum Gönder