Django REST API + Flutter Admin Panel
📌 1. shell Nedir?
python manage.py shell, Django projesinin içinde interaktif Python ortamı açmanı sağlar.
👉 Yani:
Kod yazarsın
Anında çalıştırırsun
Sonucu hemen görürsün
💡 Kısaca:
Django projenin içinde canlı test ortamıdır.
🚀 2. Shell Nasıl Açılır?
Proje klasöründe terminal aç:
python manage.py shell
Eğer kuruluysa daha gelişmiş versiyon:
python manage.py shell_plus
(django-extensions gerekir)
3. Shell Açıldığında Ne Olur?
Shell açıldığında:
Python 3.x.x (default, ...)
>>>
Artık Django projenin içindesin 🎯
📦 4. Model Kullanımı (EN ÖNEMLİ KISIM)
Örnek model:
# models.py
from django.db import models
class Student(models.Model):
name = models.CharField(max_length=100)
age = models.IntegerField()
📌 Shell'de kullanımı:
from app.models import Student
➕ 5. Veri Ekleme (CREATE)
student = Student(name="Ahmet", age=17)
student.save()
Alternatif kısa yöntem:
Student.objects.create(name="Mehmet", age=16)
📖 6. Veri Okuma (READ)
Tüm veriler:
Student.objects.all()
Tek veri:
Student.objects.get(id=1)
Filtreleme:
Student.objects.filter(age=17)
✏️ 7. Veri Güncelleme (UPDATE)
student = Student.objects.get(id=1)
student.age = 18
student.save()
❌ 8. Veri Silme (DELETE)
student = Student.objects.get(id=1)
student.delete()
🔍 9. Gelişmiş Query'ler
Büyük-küçük karşılaştırma:
Student.objects.filter(age__gt=16)
Student.objects.filter(age__lt=18)
İçeren arama:
Student.objects.filter(name__icontains="ah")
⚡ 10. Çoklu Veri İşlemleri
students = Student.objects.all()
for s in students:
print(s.name)
🔗 11. İlişkili Modeller (ForeignKey)
class Course(models.Model):
name = models.CharField(max_length=100)
class Student(models.Model):
name = models.CharField(max_length=100)
course = models.ForeignKey(Course, on_delete=models.CASCADE)
Shell:
course = Course.objects.create(name="Matematik")
Student.objects.create(name="Ali", course=course)
🧪 12. Shell ile Test Yazma Mantığı
Shell aslında:
API test etmek
Model test etmek
Hata ayıklamak
için kullanılır.
🧰 13. shell_plus (PRO SEVİYE)
Kur:
pip install django-extensions
settings.py:
INSTALLED_APPS = [
'django_extensions',
]
Çalıştır:
python manage.py shell_plus
🎯 Avantaj:
Tüm modeller otomatik import edilir
Yazmana gerek kalmaz
⚡ 14. En Çok Kullanılan Komutlar
# say
Student.objects.count()
# ilk kayıt
Student.objects.first()
# son kayıt
Student.objects.last()
# sıralama
Student.objects.order_by("age")
15. Shell'de Debug (Hata Ayıklama)
print(student.name)
type(student)
dir(student)
🚨 16. DİKKAT EDİLMESİ GEREKENLER
❗ Veritabanını direkt etkiler
❗ Yanlış silme işlemi geri alınamaz
❗ Production ortamda dikkatli kullan
💡 17. Gerçek Hayat Kullanım Senaryoları
API test etme
Admin panelden bağımsız veri ekleme
Hatalı verileri düzeltme
Veri analizi yapma
🔥 18. PRO İPUÇLARI
1. JSON veri ekleme:
import json
2. Toplu veri ekleme:
Student.objects.bulk_create([
Student(name="Ali", age=15),
Student(name="Veli", age=16),
])
🎯 19. Mini Uygulama (Gerçek Senaryo)
from app.models import Student
# veri ekle
Student.objects.create(name="Ayşe", age=17)
# filtrele
students = Student.objects.filter(age__gte=16)
# yazdır
for s in students:
print(s.name)
🏁 SONUÇ
python manage.py shell:
✔ Django öğrenmenin en hızlı yolu
✔ Backend geliştiricinin en güçlü aracı
✔ Gerçek zamanlı test ortamı
Aşağıda sana gerçek bir proje mantığında, sadecepython manage.py shell kullanarak çalışan bir Mini Admin Panel (CLI tabanlı).
Bu sistem sayesinde:
Admin panel olmadan veri yönetebileceksin
Komut yazar gibi CRUD işlemleri yapacaksın
Gerçek hayattaki backend mantığını öğreneceksin 🚀
PROJE: Shell ile Mini Admin Panel (CLI)
🎯 Amaç
Terminal üzerinden:
✔ Öğrenci ekle
✔ Listele
✔ Güncelle
✔ Sil
✔ Filtrele
📦 1. Model (Veritabanı)
# school/models.py
from django.db import models
class Student(models.Model):
name = models.CharField(max_length=100)
age = models.IntegerField()
email = models.EmailField()
def __str__(self):
return f"{self.name} ({self.age})"
⚙️ 2. Shell İçin Admin Fonksiyonları
👉 school/shell_admin.py dosyası oluştur:
from school.models import Student
# 🎯 Öğrenci ekle
def add_student():
name = input("İsim: ")
age = int(input("Yaş: "))
email = input("Email: ")
student = Student.objects.create(
name=name,
age=age,
email=email
)
print(f"✅ Eklendi: {student}")
# 📋 Listele
def list_students():
students = Student.objects.all()
if not students:
print("❌ Kayıt yok")
return
for s in students:
print(f"{s.id} - {s.name} - {s.age} - {s.email}")
# 🔍 Detay
def get_student():
id = int(input("ID: "))
try:
s = Student.objects.get(id=id)
print(s.name, s.age, s.email)
except:
print("❌ Bulunamadı")
# ✏️ Güncelle
def update_student():
id = int(input("Güncellenecek ID: "))
try:
s = Student.objects.get(id=id)
s.name = input(f"İsim ({s.name}): ") or s.name
s.age = int(input(f"Yaş ({s.age}): ") or s.age)
s.email = input(f"Email ({s.email}): ") or s.email
s.save()
print("✅ Güncellendi")
except:
print("❌ Hata")
# ❌ Sil
def delete_student():
id = int(input("Silinecek ID: "))
try:
s = Student.objects.get(id=id)
s.delete()
print("🗑 Silindi")
except:
print("❌ Bulunamadı")
# 🔍 Filtre
def filter_students():
age = int(input("Minimum yaş: "))
students = Student.objects.filter(age__gte=age)
for s in students:
print(s)
# 🧠 Menü sistemi
def menu():
while True:
print("\n--- MINI ADMIN PANEL ---")
print("1 - Öğrenci Ekle")
print("2 - Listele")
print("3 - Detay")
print("4 - Güncelle")
print("5 - Sil")
print("6 - Filtre")
print("0 - Çıkış")
choice = input("Seçim: ")
if choice == "1":
add_student()
elif choice == "2":
list_students()
elif choice == "3":
get_student()
elif choice == "4":
update_student()
elif choice == "5":
delete_student()
elif choice == "6":
filter_students()
elif choice == "0":
print("👋 Çıkılıyor...")
break
else:
print("❌ Hatalı seçim")
🚀 3. Shell'de Çalıştırma
Terminal:
python manage.py shell
Sonra:
from school.shell_admin import menu
menu()
🎉 Artık kendi terminal admin panelin çalışıyor!
🧪 4. Kullanım Senaryosu
--- MINI ADMIN PANEL ---
1 - Öğrenci Ekle
2 - Listele
3 - Detay
...
👉 1'e bas → veri gir → DB’ye kaydolur
👉 2'ye bas → tüm kayıtları gör
👉 4 → güncelle
👉 5 → sil
🔥 5. PRO GELİŞTİRMELER
Bunu gerçek projeye çevirmek için:
⚡ 1. Log sistemi ekle
import datetime
print(datetime.datetime.now())
⚡ 2. Yetkilendirme ekle
password = input("Admin şifre: ")
if password != "1234":
print("❌ Yetkisiz")
return
⚡ 3. JSON export/import
import json
def export_data():
data = list(Student.objects.values())
with open("students.json", "w") as f:
json.dump(data, f)
⚡ 4. Toplu veri ekleme
Student.objects.bulk_create([
Student(name="Ali", age=15, email="a@test.com"),
])
6. Bu Proje Sana Ne Kazandırır?
✔ Django ORM mastery
✔ Backend mantığı
✔ Admin panel mantığı
✔ CRUD gerçek kullanım
✔ CLI uygulama geliştirme
🏁 SONUÇ
Bu proje:
👉 Django Admin'in arka plan mantığını öğretir
👉 Gerçek backend geliştirici gibi düşünmeni sağlar
👉 Seni junior → mid level seviyeye taşır
🎯 PROJE: Mini Admin → Grafikli Dashboard (Django)
Ne Yapacağız?
Shell’de yaptığımız işlemleri şimdi web’e taşıyoruz:
✔ Öğrenci ekleme
✔ Listeleme
✔ Güncelleme / silme
✔ Grafikler (istatistikler)
✔ Modern dashboard UI
🏗️ 1. PROJE MİMARİSİ
project/
│
├── school/
│ ├── models.py
│ ├── views.py
│ ├── urls.py
│ ├── templates/
│ │ └── dashboard.html
│ └── static/
│ └── js/chart.js
📦 2. MODEL (Aynı kalıyor)
from django.db import models
class Student(models.Model):
name = models.CharField(max_length=100)
age = models.IntegerField()
email = models.EmailField()
def __str__(self):
return self.name
⚙️ 3. VIEW (Dashboard Mantığı)
# school/views.py
from django.shortcuts import render, redirect
from .models import Student
from django.db.models import Count
def dashboard(request):
students = Student.objects.all()
# 📊 Grafik verisi (yaşa göre dağılım)
age_data = (
Student.objects
.values('age')
.annotate(count=Count('age'))
.order_by('age')
)
ages = [item['age'] for item in age_data]
counts = [item['count'] for item in age_data]
context = {
"students": students,
"ages": ages,
"counts": counts
}
return render(request, "dashboard.html", context)
def add_student(request):
if request.method == "POST":
Student.objects.create(
name=request.POST["name"],
age=request.POST["age"],
email=request.POST["email"]
)
return redirect("dashboard")
return render(request, "add.html")
def delete_student(request, id):
Student.objects.get(id=id).delete()
return redirect("dashboard")
🌐 4. URL
# school/urls.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.dashboard, name="dashboard"),
path("add/", views.add_student, name="add"),
path("delete/<int:id>/", views.delete_student, name="delete"),
]
Ana urls.py:
path('', include('school.urls'))
🎨 5. TEMPLATE (Dashboard UI)
<!-- templates/dashboard.html -->
<!DOCTYPE html>
<html>
<head>
<title>Admin Dashboard</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
<h1>📊 Admin Dashboard</h1>
<a href="/add/">➕ Öğrenci Ekle</a>
<h2>📋 Öğrenciler</h2>
<ul>
{% for s in students %}
<li>
{{ s.name }} - {{ s.age }}
<a href="/delete/{{ s.id }}">❌</a>
</li>
{% endfor %}
</ul>
<h2>📈 Yaşa Göre Dağılım</h2>
<canvas id="chart"></canvas>
<script>
const ctx = document.getElementById('chart');
new Chart(ctx, {
type: 'bar',
data: {
labels: {{ ages|safe }},
datasets: [{
label: 'Öğrenci Sayısı',
data: {{ counts|safe }},
}]
}
});
</script>
</body>
</html>
➕ 6. ADD SAYFASI
<!-- templates/add.html -->
<h1>Öğrenci Ekle</h1>
<form method="POST">
{% csrf_token %}
<input name="name" placeholder="İsim">
<input name="age" placeholder="Yaş">
<input name="email" placeholder="Email">
<button type="submit">Kaydet</button>
</form>
🚀 7. ÇALIŞTIR
python manage.py runserver
Tarayıcı:
http://127.0.0.1:8000/
🎉 Artık gerçek bir dashboard’un var!
📊 8. NE ELDE ETTİN?
✔ Web tabanlı admin panel
✔ Gerçek grafik sistemi
✔ CRUD işlemleri
✔ Django + Frontend entegrasyonu
🔥 9. PRO GELİŞTİRMELER
🎨 1. Modern UI (Bootstrap)
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
⚡ 2. AJAX ile sayfa yenilemeden işlem
fetch("/delete/1/")
🔐 3. Login sistemi ekle
from django.contrib.auth.decorators import login_required
@login_required
def dashboard(request):
📊 4. Daha fazla grafik
Pasta grafik
Aylık kayıtlar
En aktif kullanıcılar
10. GERÇEK PROJE SEVİYESİ
Bunu şu seviyeye çıkarabiliriz:
🔥 Seviye 2
REST API (Django REST Framework)
React frontend
🔥 Seviye 3
Flutter mobil admin panel
🔥 Seviye 4
JWT + Role-based auth
🏁 SONUÇ
Sen şu an:
👉 Shell tabanlı sistem kurdun
👉 Onu web dashboard’a çevirdin
👉 Grafikli admin panel yaptın
💡 Bu = gerçek yazılım geliştirici seviyesi
Harika — şimdi projeyi tam profesyonel seviyeye çıkarıyoruz:
👉 Django backend + Flutter mobil Admin Panel (telefon uygulaması) 🚀
Bu sistemle:
Telefondan veri yönetebileceksin
Gerçek API kullanacaksın
Modern mobil UI öğreneceksin
🎯 PROJE: Flutter Mobil Admin Panel
Genel Mimari
Flutter App → Django REST API → Database
✔ Flutter = Mobil uygulama
✔ Django = Backend (API)
✔ JSON = Veri taşıma
🏗️ 1. DJANGO API (Backend)
Önce backend’i API haline getiriyoruz.
📦 Kurulum
pip install djangorestframework
settings.py:
INSTALLED_APPS = [
'rest_framework',
]
📌 Model (Aynı)
class Student(models.Model):
name = models.CharField(max_length=100)
age = models.IntegerField()
email = models.EmailField()
🔁 Serializer
# school/serializers.py
from rest_framework import serializers
from .models import Student
class StudentSerializer(serializers.ModelSerializer):
class Meta:
model = Student
fields = '__all__'
🌐 API View
# school/views.py
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .models import Student
from .serializers import StudentSerializer
@api_view(['GET'])
def get_students(request):
students = Student.objects.all()
serializer = StudentSerializer(students, many=True)
return Response(serializer.data)
@api_view(['POST'])
def add_student(request):
serializer = StudentSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
@api_view(['DELETE'])
def delete_student(request, id):
student = Student.objects.get(id=id)
student.delete()
return Response({"message": "deleted"})
🔗 URL
# school/urls.py
urlpatterns = [
path("api/students/", get_students),
path("api/add/", add_student),
path("api/delete/<int:id>/", delete_student),
]
🚀 Çalıştır
python manage.py runserver
📱 2. FLUTTER APP
📦 Paketler
dependencies:
http: ^0.13.6
Model
class Student {
final int id;
final String name;
final int age;
final String email;
Student({
required this.id,
required this.name,
required this.age,
required this.email,
});
factory Student.fromJson(Map<String, dynamic> json) {
return Student(
id: json['id'],
name: json['name'],
age: json['age'],
email: json['email'],
);
}
}
🌐 API Service
import 'dart:convert';
import 'package:http/http.dart' as http;
class ApiService {
static const String baseUrl = "http://10.0.2.2:8000/api/";
static Future<List<Student>> getStudents() async {
final response = await http.get(Uri.parse("${baseUrl}students/"));
final data = json.decode(response.body);
return data.map<Student>((e) => Student.fromJson(e)).toList();
}
static Future<void> addStudent(String name, int age, String email) async {
await http.post(
Uri.parse("${baseUrl}add/"),
body: {
"name": name,
"age": age.toString(),
"email": email,
},
);
}
static Future<void> deleteStudent(int id) async {
await http.delete(Uri.parse("${baseUrl}delete/$id/"));
}
}
🎨 3. UI (Admin Panel)
📋 Ana Ekran
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
List students = [];
void fetchStudents() async {
final data = await ApiService.getStudents();
setState(() {
students = data;
});
}
@override
void initState() {
super.initState();
fetchStudents();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Admin Panel")),
body: ListView.builder(
itemCount: students.length,
itemBuilder: (context, i) {
final s = students[i];
return ListTile(
title: Text(s.name),
subtitle: Text("${s.age}"),
trailing: IconButton(
icon: Icon(Icons.delete),
onPressed: () async {
await ApiService.deleteStudent(s.id);
fetchStudents();
},
),
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (_) => AddPage()));
},
child: Icon(Icons.add),
),
);
}
}
➕ Veri Ekleme Sayfası
class AddPage extends StatelessWidget {
final name = TextEditingController();
final age = TextEditingController();
final email = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Ekle")),
body: Column(
children: [
TextField(controller: name, decoration: InputDecoration(labelText: "İsim")),
TextField(controller: age, decoration: InputDecoration(labelText: "Yaş")),
TextField(controller: email, decoration: InputDecoration(labelText: "Email")),
ElevatedButton(
onPressed: () async {
await ApiService.addStudent(
name.text,
int.parse(age.text),
email.text,
);
Navigator.pop(context);
},
child: Text("Kaydet"),
)
],
),
);
}
}
🔥 4. ÇALIŞTIRMA
flutter run
📱 Emulator için:
http://10.0.2.2:8000
5. NE YAPTIN?
✔ Backend API yazdın
✔ Mobil uygulama yaptın
✔ Gerçek client-server sistemi kurdun
✔ CRUD işlemlerini mobilde yönettin
🚀 6. PRO GELİŞTİRME
🔐 JWT Authentication
Admin login sistemi
🎨 UI Upgrade
Material 3
Dark mode
⚡ State Management
Provider / Riverpod
📊 Grafik ekleme
charts_flutter
🏁 SONUÇ
Bu proje:
👉 Gerçek şirket projelerine %80 benzer
👉 Seni full-stack developer yapar
👉 CV’ye yazılacak seviyede
Şimdi Flutter admin panelini gerçek dashboard seviyesine çıkarıyoruz:
👉 📊 Mobilde Grafik Dashboard (Chart) sistemi
Bu sayede:
Verileri grafikle göstereceksin
Admin panel profesyonel görünecek
Gerçek uygulama hissi oluşacak
🎯 HEDEF
Flutter uygulamada:
✔ Bar Chart (yaşa göre dağılım)
✔ Dinamik veri (API’den geliyor)
✔ Dashboard ekranı
📦 1. Flutter Chart Paketi
En iyi paketlerden biri:
dependencies:
fl_chart: ^0.66.0
Kur:
flutter pub get
2. Django API (Grafik Veri)
Backend’e özel endpoint ekliyoruz:
# views.py
from django.db.models import Count
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .models import Student
@api_view(['GET'])
def student_stats(request):
data = (
Student.objects
.values('age')
.annotate(count=Count('age'))
.order_by('age')
)
return Response(list(data))
🔗 URL
path("api/stats/", student_stats),
📊 Dönen JSON
[
{ "age": 15, "count": 2 },
{ "age": 16, "count": 5 },
{ "age": 17, "count": 3 }
]
🌐 3. Flutter API Servisi
static Future<List<Map<String, dynamic>>> getStats() async {
final response =
await http.get(Uri.parse("${baseUrl}stats/"));
return List<Map<String, dynamic>>.from(
json.decode(response.body));
}
📊 4. Dashboard UI (Chart)
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
class ChartPage extends StatefulWidget {
@override
_ChartPageState createState() => _ChartPageState();
}
class _ChartPageState extends State<ChartPage> {
List data = [];
void fetchStats() async {
final result = await ApiService.getStats();
setState(() {
data = result;
});
}
@override
void initState() {
super.initState();
fetchStats();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("📊 Dashboard")),
body: Padding(
padding: EdgeInsets.all(16),
child: BarChart(
BarChartData(
barGroups: data.map((e) {
return BarChartGroupData(
x: e['age'],
barRods: [
BarChartRodData(
toY: e['count'].toDouble(),
)
],
);
}).toList(),
),
),
),
);
}
}
🔗 5. Ana Menüye Ekle
ElevatedButton(
child: Text("📊 Dashboard"),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (_) => ChartPage()),
);
},
)
🎨 6. UI Geliştirme (PRO)
Daha profesyonel görünüm için:
BarChartRodData(
toY: e['count'].toDouble(),
width: 16,
borderRadius: BorderRadius.circular(4),
)
🔥 7. EKSTRA GRAFİKLER
📈 Line Chart (zaman serisi)
Günlük kayıtlar
Kullanıcı artışı
🥧 Pie Chart
Yaş oranları
Kullanıcı türleri
8. GERÇEK PROJE MANTIĞI
Bu yapı:
✔ Backend → veri üretir
✔ API → veriyi taşır
✔ Flutter → görselleştirir
👉 Bu = full-stack dashboard mimarisi
🚀 9. PRO SEVİYE UPGRADE
İstersen bunu şu seviyeye çıkarabiliriz:
🔐 JWT + Admin login
⚡ Realtime grafik (WebSocket)
🎨 Dark mode + animasyon
🧠 AI analiz (trend tahmini)
🏁 SONUÇ
Artık sen:
✔ CRUD yapan mobil app
✔ API kullanan sistem
✔ Grafik dashboard
yaptın 🎯
👉 Bu seviye = gerçek startup projesi seviyesi
Mükemmel — artık projeyi gerçek şirket seviyesine çıkarıyoruz 🚀
Bu üç sistemi tek bir profesyonel mimaride birleştireceğiz:
👉 🔐 JWT Login (yetkili giriş)
👉 ⚡ Realtime Dashboard (canlı grafik)
👉 🧱 Flutter Clean Architecture
GENEL MİMARİ (PRO)
Flutter (Clean Architecture)
↓
Repository Layer
↓
Django REST API (JWT)
↓
WebSocket (Realtime)
↓
Database
🔐 1. JWT LOGIN SİSTEMİ (Django)
📦 Kurulum
pip install djangorestframework-simplejwt
⚙️ settings.py
from datetime import timedelta
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
),
}
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=60),
}
🔑 URL
from rest_framework_simplejwt.views import TokenObtainPairView
urlpatterns = [
path('api/login/', TokenObtainPairView.as_view()),
]
📥 Login Request
{
"username": "admin",
"password": "1234"
}
📤 Response
{
"access": "TOKEN",
"refresh": "TOKEN"
}
📱 2. FLUTTER JWT LOGIN
🌐 API Service
static Future<String?> login(String username, String password) async {
final response = await http.post(
Uri.parse("${baseUrl}login/"),
body: {
"username": username,
"password": password,
},
);
final data = json.decode(response.body);
return data["access"];
}
🔐 Token Saklama
import 'package:shared_preferences/shared_preferences.dart';
Future<void> saveToken(String token) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString("token", token);
}
📡 Token ile API çağrısı
final response = await http.get(
Uri.parse("${baseUrl}students/"),
headers: {
"Authorization": "Bearer $token"
},
);
⚡ 3. REALTIME DASHBOARD (WebSocket)
📦 Django Channels
pip install channels
⚙️ settings.py
ASGI_APPLICATION = "project.asgi.application"
🔌 Consumer
# consumers.py
from channels.generic.websocket import AsyncWebsocketConsumer
import json
class DashboardConsumer(AsyncWebsocketConsumer):
async def connect(self):
await self.accept()
async def send_update(self, event):
await self.send(text_data=json.dumps(event["data"]))
📊 Veri gönderme (signal)
from asgiref.sync import async_to_sync
from channels.layers import get_channel_layer
def send_dashboard_update(data):
channel_layer = get_channel_layer()
async_to_sync(channel_layer.group_send)(
"dashboard",
{
"type": "send_update",
"data": data
}
)
📱 Flutter WebSocket
import 'package:web_socket_channel/web_socket_channel.dart';
final channel = WebSocketChannel.connect(
Uri.parse('ws://10.0.2.2:8000/ws/dashboard/')
);
channel.stream.listen((data) {
print("Yeni veri: $data");
});
🧱 4. FLUTTER CLEAN ARCHITECTURE
📁 Klasör Yapısı
lib/
│
├── core/
│ ├── network/
│ └── utils/
│
├── features/
│ ├── auth/
│ │ ├── data/
│ │ ├── domain/
│ │ └── presentation/
│ │
│ └── student/
│ ├── data/
│ ├── domain/
│ └── presentation/
🧠 Katmanlar
1. Presentation (UI)
Flutter ekranları
2. Domain
Business logic
UseCase
3. Data
API çağrıları
📌 Örnek UseCase
class GetStudents {
final StudentRepository repo;
GetStudents(this.repo);
Future execute() {
return repo.getStudents();
}
}
📌 Repository
abstract class StudentRepository {
Future<List<Student>> getStudents();
}
📌 API Implementasyonu
class StudentRepositoryImpl implements StudentRepository {
final ApiService api;
StudentRepositoryImpl(this.api);
@override
Future<List<Student>> getStudents() {
return api.getStudents();
}
}
🎯 5. PRO SEVİYE ÖZELLİKLER
✔ Token refresh sistemi
✔ Auto login
✔ Role-based access (admin/user)
✔ Offline cache
✔ Error handling
6. SEN NE YAPTIN?
Şu an:
✔ JWT güvenlik sistemi
✔ Realtime veri akışı
✔ Clean architecture
kurmuş oldun.
👉 Bu = gerçek şirket backend + mobil mimarisi
🏁 SONUÇ
Bu proje:
💼 CV’ye yazılır
💼 Staj / iş görüşmesinde gösterilir
💼 Gerçek startup altyapısıdır
🧱 1. PROJE KLASÖR YAPISI (FULL-STACK)
django_flutter_admin/
│
├── backend/ (Django)
│ ├── manage.py
│ ├── config/
│ │ ├── settings.py
│ │ ├── urls.py
│ │ └── asgi.py
│ │
│ ├── apps/
│ │ ├── users/
│ │ ├── students/
│ │ └── dashboard/
│ │
│ ├── core/
│ │ ├── permissions.py
│ │ ├── utils.py
│ │ └── signals.py
│ │
│ └── requirements.txt
│
├── mobile/ (Flutter)
│ ├── lib/
│ │ ├── core/
│ │ │ ├── network/
│ │ │ └── storage/
│ │ │
│ │ ├── features/
│ │ │ ├── auth/
│ │ │ ├── student/
│ │ │ └── dashboard/
│ │ │
│ │ └── main.dart
│ │
│ └── pubspec.yaml
│
└── README.md
📄 2. GITHUB README (PROFESYONEL)
Aşağıyı direkt GitHub’a koyabilirsin:
🚀 Django + Flutter Mobil Admin Panel
📱 Proje Hakkında
Bu proje, Django REST API ve Flutter kullanılarak geliştirilmiş mobil admin panel uygulamasıdır.
🎯 Özellikler
🔐 JWT Authentication (güvenli giriş)
📊 Dashboard (grafik & analiz)
⚡ Realtime veri (WebSocket)
📱 Flutter mobil uygulama
🧱 Clean Architecture
🏗️ Teknolojiler
Backend
Django
Django REST Framework
SimpleJWT
Django Channels
Mobile
Flutter
HTTP
WebSocket
fl_chart
⚙️ Kurulum
Backend
cd backend
pip install -r requirements.txt
python manage.py migrate
python manage.py runserver
Mobile
cd mobile
flutter pub get
flutter run
🔐 API Endpoints
| Endpoint | Açıklama |
|---|---|
| /api/login | JWT login |
| /api/students | Liste |
| /api/add | Ekle |
| /api/delete/{id} | Sil |
| /api/stats | Grafik veri |
📊 Dashboard
Bar Chart
Realtime veri
Kullanıcı yönetimi
Mimari
Flutter → Repository → API → Django → Database
🚀 Gelecek Özellikler
🔔 Push Notification
☁️ Cloud deployment
🧠 AI analiz sistemi
👨💻 Geliştirici
Bu proje eğitim ve portföy amaçlı geliştirilmiştir.
🎨 3. UI/UX TASARIM (FIGMA SEVİYESİ)
Şimdi sana gerçek uygulama gibi ekran planı veriyorum:
📱 1. LOGIN SCREEN
🧩 Bileşenler:
Logo (üstte)
Email / Password input
“Giriş Yap” butonu
Dark theme
📊 2. DASHBOARD
🧩 İçerik:
Üstte: “Hoş geldin Admin”
Kartlar:
Toplam öğrenci
Bugünkü kayıt
Grafik:
Bar Chart
Alt menü (Bottom Navigation)
👥 3. STUDENT LIST
🧩 Özellikler:
ListView
Arama barı
Swipe → silme
FAB → ekleme
➕ 4. ADD STUDENT
🧩 Form:
İsim
Yaş
Email
Kaydet butonu
⚡ 5. REALTIME PANEL
🧩 Özellikler:
Canlı veri akışı
Animasyonlu grafik
“Live” etiketi
🎯 RENK PALETİ (PRO)
Primary: #2563EB (mavi)
Secondary: #0F172A (koyu)
Accent: #22C55E (yeşil)
Background: #F8FAFC
UX İPUÇLARI
✔ Minimal tasarım
✔ Büyük butonlar
✔ Hızlı erişim
✔ Loading animasyonu
✔ Hata mesajları
🔥 SONUÇ
Artık elinde:
✔ GitHub projesi
✔ Profesyonel README
✔ Gerçek UI/UX planı
var.
👉 Bu = portföy projesi + iş seviyesi uygulama
💻 📦 FULL PROJE (Backend + Mobile)
🧱 BACKEND (Django)
📁 backend/requirements.txt
Django
djangorestframework
djangorestframework-simplejwt
channels
📁 backend/config/settings.py (ÖNEMLİ KISIMLAR)
INSTALLED_APPS = [
'rest_framework',
'channels',
'apps.students',
]
from datetime import timedelta
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
),
}
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=60),
}
ASGI_APPLICATION = "config.asgi.application"
📁 backend/apps/students/models.py
from django.db import models
class Student(models.Model):
name = models.CharField(max_length=100)
age = models.IntegerField()
email = models.EmailField()
def __str__(self):
return self.name
📁 backend/apps/students/serializers.py
from rest_framework import serializers
from .models import Student
class StudentSerializer(serializers.ModelSerializer):
class Meta:
model = Student
fields = '__all__'
📁 backend/apps/students/views.py
from rest_framework.decorators import api_view
from rest_framework.response import Response
from django.db.models import Count
from .models import Student
from .serializers import StudentSerializer
@api_view(['GET'])
def get_students(request):
students = Student.objects.all()
return Response(StudentSerializer(students, many=True).data)
@api_view(['POST'])
def add_student(request):
serializer = StudentSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
@api_view(['DELETE'])
def delete_student(request, id):
Student.objects.get(id=id).delete()
return Response({"status": "deleted"})
@api_view(['GET'])
def stats(request):
data = (
Student.objects
.values('age')
.annotate(count=Count('age'))
.order_by('age')
)
return Response(list(data))
📁 backend/config/urls.py
from django.contrib import admin
from django.urls import path
from apps.students import views
from rest_framework_simplejwt.views import TokenObtainPairView
urlpatterns = [
path('admin/', admin.site.urls),
# JWT
path('api/login/', TokenObtainPairView.as_view()),
# Student API
path('api/students/', views.get_students),
path('api/add/', views.add_student),
path('api/delete/<int:id>/', views.delete_student),
path('api/stats/', views.stats),
]
🚀 Backend çalıştır
cd backend
pip install -r requirements.txt
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser
python manage.py runserver
📱 FLUTTER (Mobile)
📁 mobile/pubspec.yaml
dependencies:
flutter:
sdk: flutter
http: ^0.13.6
fl_chart: ^0.66.0
shared_preferences: ^2.2.2
web_socket_channel: ^2.4.0
📁 mobile/lib/core/network/api_service.dart
import 'dart:convert';
import 'package:http/http.dart' as http;
class ApiService {
static const baseUrl = "http://10.0.2.2:8000/api/";
static Future<String?> login(String u, String p) async {
final res = await http.post(
Uri.parse("${baseUrl}login/"),
body: {"username": u, "password": p},
);
final data = json.decode(res.body);
return data["access"];
}
static Future<List> getStudents(String token) async {
final res = await http.get(
Uri.parse("${baseUrl}students/"),
headers: {"Authorization": "Bearer $token"},
);
return json.decode(res.body);
}
static Future<void> addStudent(
String name, String age, String email) async {
await http.post(Uri.parse("${baseUrl}add/"), body: {
"name": name,
"age": age,
"email": email,
});
}
static Future<List> getStats() async {
final res = await http.get(Uri.parse("${baseUrl}stats/"));
return json.decode(res.body);
}
}
📁 mobile/lib/main.dart
import 'package:flutter/material.dart';
import 'core/network/api_service.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(home: LoginPage());
}
}
🔐 LOGIN PAGE
class LoginPage extends StatefulWidget {
@override
_LoginState createState() => _LoginState();
}
class _LoginState extends State<LoginPage> {
final u = TextEditingController();
final p = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
TextField(controller: u),
TextField(controller: p),
ElevatedButton(
onPressed: () async {
final token = await ApiService.login(u.text, p.text);
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => HomePage(token!),
),
);
},
child: Text("Login"),
)
],
),
);
}
}
📊 HOME + DASHBOARD
import 'package:fl_chart/fl_chart.dart';
class HomePage extends StatefulWidget {
final String token;
HomePage(this.token);
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<HomePage> {
List students = [];
List stats = [];
void load() async {
students = await ApiService.getStudents(widget.token);
stats = await ApiService.getStats();
setState(() {});
}
@override
void initState() {
super.initState();
load();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Dashboard")),
body: Column(
children: [
// 📊 Chart
SizedBox(
height: 200,
child: BarChart(
BarChartData(
barGroups: stats.map((e) {
return BarChartGroupData(
x: e['age'],
barRods: [
BarChartRodData(
toY: e['count'].toDouble(),
)
],
);
}).toList(),
),
),
),
// 📋 Liste
Expanded(
child: ListView.builder(
itemCount: students.length,
itemBuilder: (_, i) {
return ListTile(
title: Text(students[i]['name']),
);
},
),
)
],
),
);
}
}
🏁 SONUÇ
Bu proje:
✔ JWT login
✔ CRUD API
✔ Mobil app
✔ Grafik dashboard
✔ Full-stack yapı
Django Kaynak Kod: https://github.com/nuritiras/adminpanel.git
Flutter Kaynak Kod : https://github.com/nuritiras/flutter_admin_panel.git
🎨 📱 FIGMA TASARIM DOSYASI (MOBİL ADMIN PANEL)
🧱 1. Figma Sayfa Yapısı
Figma’da Pages (Sayfalar) oluştur:
📄 Pages
├── 01_Auth
├── 02_Dashboard
├── 03_Students
├── 04_Add_Student
├── 05_Realtime
├── 06_Components
🔐 2. LOGIN SCREEN (Frame)
📐 Frame
Size: 390 x 844 (iPhone 13)
Background: #0F172A (dark)
🧩 Bileşenler
[ Logo ]
[ Başlık: "Admin Panel" ]
[ Input: Email ]
[ Input: Şifre ]
[ Button: Giriş Yap ]
[ Küçük text: "Şifremi unuttum" ]
🎨 Stil
Input: rounded (12px)
Button: #2563EB (primary blue)
Text: white
📊 3. DASHBOARD SCREEN
🧩 Üst Alan
👋 Hoş geldin, Admin
📅 22 Mart
📦 KPI Kartları
[ 👥 Toplam Öğrenci: 120 ]
[ 📈 Bugün Eklenen: 5 ]
👉 Card:
Radius: 16px
Shadow: soft
Padding: 16
📊 Grafik Alanı
📊 Yaş Dağılımı
[ Bar Chart ]
👉 Figma’da:
Rectangle barlar çiz
Auto layout kullan
📋 Son Öğrenciler
Ali - 17
Ayşe - 16
Mehmet - 15
📱 Bottom Navigation
[🏠] [📊] [👥] [⚙️]
👥 4. STUDENT LIST SCREEN
🧩 Üst
🔍 Search Bar
📋 Liste
[ Avatar ] Ali - 17 🗑
[ Avatar ] Ayşe - 16 🗑
👉 Swipe action hissi için:
sağa ikon koy
➕ FAB Button
( + )
Sağ alt
Renk: #22C55E
➕ 5. ADD STUDENT SCREEN
🧩 Form
İsim
Yaş
Email
[ Kaydet Butonu ]
🎨 UX
Input spacing: 16px
Button full width
⚡ 6. REALTIME DASHBOARD
🧩
🔴 LIVE
📊 Grafik (animasyon hissi)
📥 Son Gelen Veri:
"Yeni öğrenci eklendi"
🧱 7. COMPONENT SYSTEM (EN ÖNEMLİ)
Figma’da Components oluştur:
🎯 Buttons
Primary
Secondary
🎯 Inputs
Default
Focus
Error
🎯 Cards
KPI Card
List Item
🎨 8. DESIGN SYSTEM
🌈 Renkler
Primary: #2563EB
Dark: #0F172A
Background:#F8FAFC
Success: #22C55E
Danger: #EF4444
🔤 Font
Başlık: Bold
İçerik: Regular
Font: Inter / Roboto
⚙️ 9. AUTO LAYOUT (ÇOK ÖNEMLİ)
Her şeyi:
✔ Auto Layout ile yap
✔ Spacing: 8 / 16 / 24 sistemi
✔ Responsive düşün
10. PRO TASARIM İPUÇLARI
✔ Boşluk kullan (whitespace)
✔ Çok renk kullanma
✔ Tutarlılık = profesyonellik
✔ Aynı component tekrar kullan
🏁 SONUÇ
Bu tasarımı Figma’da kurarsan:
👉 Gerçek mobil app UI
👉 Portföy seviyesi tasarım
👉 Flutter’a birebir aktarılabilir
Yorumlar
Yorum Gönder