{"id":31916,"date":"2025-10-15T14:41:06","date_gmt":"2025-10-15T11:41:06","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/?p=31916"},"modified":"2025-10-15T14:41:06","modified_gmt":"2025-10-15T11:41:06","slug":"digitalocean-api-verilerini-django-ile-goruntuleme-rehberi","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/digitalocean-api-verilerini-django-ile-goruntuleme-rehberi\/","title":{"rendered":"DigitalOcean API Verilerini Django ile G\u00f6r\u00fcnt\u00fcleme Rehberi"},"content":{"rendered":"<p><body><\/p>\n<h2>DigitalOcean API Verilerini Django ile G\u00f6r\u00fcnt\u00fcleme Rehberi<\/h2>\n<h3>Giri\u015f<\/h3>\n<p>G\u00fcn\u00fcm\u00fcz\u00fcn bulut tabanl\u0131 altyap\u0131lar\u0131, geli\u015ftiricilere ve sistem y\u00f6neticilerine kaynaklar\u0131n\u0131 programatik olarak y\u00f6netme yetene\u011fi sunar. DigitalOcean, sundu\u011fu basit ve g\u00fc\u00e7l\u00fc API&#8217;si ile bu programatik y\u00f6netimi kolayla\u015ft\u0131r\u0131r. Bir yandan da Django, Python tabanl\u0131, &#8220;pil dahil&#8221; felsefesiyle h\u0131zl\u0131 ve g\u00fcvenli web uygulamalar\u0131 geli\u015ftirmek i\u00e7in pop\u00fcler bir \u00e7er\u00e7evedir. DigitalOcean API&#8217;sinden al\u0131nan verileri bir Django uygulamas\u0131 i\u00e7inde g\u00f6r\u00fcnt\u00fclemek, \u00f6zel kontrol panelleri olu\u015fturmak, otomasyon s\u00fcre\u00e7lerini izlemek veya bulut kaynaklar\u0131n\u0131n durumunu kolayca g\u00f6rselle\u015ftirmek i\u00e7in harika bir yoldur.<\/p>\n<p>Bu kapsaml\u0131 teknik makalede, DigitalOcean API&#8217;sinden veri \u00e7ekmek, bu verileri Django modellerine entegre etmek ve son olarak kullan\u0131c\u0131 dostu bir aray\u00fczle web sayfan\u0131zda g\u00f6r\u00fcnt\u00fclemek i\u00e7in ad\u0131m ad\u0131m bir rehber sunaca\u011f\u0131z. Ayr\u0131ca, g\u00fcvenlik, performans ve en iyi uygulamalar gibi konulara da de\u011finece\u011fiz.<\/p>\n<h3>Neden DigitalOcean API ve Django?<\/h3>\n<p>DigitalOcean API&#8217;si, Droplet&#8217;ler, domain&#8217;ler, depolama birimleri, g\u00fcvenlik duvarlar\u0131 ve daha fazlas\u0131 dahil olmak \u00fczere DigitalOcean kaynaklar\u0131n\u0131z\u0131 programatik olarak y\u00f6netmenize olanak tan\u0131r. Bu, manuel i\u015flemleri otomatikle\u015ftirmek, \u00f6zel izleme \u00e7\u00f6z\u00fcmleri olu\u015fturmak veya CI\/CD s\u00fcre\u00e7lerinizi entegre etmek i\u00e7in g\u00fc\u00e7l\u00fc bir ara\u00e7t\u0131r.<\/p>\n<p>Django ise, h\u0131zl\u0131 geli\u015ftirme d\u00f6ng\u00fcleri, ORM (Object-Relational Mapper) deste\u011fi, g\u00fc\u00e7l\u00fc \u015fablon motoru, admin paneli ve kapsaml\u0131 g\u00fcvenlik \u00f6zellikleri ile karma\u015f\u0131k web uygulamalar\u0131 geli\u015ftirmek i\u00e7in idealdir. DigitalOcean API&#8217;sinden gelen verileri Django ile birle\u015ftirmek, bu verileri kullan\u0131c\u0131 aray\u00fcz\u00fcnde sunarken Django&#8217;nun t\u00fcm avantajlar\u0131ndan yararlanman\u0131z\u0131 sa\u011flar. \u00d6rne\u011fin:<\/p>\n<ul>\n<li><strong>\u00d6zelle\u015ftirilmi\u015f Paneller:<\/strong> Kendi ihtiya\u00e7lar\u0131n\u0131za g\u00f6re DigitalOcean kaynaklar\u0131n\u0131z\u0131n durumunu g\u00f6steren paneller olu\u015fturabilirsiniz.<\/li>\n<li><strong>Otomasyon \u0130zleme:<\/strong> Otomatikle\u015ftirilmi\u015f i\u015flemlerin sonu\u00e7lar\u0131n\u0131 veya durumlar\u0131n\u0131 bir web aray\u00fcz\u00fcnden takip edebilirsiniz.<\/li>\n<li><strong>Veri G\u00f6rselle\u015ftirme:<\/strong> \u00c7ekilen veriler \u00fczerinde grafikler ve tablolar olu\u015fturarak daha anlaml\u0131 i\u00e7g\u00f6r\u00fcler elde edebilirsiniz.<\/li>\n<li><strong>Entegrasyon:<\/strong> DigitalOcean verilerini di\u011fer sistemlerinizle (\u00f6rne\u011fin, faturaland\u0131rma veya envanter sistemleri) entegre edebilirsiniz.<\/li>\n<\/ul>\n<h3>\u00d6n Gereksinimler<\/h3>\n<p>Bu rehberi takip edebilmek i\u00e7in a\u015fa\u011f\u0131daki \u00f6n gereksinimlere sahip olman\u0131z gerekmektedir:<\/p>\n<ul>\n<li><strong>Python 3.x:<\/strong> Sisteminizde Python y\u00fckl\u00fc olmal\u0131d\u0131r.<\/li>\n<li><strong>Django:<\/strong> Python sanal ortam\u0131n\u0131zda Django kurulu olmal\u0131d\u0131r.<\/li>\n<li><strong>DigitalOcean Hesab\u0131:<\/strong> Aktif bir DigitalOcean hesab\u0131n\u0131z olmal\u0131d\u0131r.<\/li>\n<li><strong>DigitalOcean API Token:<\/strong> DigitalOcean hesab\u0131n\u0131zdan bir Personal Access Token (PAT) olu\u015fturmu\u015f olman\u0131z gerekmektedir. Bu token&#8217;\u0131 g\u00fcvenli bir yerde saklay\u0131n, \u00e7\u00fcnk\u00fc API isteklerinizde kimlik do\u011frulamas\u0131 i\u00e7in kullan\u0131lacakt\u0131r.<\/li>\n<li><strong>Temel Python ve Django Bilgisi:<\/strong> Django projesi olu\u015fturma, uygulama tan\u0131mlama, view&#8217;lar ve \u015fablonlar hakk\u0131nda temel bilgiye sahip olman\u0131z beklenir.<\/li>\n<\/ul>\n<h3>DigitalOcean API&#8217;ye Genel Bak\u0131\u015f ve API Token Olu\u015fturma<\/h3>\n<p>DigitalOcean API&#8217;si, RESTful bir mimariye sahiptir ve JSON format\u0131nda veri d\u00f6nd\u00fcr\u00fcr. API&#8217;ye yap\u0131lan t\u00fcm istekler, bir Personal Access Token (PAT) ile kimlik do\u011frulamas\u0131 gerektirir.<\/p>\n<h4>API Token Olu\u015fturma<\/h4>\n<ol>\n<li>DigitalOcean hesab\u0131n\u0131za giri\u015f yap\u0131n.<\/li>\n<li>Sol men\u00fcden &#8220;API&#8221; sekmesine gidin.<\/li>\n<li>&#8220;Tokens\/Keys&#8221; alt\u0131nda &#8220;Generate New Token&#8221; d\u00fc\u011fmesine t\u0131klay\u0131n.<\/li>\n<li>Token&#8217;\u0131n\u0131za a\u00e7\u0131klay\u0131c\u0131 bir isim verin (\u00f6rn: &#8220;DjangoAppToken&#8221;).<\/li>\n<li>Token&#8217;\u0131n izinlerini se\u00e7in. Verileri sadece g\u00f6r\u00fcnt\u00fclemek i\u00e7in &#8220;Read&#8221; izinleri yeterli olacakt\u0131r. E\u011fer kaynaklar\u0131 y\u00f6netmek isterseniz &#8220;Write&#8221; izinlerini de vermeniz gerekebilir. Ancak g\u00fcvenlik a\u00e7\u0131s\u0131ndan her zaman en az yetki prensibini uygulay\u0131n.<\/li>\n<li>&#8220;Generate Token&#8221; d\u00fc\u011fmesine t\u0131klay\u0131n.<\/li>\n<li>Olu\u015fturulan token&#8217;\u0131 kopyalay\u0131n. <strong>Bu token&#8217;\u0131 sadece bir kez g\u00f6rebilirsiniz, bu y\u00fczden hemen g\u00fcvenli bir yere kaydedin.<\/strong><\/li>\n<\/ol>\n<p>Bu token, API isteklerinizin <code>Authorization<\/code> ba\u015fl\u0131\u011f\u0131nda <code>Bearer <YOUR_TOKEN><\/code> \u015feklinde g\u00f6nderilecektir.<\/p>\n<h3>Django Projesi Kurulumu<\/h3>\n<p>\u015eimdi bir Django projesi olu\u015ftural\u0131m ve DigitalOcean API verilerini g\u00f6r\u00fcnt\u00fclemek i\u00e7in gerekli temel yap\u0131land\u0131rmay\u0131 yapal\u0131m.<\/p>\n<h4>1. Sanal Ortam Olu\u015fturma ve Django Kurulumu<\/h4>\n<pre><code class=\"language-bash\">mkdir digitalocean_dashboard\ncd digitalocean_dashboard\npython3 -m venv venv\nsource venv\/bin\/activate  # Linux\/macOS\n<h2>venv\\Scripts\\activate  # Windows<\/h2>\npip install django requests python-digitalocean django-environ<\/code><\/pre>\n<p><code>requests<\/code> k\u00fct\u00fcphanesi, HTTP istekleri yapmak i\u00e7in kullan\u0131lacak. <code>python-digitalocean<\/code> ise DigitalOcean API&#8217;si i\u00e7in resmi olmayan ancak pop\u00fcler bir Python istemcisidir. Bu rehberde <code>requests<\/code> k\u00fct\u00fcphanesini do\u011frudan kullanarak API etkile\u015fimini daha temel seviyede g\u00f6sterece\u011fiz, ancak <code>python-digitalocean<\/code> k\u00fct\u00fcphanesini kullanmak genellikle daha kolayd\u0131r. <code>django-environ<\/code> ise \u00e7evre de\u011fi\u015fkenlerini y\u00f6netmek i\u00e7in kullan\u0131lacak.<\/p>\n<h4>2. Django Projesi ve Uygulamas\u0131 Olu\u015fturma<\/h4>\n<pre><code class=\"language-bash\">django-admin startproject dodashboard .\npython manage.py startapp doapi<\/code><\/pre>\n<p>Bu komutlar, <code>dodeshboard<\/code> ad\u0131nda bir proje ve <code>doapi<\/code> ad\u0131nda bir uygulama olu\u015fturur.<\/p>\n<h4>3. Uygulamay\u0131 <code>settings.py<\/code>&#8216;ye Ekleme<\/h4>\n<p><code>dodeshboard\/settings.py<\/code> dosyas\u0131n\u0131 a\u00e7\u0131n ve <code>INSTALLED_APPS<\/code> listesine <code>doapi<\/code> uygulamas\u0131n\u0131 ekleyin:<\/p>\n<pre><code class=\"language-python\"># dodashboard\/settings.py\n\nINSTALLED_APPS = [\n    # ... di\u011fer uygulamalar\n    'doapi',\n]<\/code><\/pre>\n<h4>4. URL Yap\u0131land\u0131rmas\u0131<\/h4>\n<p><code>dodeshboard\/urls.py<\/code> dosyas\u0131n\u0131 a\u00e7\u0131n ve <code>doapi<\/code> uygulamas\u0131n\u0131n URL&#8217;lerini ana URL yap\u0131land\u0131rmas\u0131na dahil edin:<\/p>\n<pre><code class=\"language-python\"># dodashboard\/urls.py\n\nfrom django.contrib import admin\nfrom django.urls import path, include\n\nurlpatterns = [\n    path('admin\/', admin.site.urls),\n    path('doapi\/', include('doapi.urls')), # doapi uygulamas\u0131n\u0131n URL'lerini dahil et\n]<\/code><\/pre>\n<p>\u015eimdi <code>doapi<\/code> uygulamas\u0131 i\u00e7in <code>doapi\/urls.py<\/code> dosyas\u0131n\u0131 olu\u015fturun:<\/p>\n<pre><code class=\"language-python\"># doapi\/urls.py\n\nfrom django.urls import path\nfrom . import views\n\nurlpatterns = [\n    path('droplets\/', views.droplet_list, name='droplet_list'),\n    path('domains\/', views.domain_list, name='domain_list'),\n    path('projects\/', views.project_list, name='project_list'),\n    path('', views.dashboard_home, name='dashboard_home'),\n]<\/code><\/pre>\n<h3>API Token&#8217;\u0131n\u0131 G\u00fcvenli Bir \u015eekilde Saklama (<code>django-environ<\/code> ile)<\/h3>\n<p>API token&#8217;lar\u0131n\u0131 do\u011frudan <code>settings.py<\/code> dosyas\u0131na yazmak g\u00fcvenlik a\u00e7\u0131s\u0131ndan k\u00f6t\u00fc bir uygulamad\u0131r. Bu token&#8217;lar hassas bilgiler i\u00e7erir ve versiyon kontrol sistemlerine (Git gibi) y\u00fcklenmemelidir. <code>django-environ<\/code> k\u00fct\u00fcphanesi, \u00e7evre de\u011fi\u015fkenlerini veya <code>.env<\/code> dosyalar\u0131n\u0131 kullanarak bu t\u00fcr hassas bilgileri g\u00fcvenli bir \u015fekilde y\u00f6netmenizi sa\u011flar.<\/p>\n<p>Projenizin k\u00f6k dizininde (<code>manage.py<\/code> ile ayn\u0131 yerde) <code>.env<\/code> ad\u0131nda bir dosya olu\u015fturun ve DigitalOcean API token&#8217;\u0131n\u0131z\u0131 buraya ekleyin:<\/p>\n<pre><code class=\"language-\"># .env\nDIGITALOCEAN_API_TOKEN=\"sizin_digitalocean_api_token'\u0131n\u0131z_buraya\"<\/code><\/pre>\n<p><code>.gitignore<\/code> dosyan\u0131za <code>.env<\/code>&#8216;yi eklemeyi unutmay\u0131n:<\/p>\n<pre><code class=\"language-\"># .gitignore\n*.pyc\n__pycache__\/\n.env\ndb.sqlite3<\/code><\/pre>\n<p>\u015eimdi <code>dodeshboard\/settings.py<\/code> dosyas\u0131n\u0131 g\u00fcncelleyerek bu token&#8217;\u0131 \u00e7ekelim:<\/p>\n<pre><code class=\"language-python\"># dodashboard\/settings.py\n\nimport os\nimport environ\n\n<h2>environ k\u00fct\u00fcphanesini ba\u015flat<\/h2>\nenv = environ.Env(\n    # default de\u011ferler veya tip d\u00f6n\u00fc\u015f\u00fcmleri tan\u0131mlayabilirsiniz\n    DEBUG=(bool, False)\n)\n\n<h2>.env dosyas\u0131n\u0131 oku<\/h2>\nenviron.Env.read_env(os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), '.env'))\n\n<h2>Di\u011fer ayarlar...<\/h2>\n\n<h2>DigitalOcean API Token'\u0131n\u0131 \u00e7evre de\u011fi\u015fkeninden \u00e7ek<\/h2>\nDIGITALOCEAN_API_TOKEN = env('DIGITALOCEAN_API_TOKEN')\n\n<h2>DEBUG ayar\u0131n\u0131 .env'den \u00e7ek<\/h2>\nDEBUG = env('DEBUG')\n\n<h2>SECRET_KEY gibi di\u011fer hassas bilgileri de buradan \u00e7ekebilirsiniz<\/h2>\nSECRET_KEY = env('DJANGO_SECRET_KEY', default='bir_varsay\u0131lan_de\u011fer_verilebilir_ama_\u00fcretimde_asla_kullanmay\u0131n')<\/code><\/pre>\n<p>Bu yap\u0131land\u0131rma ile <code>DIGITALOCEAN_API_TOKEN<\/code> de\u011fi\u015fkeni, <code>.env<\/code> dosyas\u0131ndan g\u00fcvenli bir \u015fekilde al\u0131nacakt\u0131r.<\/p>\n<h3>API Verilerini \u00c7ekme (Django View&#8217;lar\u0131 ile)<\/h3>\n<p>\u015eimdi <code>doapi\/views.py<\/code> dosyas\u0131n\u0131 olu\u015fturarak DigitalOcean API&#8217;sinden veri \u00e7ekecek fonksiyonlar\u0131 yazal\u0131m. <code>requests<\/code> k\u00fct\u00fcphanesini kullanarak API&#8217;ye HTTP GET istekleri g\u00f6nderece\u011fiz.<\/p>\n<h4>Temel API \u0130stek Fonksiyonu<\/h4>\n<p>\u00d6ncelikle, API isteklerini yapacak genel bir yard\u0131mc\u0131 fonksiyon tan\u0131mlayal\u0131m:<\/p>\n<pre><code class=\"language-python\"># doapi\/views.py\n\nimport requests\nfrom django.conf import settings\nfrom django.shortcuts import render\n\nDIGITALOCEAN_API_BASE_URL = \"https:\/\/api.digitalocean.com\/v2\"\n\ndef _make_digitalocean_api_request(endpoint):\n    \"\"\"\n    DigitalOcean API'sine GET iste\u011fi yapar ve JSON yan\u0131t\u0131n\u0131 d\u00f6nd\u00fcr\u00fcr.\n    \"\"\"\n    headers = {\n        \"Authorization\": f\"Bearer {settings.DIGITALOCEAN_API_TOKEN}\",\n        \"Content-Type\": \"application\/json\",\n    }\n    url = f\"{DIGITALOCEAN_API_BASE_URL}\/{endpoint}\"\n\n    try:\n        response = requests.get(url, headers=headers)\n        response.raise_for_status()  # HTTP hatalar\u0131 i\u00e7in istisna f\u0131rlat\n        return response.json()\n    except requests.exceptions.RequestException as e:\n        print(f\"DigitalOcean API iste\u011fi ba\u015far\u0131s\u0131z oldu: {e}\")\n        return None<\/code><\/pre>\n<h4>Droplet Listesini \u00c7ekme ve G\u00f6r\u00fcnt\u00fcleme<\/h4>\n<p>\u015eimdi bu yard\u0131mc\u0131 fonksiyonu kullanarak Droplet&#8217;leri \u00e7ekelim ve bir Django \u015fablonunda g\u00f6r\u00fcnt\u00fclemek \u00fczere haz\u0131rlayal\u0131m.<\/p>\n<pre><code class=\"language-python\"># doapi\/views.py (devam\u0131)\n\ndef droplet_list(request):\n    \"\"\"\n    DigitalOcean Droplet'lerini \u00e7eker ve listeler.\n    \"\"\"\n    data = _make_digitalocean_api_request(\"droplets\")\n    \n    if data and 'droplets' in data:\n        droplets = data['droplets']\n    else:\n        droplets = [] # Hata durumunda bo\u015f liste\n        \n    context = {\n        'droplets': droplets\n    }\n    return render(request, 'doapi\/droplet_list.html', context)<\/code><\/pre>\n<h4>Domain Listesini \u00c7ekme ve G\u00f6r\u00fcnt\u00fcleme<\/h4>\n<p>Benzer \u015fekilde, domain&#8217;leri de \u00e7ekebiliriz:<\/p>\n<pre><code class=\"language-python\"># doapi\/views.py (devam\u0131)\n\ndef domain_list(request):\n    \"\"\"\n    DigitalOcean Domain'lerini \u00e7eker ve listeler.\n    \"\"\"\n    data = _make_digitalocean_api_request(\"domains\")\n    \n    if data and 'domains' in data:\n        domains = data['domains']\n    else:\n        domains = []\n        \n    context = {\n        'domains': domains\n    }\n    return render(request, 'doapi\/domain_list.html', context)<\/code><\/pre>\n<h4>Project Listesini \u00c7ekme ve G\u00f6r\u00fcnt\u00fcleme<\/h4>\n<p>Ve projeleri \u00e7ekme:<\/p>\n<pre><code class=\"language-python\"># doapi\/views.py (devam\u0131)\n\ndef project_list(request):\n    \"\"\"\n    DigitalOcean Projelerini \u00e7eker ve listeler.\n    \"\"\"\n    data = _make_digitalocean_api_request(\"projects\")\n    \n    if data and 'projects' in data:\n        projects = data['projects']\n    else:\n        projects = []\n        \n    context = {\n        'projects': projects\n    }\n    return render(request, 'doapi\/project_list.html', context)<\/code><\/pre>\n<h4>Dashboard Ana Sayfas\u0131<\/h4>\n<p>Genel bir dashboard ana sayfas\u0131 da olu\u015fturabiliriz:<\/p>\n<pre><code class=\"language-python\"># doapi\/views.py (devam\u0131)\n\ndef dashboard_home(request):\n    \"\"\"\n    DigitalOcean kaynaklar\u0131n\u0131n \u00f6zetini g\u00f6steren ana dashboard sayfas\u0131.\n    \"\"\"\n    droplets_data = _make_digitalocean_api_request(\"droplets\")\n    domains_data = _make_digitalocean_api_request(\"domains\")\n    projects_data = _make_digitalocean_api_request(\"projects\")\n\n    num_droplets = len(droplets_data.get('droplets', [])) if droplets_data else 0\n    num_domains = len(domains_data.get('domains', [])) if domains_data else 0\n    num_projects = len(projects_data.get('projects', [])) if projects_data else 0\n\n    context = {\n        'num_droplets': num_droplets,\n        'num_domains': num_domains,\n        'num_projects': num_projects,\n    }\n    return render(request, 'doapi\/dashboard_home.html', context)<\/code><\/pre>\n<h3>Veriyi Django \u015eablonlar\u0131nda G\u00f6r\u00fcnt\u00fcleme<\/h3>\n<p>\u015eimdi API&#8217;den \u00e7ekilen verileri Django \u015fablonlar\u0131 (HTML dosyalar\u0131) kullanarak kullan\u0131c\u0131 aray\u00fcz\u00fcnde g\u00f6sterelim.<\/p>\n<h4>\u015eablon Klas\u00f6r\u00fc Olu\u015fturma<\/h4>\n<p><code>doapi<\/code> uygulamas\u0131 i\u00e7inde bir <code>templates<\/code> klas\u00f6r\u00fc ve onun i\u00e7inde de <code>doapi<\/code> ad\u0131nda ba\u015fka bir klas\u00f6r olu\u015fturun:<\/p>\n<pre><code class=\"language-\">digitalocean_dashboard\/\n\u251c\u2500\u2500 dodashboard\/\n\u251c\u2500\u2500 doapi\/\n\u2502   \u251c\u2500\u2500 migrations\/\n\u2502   \u251c\u2500\u2500 templates\/\n\u2502   \u2502   \u2514\u2500\u2500 doapi\/\n\u2502   \u2502       \u251c\u2500\u2500 base.html\n\u2502   \u2502       \u251c\u2500\u2500 dashboard_home.html\n\u2502   \u2502       \u251c\u2500\u2500 droplet_list.html\n\u2502   \u2502       \u251c\u2500\u2500 domain_list.html\n\u2502   \u2502       \u2514\u2500\u2500 project_list.html\n\u2502   \u251c\u2500\u2500 __init__.py\n\u2502   \u251c\u2500\u2500 admin.py\n\u2502   \u251c\u2500\u2500 apps.py\n\u2502   \u251c\u2500\u2500 models.py\n\u2502   \u251c\u2500\u2500 tests.py\n\u2502   \u251c\u2500\u2500 urls.py\n\u2502   \u2514\u2500\u2500 views.py\n\u251c\u2500\u2500 manage.py\n\u251c\u2500\u2500 .env\n\u2514\u2500\u2500 venv\/<\/code><\/pre>\n<p><code>dodeshboard\/settings.py<\/code> dosyas\u0131nda <code>TEMPLATES<\/code> ayar\u0131n\u0131n <code>APP_DIRS: True<\/code> oldu\u011fundan emin olun, bu Django&#8217;nun her uygulaman\u0131n <code>templates<\/code> klas\u00f6r\u00fcn\u00fc aramas\u0131n\u0131 sa\u011flar.<\/p>\n<h4>Temel \u015eablon (<code>base.html<\/code>)<\/h4>\n<p>T\u00fcm sayfalar\u0131m\u0131z i\u00e7in ortak bir yap\u0131 sa\u011flayacak bir <code>base.html<\/code> \u015fablonu olu\u015ftural\u0131m:<\/p>\n<pre><code class=\"language-html\"><!-- doapi\/templates\/doapi\/base.html -->\n<!DOCTYPE html>\n<html lang=\"tr\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>DigitalOcean Dashboard - {% block title %}Ana Sayfa{% endblock %}<\/title>\n    <link href=\"https:\/\/cdn.jsdelivr.net\/npm\/bootstrap@5.3.0\/dist\/css\/bootstrap.min.css\" rel=\"stylesheet\">\n    <style>\n        body { padding-top: 56px; }\n        .sidebar {\n            position: fixed;\n            top: 56px;\n            bottom: 0;\n            left: 0;\n            z-index: 1000;\n            padding: 20px;\n            overflow-x: hidden;\n            overflow-y: auto; \/<em> Scrollable contents if viewport is shorter than content. <\/em>\/\n            border-right: 1px solid #eee;\n        }\n    <\/style>\n<\/head>\n<body>\n    <nav class=\"navbar navbar-expand-lg navbar-dark bg-dark fixed-top\">\n        <div class=\"container-fluid\">\n            <a class=\"navbar-brand\" href=\"{% url 'dashboard_home' %}\">DO Dashboard<\/a>\n            <button class=\"navbar-toggler\" type=\"button\" data-bs-toggle=\"collapse\" data-bs-target=\"#navbarNav\" aria-controls=\"navbarNav\" aria-expanded=\"false\" aria-label=\"Toggle navigation\">\n                <span class=\"navbar-toggler-icon\"><\/span>\n            <\/button>\n            <div class=\"collapse navbar-collapse\" id=\"navbarNav\">\n                <ul class=\"navbar-nav me-auto mb-2 mb-lg-0\">\n                    <li class=\"nav-item\">\n                        <a class=\"nav-link\" href=\"{% url 'droplet_list' %}\">Dropletler<\/a>\n                    <\/li>\n                    <li class=\"nav-item\">\n                        <a class=\"nav-link\" href=\"{% url 'domain_list' %}\">Domainler<\/a>\n                    <\/li>\n                    <li class=\"nav-item\">\n                        <a class=\"nav-link\" href=\"{% url 'project_list' %}\">Projeler<\/a>\n                    <\/li>\n                <\/ul>\n            <\/div>\n        <\/div>\n    <\/nav>\n\n    <div class=\"container-fluid\">\n        <div class=\"row\">\n            <nav id=\"sidebarMenu\" class=\"col-md-3 col-lg-2 d-md-block bg-light sidebar collapse\">\n                <div class=\"position-sticky pt-3\">\n                    <ul class=\"nav flex-column\">\n                        <li class=\"nav-item\">\n                            <a class=\"nav-link active\" aria-current=\"page\" href=\"{% url 'dashboard_home' %}\">\n                                <span data-feather=\"home\"><\/span>\n                                Ana Sayfa\n                            <\/a>\n                        <\/li>\n                        <li class=\"nav-item\">\n                            <a class=\"nav-link\" href=\"{% url 'droplet_list' %}\">\n                                <span data-feather=\"server\"><\/span>\n                                Dropletler\n                            <\/a>\n                        <\/li>\n                        <li class=\"nav-item\">\n                            <a class=\"nav-link\" href=\"{% url 'domain_list' %}\">\n                                <span data-feather=\"globe\"><\/span>\n                                Domainler\n                            <\/a>\n                        <\/li>\n                        <li class=\"nav-item\">\n                            <a class=\"nav-link\" href=\"{% url 'project_list' %}\">\n                                <span data-feather=\"briefcase\"><\/span>\n                                Projeler\n                            <\/a>\n                        <\/li>\n                    <\/ul>\n                <\/div>\n            <\/nav>\n\n            <main class=\"col-md-9 ms-sm-auto col-lg-10 px-md-4\">\n                <div class=\"d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom\">\n                    \n                <\/div>\n                {% block content %}\n                {% endblock %}\n            <\/main>\n        <\/div>\n    <\/div>\n\n    <script src=\"https:\/\/cdn.jsdelivr.net\/npm\/bootstrap@5.3.0\/dist\/js\/bootstrap.bundle.min.js\"><\/script>\n<\/body>\n<\/html><\/code><\/pre>\n<h4>Dashboard Ana Sayfa \u015eablonu (<code>dashboard_home.html<\/code>)<\/h4>\n<pre><code class=\"language-html\"><!-- doapi\/templates\/doapi\/dashboard_home.html -->\n{% extends 'doapi\/base.html' %}\n\n{% block title %}Ana Sayfa{% endblock %}\n{% block page_title %}DigitalOcean Genel Bak\u0131\u015f{% endblock %}\n\n{% block content %}\n<div class=\"row\">\n    <div class=\"col-md-4\">\n        <div class=\"card text-center mb-3\">\n            <div class=\"card-body\">\n                <h5 class=\"card-title\">Toplam Droplet<\/h5>\n                <p class=\"card-text display-4\">{{ num_droplets }}<\/p>\n                <a href=\"{% url 'droplet_list' %}\" class=\"btn btn-primary\">Detaylar\u0131 G\u00f6r<\/a>\n            <\/div>\n        <\/div>\n    <\/div>\n    <div class=\"col-md-4\">\n        <div class=\"card text-center mb-3\">\n            <div class=\"card-body\">\n                <h5 class=\"card-title\">Toplam Domain<\/h5>\n                <p class=\"card-text display-4\">{{ num_domains }}<\/p>\n                <a href=\"{% url 'domain_list' %}\" class=\"btn btn-primary\">Detaylar\u0131 G\u00f6r<\/a>\n            <\/div>\n        <\/div>\n    <\/div>\n    <div class=\"col-md-4\">\n        <div class=\"card text-center mb-3\">\n            <div class=\"card-body\">\n                <h5 class=\"card-title\">Toplam Proje<\/h5>\n                <p class=\"card-text display-4\">{{ num_projects }}<\/p>\n                <a href=\"{% url 'project_list' %}\" class=\"btn btn-primary\">Detaylar\u0131 G\u00f6r<\/a>\n            <\/div>\n        <\/div>\n    <\/div>\n<\/div>\n{% endblock %}<\/code><\/pre>\n<h4>Droplet Listesi \u015eablonu (<code>droplet_list.html<\/code>)<\/h4>\n<pre><code class=\"language-html\"><!-- doapi\/templates\/doapi\/droplet_list.html -->\n{% extends 'doapi\/base.html' %}\n\n{% block title %}Dropletler{% endblock %}\n{% block page_title %}Droplet Listesi{% endblock %}\n\n{% block content %}\n    {% if droplets %}\n        <div class=\"table-responsive\">\n            <table class=\"table table-striped table-sm\">\n                <thead>\n                    <tr>\n                        <th>ID<\/th>\n                        <th>\u0130sim<\/th>\n                        <th>B\u00f6lge<\/th>\n                        <th>Boyut<\/th>\n                        <th>Durum<\/th>\n                        <th>IP Adresi<\/th>\n                    <\/tr>\n                <\/thead>\n                <tbody>\n                    {% for droplet in droplets %}\n                        <tr>\n                            <td>{{ droplet.id }}<\/td>\n                            <td>{{ droplet.name }}<\/td>\n                            <td>{{ droplet.region.name }} ({{ droplet.region.slug }})<\/td>\n                            <td>{{ droplet.size.slug }} ({{ droplet.size.memory }}MB RAM)<\/td>\n                            <td><span class=\"badge {% if droplet.status == 'active' %}bg-success{% else %}bg-warning text-dark{% endif %}\">{{ droplet.status }}<\/span><\/td>\n                            <td>\n                                {% for network in droplet.networks.v4 %}\n                                    {% if network.type == 'public' %}\n                                        {{ network.ip_address }}\n                                    {% endif %}\n                                {% endfor %}\n                            <\/td>\n                        <\/tr>\n                    {% endfor %}\n                <\/tbody>\n            <\/table>\n        <\/div>\n    {% else %}\n        <p class=\"alert alert-warning\">Hi\u00e7 Droplet bulunamad\u0131 veya API'den veri \u00e7ekilemedi.<\/p>\n    {% endif %}\n{% endblock %}<\/code><\/pre>\n<h4>Domain Listesi \u015eablonu (<code>domain_list.html<\/code>)<\/h4>\n<pre><code class=\"language-html\"><!-- doapi\/templates\/doapi\/domain_list.html -->\n{% extends 'doapi\/base.html' %}\n\n{% block title %}Domainler{% endblock %}\n{% block page_title %}Domain Listesi{% endblock %}\n\n{% block content %}\n    {% if domains %}\n        <div class=\"table-responsive\">\n            <table class=\"table table-striped table-sm\">\n                <thead>\n                    <tr>\n                        <th>\u0130sim<\/th>\n                        <th>TTL<\/th>\n                        <th>Zone File \u00dcretildi<\/th>\n                    <\/tr>\n                <\/thead>\n                <tbody>\n                    {% for domain in domains %}\n                        <tr>\n                            <td>{{ domain.name }}<\/td>\n                            <td>{{ domain.ttl }}<\/td>\n                            <td>{{ domain.zone_file_generated_at }}<\/td>\n                        <\/tr>\n                    {% endfor %}\n                <\/tbody>\n            <\/table>\n        <\/div>\n    {% else %}\n        <p class=\"alert alert-warning\">Hi\u00e7 Domain bulunamad\u0131 veya API'den veri \u00e7ekilemedi.<\/p>\n    {% endif %}\n{% endblock %}<\/code><\/pre>\n<h4>Proje Listesi \u015eablonu (<code>project_list.html<\/code>)<\/h4>\n<pre><code class=\"language-html\"><!-- doapi\/templates\/doapi\/project_list.html -->\n{% extends 'doapi\/base.html' %}\n\n{% block title %}Projeler{% endblock %}\n{% block page_title %}Proje Listesi{% endblock %}\n\n{% block content %}\n    {% if projects %}\n        <div class=\"table-responsive\">\n            <table class=\"table table-striped table-sm\">\n                <thead>\n                    <tr>\n                        <th>ID<\/th>\n                        <th>\u0130sim<\/th>\n                        <th>A\u00e7\u0131klama<\/th>\n                        <th>Amac\u0131<\/th>\n                        <th>Olu\u015fturulma Tarihi<\/th>\n                    <\/tr>\n                <\/thead>\n                <tbody>\n                    {% for project in projects %}\n                        <tr>\n                            <td>{{ project.id }}<\/td>\n                            <td>{{ project.name }}<\/td>\n                            <td>{{ project.description }}<\/td>\n                            <td>{{ project.purpose }}<\/td>\n                            <td>{{ project.created_at }}<\/td>\n                        <\/tr>\n                    {% endfor %}\n                <\/tbody>\n            <\/table>\n        <\/div>\n    {% else %}\n        <p class=\"alert alert-warning\">Hi\u00e7 Proje bulunamad\u0131 veya API'den veri \u00e7ekilemedi.<\/p>\n    {% endif %}\n{% endblock %}<\/code><\/pre>\n<h3>Uygulamay\u0131 \u00c7al\u0131\u015ft\u0131rma<\/h3>\n<p>T\u00fcm bu ad\u0131mlar\u0131 tamamlad\u0131ktan sonra, Django geli\u015ftirme sunucusunu ba\u015flatabilir ve uygulaman\u0131z\u0131 test edebilirsiniz:<\/p>\n<pre><code class=\"language-bash\">python manage.py runserver<\/code><\/pre>\n<p>Taray\u0131c\u0131n\u0131zda <code>http:\/\/127.0.0.1:8000\/doapi\/<\/code> adresine gidin. DigitalOcean kaynaklar\u0131n\u0131z\u0131n \u00f6zetini ve detayl\u0131 listelerini g\u00f6rmelisiniz.<\/p>\n<h3>Geli\u015fmi\u015f Konular ve En \u0130yi Uygulamalar<\/h3>\n<h4>1. \u00d6nbellekleme (Caching)<\/h4>\n<p>DigitalOcean API&#8217;sine her sayfa y\u00fcklemede istek g\u00f6ndermek, hem API rate limit&#8217;lerinizi t\u00fcketebilir hem de uygulaman\u0131z\u0131n performans\u0131n\u0131 d\u00fc\u015f\u00fcrebilir. Bu nedenle, API verilerini \u00f6nbelle\u011fe almak \u00f6nemlidir. Django&#8217;nun yerle\u015fik \u00f6nbellekleme \u00e7er\u00e7evesini kullanabilirsiniz.<\/p>\n<p><strong>\u00d6rnek (Basit \u00d6nbellekleme):<\/strong><br \/>\n<code>dodeshboard\/settings.py<\/code> i\u00e7inde \u00f6nbellekleme yap\u0131land\u0131rmas\u0131:<\/p>\n<pre><code class=\"language-python\"># dodashboard\/settings.py\n\nCACHES = {\n    'default': {\n        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',\n        'LOCATION': 'unique-snowflake',\n        'TIMEOUT': 300, # 5 dakika (saniye cinsinden)\n    }\n}<\/code><\/pre>\n<p><code>doapi\/views.py<\/code> i\u00e7inde \u00f6nbellekleme kullan\u0131m\u0131:<\/p>\n<pre><code class=\"language-python\"># doapi\/views.py\n\nfrom django.core.cache import cache\n\n<h2>... (di\u011fer importlar ve _make_digitalocean_api_request fonksiyonu)<\/h2>\n\ndef _get_cached_digitalocean_data(endpoint, cache_key, timeout=300):\n    \"\"\"\n    API verilerini \u00f6nbellekten \u00e7ekmeye \u00e7al\u0131\u015f\u0131r, yoksa API'den \u00e7eker ve \u00f6nbelle\u011fe kaydeder.\n    \"\"\"\n    data = cache.get(cache_key)\n    if not data:\n        data = _make_digitalocean_api_request(endpoint)\n        if data:\n            cache.set(cache_key, data, timeout)\n    return data\n\ndef droplet_list(request):\n    data = _get_cached_digitalocean_data(\"droplets\", \"do_droplets_cache\")\n    # ... (geri kalan kod ayn\u0131)<\/code><\/pre>\n<p>Bu \u015fekilde, Droplet verileri 5 dakika boyunca \u00f6nbellekte kalacak ve bu s\u00fcre zarf\u0131nda API&#8217;ye tekrar istek g\u00f6nderilmeyecektir.<\/p>\n<h4>2. Arka Plan G\u00f6revleri (Celery)<\/h4>\n<p>E\u011fer API istekleri uzun s\u00fcr\u00fcyorsa veya d\u00fczenli aral\u0131klarla veri \u00e7ekmeniz gerekiyorsa, bu i\u015flemleri arka plan g\u00f6revlerine devretmek iyi bir fikirdir. Celery, bu t\u00fcr g\u00f6revleri y\u00f6netmek i\u00e7in pop\u00fcler bir Python k\u00fct\u00fcphanesidir. Celery ile API verilerini periyodik olarak \u00e7ekip bir veritaban\u0131na kaydedebilir, b\u00f6ylece web uygulaman\u0131z her zaman g\u00fcncel verilere h\u0131zl\u0131ca eri\u015febilir.<\/p>\n<h4>3. Hata Y\u00f6netimi ve Loglama<\/h4>\n<p>API istekleri her zaman ba\u015far\u0131l\u0131 olmayabilir. A\u011f sorunlar\u0131, API limitlerine tak\u0131lma, ge\u00e7ersiz token gibi durumlar hatalara yol a\u00e7abilir. Bu hatalar\u0131 d\u00fczg\u00fcn bir \u015fekilde y\u00f6netmek ve loglamak \u00f6nemlidir.<\/p>\n<pre><code class=\"language-python\"># doapi\/views.py (genel API istek fonksiyonunda geli\u015ftirme)\n\nimport logging\nlogger = logging.getLogger(__name__)\n\ndef _make_digitalocean_api_request(endpoint):\n    # ... (\u00f6nceki kod)\n    try:\n        response = requests.get(url, headers=headers)\n        response.raise_for_status()\n        return response.json()\n    except requests.exceptions.HTTPError as http_err:\n        logger.error(f\"HTTP hatas\u0131 olu\u015ftu: {http_err} - Yan\u0131t: {response.text}\")\n        return None\n    except requests.exceptions.ConnectionError as conn_err:\n        logger.error(f\"Ba\u011flant\u0131 hatas\u0131 olu\u015ftu: {conn_err}\")\n        return None\n    except requests.exceptions.Timeout as timeout_err:\n        logger.error(f\"\u0130stek zaman a\u015f\u0131m\u0131na u\u011frad\u0131: {timeout_err}\")\n        return None\n    except requests.exceptions.RequestException as req_err:\n        logger.error(f\"DigitalOcean API iste\u011fi bilinmeyen bir hatayla ba\u015far\u0131s\u0131z oldu: {req_err}\")\n        return None<\/code><\/pre>\n<p>Django&#8217;nun loglama yap\u0131land\u0131rmas\u0131n\u0131 kullanarak bu loglar\u0131 dosyalara veya di\u011fer loglama servislerine y\u00f6nlendirebilirsiniz.<\/p>\n<h4>4. G\u00fcvenlik \u0130yile\u015ftirmeleri<\/h4>\n<p>API token&#8217;lar\u0131n\u0131 <code>.env<\/code> dosyas\u0131 ile y\u00f6netmek iyi bir ba\u015flang\u0131\u00e7t\u0131r. \u00dcretim ortam\u0131nda, bu token&#8217;lar\u0131 daha da g\u00fcvenli bir \u015fekilde saklamak i\u00e7in HashiCorp Vault gibi s\u0131r y\u00f6netim \u00e7\u00f6z\u00fcmlerini veya bulut sa\u011flay\u0131c\u0131n\u0131z\u0131n (AWS Secrets Manager, Azure Key Vault vb.) s\u0131r y\u00f6netim hizmetlerini d\u00fc\u015f\u00fcnebilirsiniz.<\/p>\n<h4>5. Sayfaland\u0131rma (Pagination)<\/h4>\n<p>DigitalOcean API&#8217;si, b\u00fcy\u00fck veri k\u00fcmeleri i\u00e7in sayfaland\u0131rma (pagination) sunar. E\u011fer \u00e7ok say\u0131da Droplet veya domain&#8217;iniz varsa, API yan\u0131t\u0131 tek bir istekte t\u00fcm veriyi d\u00f6nd\u00fcrmeyebilir. <code>Link<\/code> ba\u015fl\u0131\u011f\u0131n\u0131 ve <code>page<\/code>, <code>per_page<\/code> parametrelerini kullanarak sayfalar aras\u0131nda gezmeniz gerekebilir.<\/p>\n<pre><code class=\"language-python\"># _make_digitalocean_api_request fonksiyonunda sayfaland\u0131rma \u00f6rne\u011fi (basit)\ndef _make_digitalocean_api_request(endpoint, params=None):\n    # ... (headers, url tan\u0131mlamalar\u0131)\n    all_data = []\n    page = 1\n    per_page = 20 # DigitalOcean varsay\u0131lan\u0131 20\n    \n    while True:\n        current_params = params.copy() if params else {}\n        current_params.update({'page': page, 'per_page': per_page})\n        \n        response = requests.get(url, headers=headers, params=current_params)\n        response.raise_for_status()\n        json_data = response.json()\n        \n        # API yan\u0131t\u0131ndaki anahtar ismine g\u00f6re veriyi al\n        if endpoint == \"droplets\":\n            all_data.extend(json_data.get('droplets', []))\n        elif endpoint == \"domains\":\n            all_data.extend(json_data.get('domains', []))\n        elif endpoint == \"projects\":\n            all_data.extend(json_data.get('projects', []))\n        # ... di\u011fer endpointler i\u00e7in ekle\n            \n        # Sonraki sayfa olup olmad\u0131\u011f\u0131n\u0131 kontrol et\n        if 'pages' in json_data['links'] and 'next' in json_data['links']['pages']:\n            page += 1\n        else:\n            break\n            \n    return {endpoint: all_data} # T\u00fcm veriyi tek bir s\u00f6zl\u00fckte d\u00f6nd\u00fcr<\/code><\/pre>\n<p>Bu \u00f6rnek, t\u00fcm sayfalar\u0131 otomatik olarak \u00e7ekmek i\u00e7in basit bir d\u00f6ng\u00fc kullan\u0131r. Ger\u00e7ek bir uygulamada, bu mant\u0131\u011f\u0131 daha esnek hale getirebilir veya kullan\u0131c\u0131n\u0131n sayfalar aras\u0131nda gezinmesine izin verebilirsiniz.<\/p>\n<h4>6. Veri Modelleme ve Veritaban\u0131na Kay\u0131t<\/h4>\n<p>E\u011fer API&#8217;den gelen veriler \u00fczerinde karma\u015f\u0131k sorgular yapman\u0131z, arama veya filtreleme uygulaman\u0131z gerekiyorsa, bu verileri Django modelleri arac\u0131l\u0131\u011f\u0131yla kendi veritaban\u0131n\u0131za kaydetmek daha mant\u0131kl\u0131 olabilir. Bu durumda, API&#8217;den verileri \u00e7eken bir Celery g\u00f6revi, bu verileri d\u00fczenli olarak veritaban\u0131n\u0131zdaki modellere senkronize ederdi.<\/p>\n<p><strong>\u00d6rnek Model (<code>doapi\/models.py<\/code>):<\/strong><\/p>\n<pre><code class=\"language-python\"># doapi\/models.py\nfrom django.db import models\n\nclass Droplet(models.Model):\n    droplet_id = models.IntegerField(unique=True)\n    name = models.CharField(max_length=255)\n    region_slug = models.CharField(max_length=50)\n    size_slug = models.CharField(max_length=50)\n    status = models.CharField(max_length=50)\n    ip_address = models.GenericIPAddressField(null=True, blank=True)\n    created_at = models.DateTimeField()\n\n    def __str__(self):\n        return self.name<\/code><\/pre>\n<p>API&#8217;den gelen verileri bu modele kaydetmek i\u00e7in bir senkronizasyon fonksiyonu yaz\u0131labilir:<\/p>\n<pre><code class=\"language-python\"># doapi\/tasks.py (Celery kullan\u0131yorsan\u0131z) veya doapi\/utils.py\nfrom .models import Droplet\nfrom .views import _make_digitalocean_api_request # API iste\u011fi yapan fonksiyonu import et\n\ndef sync_droplets_from_do():\n    droplets_data = _make_digitalocean_api_request(\"droplets\")\n    if droplets_data and 'droplets' in droplets_data:\n        for do_droplet in droplets_data['droplets']:\n            ip_address = None\n            for network in do_droplet['networks']['v4']:\n                if network['type'] == 'public':\n                    ip_address = network['ip_address']\n                    break\n\n            droplet, created = Droplet.objects.update_or_create(\n                droplet_id=do_droplet['id'],\n                defaults={\n                    'name': do_droplet['name'],\n                    'region_slug': do_droplet['region']['slug'],\n                    'size_slug': do_droplet['size']['slug'],\n                    'status': do_droplet['status'],\n                    'ip_address': ip_address,\n                    'created_at': do_droplet['created_at'],\n                }\n            )\n            if created:\n                print(f\"Yeni Droplet eklendi: {droplet.name}\")\n            else:\n                print(f\"Droplet g\u00fcncellendi: {droplet.name}\")<\/code><\/pre>\n<p>Bu yakla\u015f\u0131m, API&#8217;ye ba\u011f\u0131ml\u0131l\u0131\u011f\u0131 azalt\u0131r ve uygulama performans\u0131n\u0131 art\u0131r\u0131r, ancak verilerin g\u00fcncelli\u011fini korumak i\u00e7in d\u00fczenli senkronizasyon gerektirir.<\/p>\n<h3>Sonu\u00e7<\/h3>\n<p>Bu makalede, DigitalOcean API&#8217;sinden veri \u00e7ekmek ve bu verileri Django web uygulamas\u0131nda g\u00f6r\u00fcnt\u00fclemek i\u00e7in kapsaml\u0131 bir rehber sunduk. DigitalOcean API token&#8217;\u0131n\u0131 g\u00fcvenli bir \u015fekilde y\u00f6netmekten, <code>requests<\/code> k\u00fct\u00fcphanesi ile API istekleri yapmaya, \u00e7ekilen verileri Django \u015fablonlar\u0131nda g\u00f6stermeye kadar bir\u00e7ok konuyu ele ald\u0131k. Ayr\u0131ca, \u00f6nbellekleme, arka plan g\u00f6revleri, hata y\u00f6netimi ve veritaban\u0131 entegrasyonu gibi geli\u015fmi\u015f konulara da de\u011finerek uygulaman\u0131z\u0131n performans\u0131n\u0131 ve g\u00fcvenli\u011fini art\u0131rmak i\u00e7in en iyi uygulamalar\u0131 tart\u0131\u015ft\u0131k.<\/p>\n<p>Bu rehber, DigitalOcean kaynaklar\u0131n\u0131z\u0131n durumunu izlemek, \u00f6zel bir kontrol paneli olu\u015fturmak veya bulut altyap\u0131n\u0131zla etkile\u015fim kuran daha karma\u015f\u0131k otomasyon \u00e7\u00f6z\u00fcmleri geli\u015ftirmek i\u00e7in sa\u011flam bir temel olu\u015fturmaktad\u0131r. Django&#8217;nun esnekli\u011fi ve DigitalOcean API&#8217;sinin g\u00fcc\u00fc birle\u015fti\u011finde, bulut kaynaklar\u0131n\u0131z\u0131 kendi ihtiya\u00e7lar\u0131n\u0131za g\u00f6re \u015fekillendirme konusunda s\u0131n\u0131rs\u0131z olanaklara sahip olursunuz. Unutmay\u0131n, API token&#8217;lar\u0131n\u0131z\u0131n g\u00fcvenli\u011fini sa\u011flamak her zaman en y\u00fcksek \u00f6nceli\u011finiz olmal\u0131d\u0131r.<\/p>\n","protected":false},"excerpt":{"rendered":"DigitalOcean API Verilerini Django ile G\u00f6r\u00fcnt\u00fcleme Rehberi\nGiri\u015f\nG\u00fcn\u00fcm\u00fcz\u00fcn bulut tabanl\u0131 altyap\u0131lar\u0131, geli\u015ftiricilere ve sistem y\u00f6netic","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1401],"tags":[],"class_list":{"0":"post-31916","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-git","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>DigitalOcean API Verilerini Django ile G\u00f6r\u00fcnt\u00fcleme Rehberi - Kodlar\u0131n Gizemli D\u00fcnyas\u0131<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/digitalocean-api-verilerini-django-ile-goruntuleme-rehberi\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"DigitalOcean API Verilerini Django ile G\u00f6r\u00fcnt\u00fcleme Rehberi\" \/>\n<meta property=\"og:description\" content=\"DigitalOcean API Verilerini Django ile G\u00f6r\u00fcnt\u00fcleme Rehberi Giri\u015f G\u00fcn\u00fcm\u00fcz\u00fcn bulut tabanl\u0131 altyap\u0131lar\u0131, geli\u015ftiricilere ve sistem y\u00f6netic\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/digitalocean-api-verilerini-django-ile-goruntuleme-rehberi\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-10-15T11:41:06+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"17 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/digitalocean-api-verilerini-django-ile-goruntuleme-rehberi\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/digitalocean-api-verilerini-django-ile-goruntuleme-rehberi\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"DigitalOcean API Verilerini Django ile G\u00f6r\u00fcnt\u00fcleme Rehberi\",\"datePublished\":\"2025-10-15T11:41:06+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/digitalocean-api-verilerini-django-ile-goruntuleme-rehberi\/\"},\"wordCount\":1857,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"articleSection\":[\"Git\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/digitalocean-api-verilerini-django-ile-goruntuleme-rehberi\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/digitalocean-api-verilerini-django-ile-goruntuleme-rehberi\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/digitalocean-api-verilerini-django-ile-goruntuleme-rehberi\/\",\"name\":\"DigitalOcean API Verilerini Django ile G\u00f6r\u00fcnt\u00fcleme Rehberi - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-10-15T11:41:06+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/digitalocean-api-verilerini-django-ile-goruntuleme-rehberi\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/digitalocean-api-verilerini-django-ile-goruntuleme-rehberi\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/digitalocean-api-verilerini-django-ile-goruntuleme-rehberi\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"DigitalOcean API Verilerini Django ile G\u00f6r\u00fcnt\u00fcleme Rehberi\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"DigitalOcean API Verilerini Django ile G\u00f6r\u00fcnt\u00fcleme Rehberi - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/digitalocean-api-verilerini-django-ile-goruntuleme-rehberi\/","og_locale":"tr_TR","og_type":"article","og_title":"DigitalOcean API Verilerini Django ile G\u00f6r\u00fcnt\u00fcleme Rehberi","og_description":"DigitalOcean API Verilerini Django ile G\u00f6r\u00fcnt\u00fcleme Rehberi Giri\u015f G\u00fcn\u00fcm\u00fcz\u00fcn bulut tabanl\u0131 altyap\u0131lar\u0131, geli\u015ftiricilere ve sistem y\u00f6netic","og_url":"https:\/\/fatihsoysal.com\/blog\/digitalocean-api-verilerini-django-ile-goruntuleme-rehberi\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-10-15T11:41:06+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"17 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/digitalocean-api-verilerini-django-ile-goruntuleme-rehberi\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/digitalocean-api-verilerini-django-ile-goruntuleme-rehberi\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"DigitalOcean API Verilerini Django ile G\u00f6r\u00fcnt\u00fcleme Rehberi","datePublished":"2025-10-15T11:41:06+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/digitalocean-api-verilerini-django-ile-goruntuleme-rehberi\/"},"wordCount":1857,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"articleSection":["Git"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/digitalocean-api-verilerini-django-ile-goruntuleme-rehberi\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/digitalocean-api-verilerini-django-ile-goruntuleme-rehberi\/","url":"https:\/\/fatihsoysal.com\/blog\/digitalocean-api-verilerini-django-ile-goruntuleme-rehberi\/","name":"DigitalOcean API Verilerini Django ile G\u00f6r\u00fcnt\u00fcleme Rehberi - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-10-15T11:41:06+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/digitalocean-api-verilerini-django-ile-goruntuleme-rehberi\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/digitalocean-api-verilerini-django-ile-goruntuleme-rehberi\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/digitalocean-api-verilerini-django-ile-goruntuleme-rehberi\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"DigitalOcean API Verilerini Django ile G\u00f6r\u00fcnt\u00fcleme Rehberi"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/31916","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=31916"}],"version-history":[{"count":1,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/31916\/revisions"}],"predecessor-version":[{"id":31917,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/31916\/revisions\/31917"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=31916"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=31916"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=31916"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}