{"id":33840,"date":"2025-11-07T20:40:56","date_gmt":"2025-11-07T17:40:56","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/?p=33840"},"modified":"2025-11-07T20:40:56","modified_gmt":"2025-11-07T17:40:56","slug":"django-ve-react-ile-musteri-bilgilerini-yoneten-modern-bir-web-uygulamasi-nasil-gelistirilir-ubuntu-18-04-uzerinde","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/django-ve-react-ile-musteri-bilgilerini-yoneten-modern-bir-web-uygulamasi-nasil-gelistirilir-ubuntu-18-04-uzerinde\/","title":{"rendered":"Django ve React ile M\u00fc\u015fteri Bilgilerini Y\u00f6neten Modern Bir Web Uygulamas\u0131 Nas\u0131l Geli\u015ftirilir? (Ubuntu 18.04 \u00dczerinde)"},"content":{"rendered":"<p><body><\/p>\n<h2>Django ve React ile M\u00fc\u015fteri Bilgilerini Y\u00f6neten Modern Bir Web Uygulamas\u0131 Nas\u0131l Geli\u015ftirilir? (Ubuntu 18.04 \u00dczerinde)<\/h2>\n<p>Modern web uygulamalar\u0131, kullan\u0131c\u0131 deneyimi, performans ve \u00f6l\u00e7eklenebilirlik a\u00e7\u0131s\u0131ndan s\u00fcrekli geli\u015fen beklentilere yan\u0131t vermek zorundad\u0131r. Bu beklentileri kar\u015f\u0131lamak i\u00e7in bir\u00e7ok geli\u015ftirici, g\u00fc\u00e7l\u00fc bir arka u\u00e7 (backend) \u00e7er\u00e7evesi ile dinamik ve etkile\u015fimli bir \u00f6n u\u00e7 (frontend) k\u00fct\u00fcphanesini bir araya getirmeyi tercih eder. Bu makalede, Python tabanl\u0131 pop\u00fcler bir web \u00e7er\u00e7evesi olan Django&#8217;yu RESTful API olu\u015fturmak i\u00e7in ve JavaScript tabanl\u0131, kullan\u0131c\u0131 aray\u00fcz\u00fc geli\u015ftirmek i\u00e7in tercih edilen React&#8217;\u0131 \u00f6n u\u00e7ta kullan\u0131larak, m\u00fc\u015fteri bilgilerini y\u00f6neten modern bir web uygulamas\u0131 geli\u015ftirmeyi ad\u0131m ad\u0131m inceleyece\u011fiz. T\u00fcm bu s\u00fcre\u00e7leri Ubuntu 18.04 i\u015fletim sistemi \u00fczerinde ger\u00e7ekle\u015ftirece\u011fiz.<\/p>\n<p>M\u00fc\u015fteri \u0130li\u015fkileri Y\u00f6netimi (CRM) sistemleri, i\u015fletmeler i\u00e7in kritik \u00f6neme sahiptir. M\u00fc\u015fteri verilerini etkin bir \u015fekilde y\u00f6netmek, sat\u0131\u015flar\u0131 art\u0131rmak, m\u00fc\u015fteri memnuniyetini y\u00fckseltmek ve daha iyi i\u015f kararlar\u0131 almak i\u00e7in temel bir gerekliliktir. Geli\u015ftirece\u011fimiz uygulama, m\u00fc\u015fterilerin temel bilgilerini (ad, soyad, e-posta, telefon, adres vb.) ekleme, g\u00f6r\u00fcnt\u00fcleme, d\u00fczenleme ve silme yeteneklerine sahip olacak.<\/p>\n<h3>1. Giri\u015f: Modern Web Uygulamalar\u0131na Giri\u015f ve Neden Django\/React?<\/h3>\n<p>G\u00fcn\u00fcm\u00fcz web uygulamalar\u0131, genellikle bir taray\u0131c\u0131da \u00e7al\u0131\u015fan ve sunucu ile ileti\u015fim kurarak veri al\u0131p g\u00f6nderen tek sayfa uygulamalar\u0131 (Single Page Application &#8211; SPA) mimarisini benimsemektedir. SPA&#8217;lar, sayfa yenilemeleri olmadan h\u0131zl\u0131 ve ak\u0131c\u0131 bir kullan\u0131c\u0131 deneyimi sunar. Bu mimaride, backend bir RESTful API arac\u0131l\u0131\u011f\u0131yla verileri JSON format\u0131nda sa\u011flar ve frontend bu verileri t\u00fcketerek kullan\u0131c\u0131 aray\u00fcz\u00fcn\u00fc dinamik olarak g\u00fcnceller.<\/p>\n<p><strong>Neden Django?<\/strong><br \/>\nDjango, &#8220;aceleci geli\u015ftiriciler i\u00e7in m\u00fckemmeliyet\u00e7i bir \u00e7er\u00e7eve&#8221; slogan\u0131yla bilinen, y\u00fcksek seviyeli bir Python web \u00e7er\u00e7evesidir. H\u0131zl\u0131 geli\u015ftirme, temiz ve pragmatik tasar\u0131m felsefesi ile \u00f6ne \u00e7\u0131kar.<br \/>\n*   <strong>Tam Donan\u0131ml\u0131:<\/strong> Kendi ORM&#8217;i (Object-Relational Mapper), y\u00f6netim paneli, kimlik do\u011frulama sistemi ve daha bir\u00e7ok \u00f6zelli\u011fi ile gelir.<br \/>\n*   <strong>G\u00fcvenlik:<\/strong> CSRF, XSS, SQL Injection gibi yayg\u0131n g\u00fcvenlik a\u00e7\u0131klar\u0131na kar\u015f\u0131 yerle\u015fik korumalar sunar.<br \/>\n*   <strong>\u00d6l\u00e7eklenebilirlik:<\/strong> B\u00fcy\u00fck ve karma\u015f\u0131k projeler i\u00e7in uygundur.<br \/>\n*   <strong>DRF (Django REST Framework):<\/strong> Django ile kolayca g\u00fc\u00e7l\u00fc ve esnek RESTful API&#8217;ler olu\u015fturmay\u0131 sa\u011flar.<\/p>\n<p><strong>Neden React?<\/strong><br \/>\nReact, Facebook taraf\u0131ndan geli\u015ftirilen ve kullan\u0131c\u0131 aray\u00fczleri olu\u015fturmak i\u00e7in kullan\u0131lan bir JavaScript k\u00fct\u00fcphanesidir.<br \/>\n*   <strong>Bile\u015fen Tabanl\u0131 Mimari:<\/strong> Uygulamay\u0131 k\u00fc\u00e7\u00fck, yeniden kullan\u0131labilir bile\u015fenlere ay\u0131rarak geli\u015ftirme s\u00fcrecini basitle\u015ftirir.<br \/>\n*   <strong>Sanal DOM:<\/strong> Performansl\u0131 g\u00fcncellemeler sa\u011flar, sadece de\u011fi\u015fen k\u0131s\u0131mlar\u0131 render eder.<br \/>\n*   <strong>Geni\u015f Ekosistem:<\/strong> B\u00fcy\u00fck bir toplulu\u011fa, zengin k\u00fct\u00fcphanelere ve ara\u00e7lara sahiptir.<br \/>\n*   <strong>Tek Y\u00f6nl\u00fc Veri Ak\u0131\u015f\u0131:<\/strong> Uygulaman\u0131n durumunu y\u00f6netmeyi kolayla\u015ft\u0131r\u0131r.<\/p>\n<p><strong>Ubuntu 18.04:<\/strong><br \/>\nUbuntu, sunucu ortamlar\u0131nda yayg\u0131n olarak kullan\u0131lan stabil ve g\u00fcvenilir bir Linux da\u011f\u0131t\u0131m\u0131d\u0131r. 18.04 LTS (Long Term Support) s\u00fcr\u00fcm\u00fc, uzun s\u00fcreli destek sunmas\u0131 nedeniyle \u00fcretim ortamlar\u0131 i\u00e7in s\u0131k\u00e7a tercih edilir. Geli\u015ftirme ortam\u0131m\u0131z\u0131 bu platform \u00fczerinde kuraca\u011f\u0131z.<\/p>\n<h3>2. Proje \u00d6n Haz\u0131rl\u0131\u011f\u0131: Geli\u015ftirme Ortam\u0131n\u0131n Kurulumu (Ubuntu 18.04)<\/h3>\n<p>Uygulama geli\u015ftirmeye ba\u015flamadan \u00f6nce, gerekli t\u00fcm yaz\u0131l\u0131mlar\u0131 Ubuntu 18.04 sistemimize kurmam\u0131z gerekiyor.<\/p>\n<h4>2.1. Sistem G\u00fcncellemesi ve Temel Paketler<\/h4>\n<p>\u0130lk ad\u0131m olarak, sistem paket listemizi g\u00fcncelleyelim ve y\u00fckseltelim:<\/p>\n<pre><code class=\"language-bash\">sudo apt update\nsudo apt upgrade -y<\/code><\/pre>\n<p>Geli\u015ftirme i\u00e7in gerekli olabilecek baz\u0131 temel paketleri kural\u0131m:<\/p>\n<pre><code class=\"language-bash\">sudo apt install build-essential libssl-dev libffi-dev python3-dev -y<\/code><\/pre>\n<h4>2.2. Python ve pip Kurulumu<\/h4>\n<p>Ubuntu 18.04, Python 3 ile birlikte gelir. Ancak <code>pip<\/code> (Python paket y\u00f6neticisi) ve <code>venv<\/code> (sanal ortam olu\u015fturma arac\u0131) kurulu olmayabilir.<\/p>\n<pre><code class=\"language-bash\">sudo apt install python3-pip python3-venv -y<\/code><\/pre>\n<p>Sanal ortamlar, projemizin ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131 sistem genelindeki Python paketlerinden izole etmek i\u00e7in kritik \u00f6neme sahiptir. Projemiz i\u00e7in bir sanal ortam olu\u015ftural\u0131m ve etkinle\u015ftirelim:<\/p>\n<pre><code class=\"language-bash\">mkdir customer_crm\ncd customer_crm\npython3 -m venv venv_backend\nsource venv_backend\/bin\/activate<\/code><\/pre>\n<p>Art\u0131k terminalin ba\u015f\u0131nda <code>(venv_backend)<\/code> g\u00f6receksiniz, bu sanal ortam\u0131n etkin oldu\u011funu g\u00f6sterir.<\/p>\n<h4>2.3. Node.js ve npm Kurulumu<\/h4>\n<p>React uygulamas\u0131 geli\u015ftirmek i\u00e7in Node.js ve npm&#8217;e (Node paket y\u00f6neticisi) ihtiyac\u0131m\u0131z var. Ubuntu 18.04&#8217;\u00fcn varsay\u0131lan depolar\u0131ndaki Node.js s\u00fcr\u00fcm\u00fc eski olabilir, bu y\u00fczden daha g\u00fcncel bir s\u00fcr\u00fcm i\u00e7in NodeSource deposunu kullanmak daha iyidir.<\/p>\n<pre><code class=\"language-bash\">curl -sL https:\/\/deb.nodesource.com\/setup_14.x | sudo -E bash -\nsudo apt install nodejs -y<\/code><\/pre>\n<p>Kurulumu do\u011frulay\u0131n:<\/p>\n<pre><code class=\"language-bash\">node -v\nnpm -v<\/code><\/pre>\n<p>Bu komutlar Node.js ve npm&#8217;in s\u00fcr\u00fcm numaralar\u0131n\u0131 g\u00f6stermelidir.<\/p>\n<h4>2.4. Veritaban\u0131 Kurulumu (PostgreSQL \u00d6nerisi)<\/h4>\n<p>Django, varsay\u0131lan olarak SQLite kullanabilir ancak \u00fcretim ortamlar\u0131 i\u00e7in PostgreSQL gibi daha g\u00fc\u00e7l\u00fc bir veritaban\u0131 \u00f6nerilir.<\/p>\n<pre><code class=\"language-bash\">sudo apt install postgresql postgresql-contrib -y<\/code><\/pre>\n<p>PostgreSQL kurulumundan sonra, bir veritaban\u0131 kullan\u0131c\u0131s\u0131 ve veritaban\u0131 olu\u015ftural\u0131m:<\/p>\n<pre><code class=\"language-bash\">sudo -i -u postgres psql<\/code><\/pre>\n<p>PostgreSQL komut isteminde:<\/p>\n<pre><code class=\"language-sql\">CREATE USER crmuser WITH PASSWORD 'your_secure_password';\nCREATE DATABASE customer_crm_db OWNER crmuser;\nGRANT ALL PRIVILEGES ON DATABASE customer_crm_db TO crmuser;\n\\q<\/code><\/pre>\n<p><code>your_secure_password<\/code> yerine g\u00fc\u00e7l\u00fc bir \u015fifre belirledi\u011finizden emin olun.<\/p>\n<h3>3. Django Backend Geli\u015ftirme: REST API Olu\u015fturma<\/h3>\n<p>\u015eimdi sanal ortam\u0131m\u0131z etkin durumdayken Django backend&#8217;imizi geli\u015ftirmeye ba\u015flayabiliriz.<\/p>\n<h4>3.1. Django Projesi ve Uygulamas\u0131 Olu\u015fturma<\/h4>\n<p>Gerekli Django ve Django REST Framework paketlerini kural\u0131m:<\/p>\n<pre><code class=\"language-bash\">pip install django djangorestframework psycopg2-binary<\/code><\/pre>\n<p><code>psycopg2-binary<\/code> paketi, Django&#8217;nun PostgreSQL ile ileti\u015fim kurmas\u0131n\u0131 sa\u011flar.<br \/>\n\u015eimdi bir Django projesi ve bir uygulama olu\u015ftural\u0131m:<\/p>\n<pre><code class=\"language-bash\">django-admin startproject customer_crm_backend .\npython manage.py startapp customers<\/code><\/pre>\n<p><code>customer_crm_backend\/settings.py<\/code> dosyas\u0131n\u0131 a\u00e7\u0131n ve <code>INSTALLED_APPS<\/code> listesine <code>rest_framework<\/code> ve <code>customers<\/code> uygulamalar\u0131n\u0131 ekleyin. Ayr\u0131ca veritaban\u0131 ayarlar\u0131n\u0131 PostgreSQL&#8217;e g\u00f6re yap\u0131land\u0131r\u0131n:<\/p>\n<pre><code class=\"language-python\"># customer_crm_backend\/settings.py\n\nINSTALLED_APPS = [\n    # ... di\u011fer uygulamalar ...\n    'rest_framework',\n    'customers',\n]\n\nDATABASES = {\n    'default': {\n        'ENGINE': 'django.db.backends.postgresql',\n        'NAME': 'customer_crm_db',\n        'USER': 'crmuser',\n        'PASSWORD': 'your_secure_password',\n        'HOST': 'localhost',\n        'PORT': '',\n    }\n}\n\n<h2>CORS ayarlar\u0131 i\u00e7in daha sonra eklenecek<\/h2>\nCORS_ORIGIN_WHITELIST = [\n    'http:\/\/localhost:3000', # React uygulamas\u0131n\u0131n \u00e7al\u0131\u015ft\u0131\u011f\u0131 port\n]\nCORS_ALLOW_CREDENTIALS = True<\/code><\/pre>\n<h4>3.2. M\u00fc\u015fteri Modeli Tan\u0131mlama<\/h4>\n<p><code>customers\/models.py<\/code> dosyas\u0131nda m\u00fc\u015fteri verilerini saklamak i\u00e7in bir model olu\u015ftural\u0131m:<\/p>\n<pre><code class=\"language-python\"># customers\/models.py\n\nfrom django.db import models\n\nclass Customer(models.Model):\n    name = models.CharField(max_length=100)\n    email = models.EmailField(unique=True)\n    phone = models.CharField(max_length=20, blank=True, null=True)\n    address = models.TextField(blank=True, null=True)\n    created_at = models.DateTimeField(auto_now_add=True)\n    updated_at = models.DateTimeField(auto_now=True)\n\n    def __str__(self):\n        return self.name<\/code><\/pre>\n<p>Modeli olu\u015fturduktan sonra veritaban\u0131 g\u00f6\u00e7lerini (migrations) yapmam\u0131z gerekir:<\/p>\n<pre><code class=\"language-bash\">python manage.py makemigrations\npython manage.py migrate<\/code><\/pre>\n<p>Django&#8217;nun y\u00f6netim panelini kullanmak i\u00e7in bir s\u00fcper kullan\u0131c\u0131 olu\u015ftural\u0131m:<\/p>\n<pre><code class=\"language-bash\">python manage.py createsuperuser<\/code><\/pre>\n<h4>3.3. Serializers ile Veri D\u00f6n\u00fc\u015f\u00fcm\u00fc<\/h4>\n<p>Django modellerini JSON gibi formatlara d\u00f6n\u00fc\u015ft\u00fcrmek i\u00e7in <code>serializers<\/code> kullan\u0131r\u0131z. <code>customers<\/code> uygulamas\u0131 i\u00e7inde <code>serializers.py<\/code> ad\u0131nda yeni bir dosya olu\u015ftural\u0131m:<\/p>\n<pre><code class=\"language-python\"># customers\/serializers.py\n\nfrom rest_framework import serializers\nfrom .models import Customer\n\nclass CustomerSerializer(serializers.ModelSerializer):\n    class Meta:\n        model = Customer\n        fields = '__all__' # T\u00fcm alanlar\u0131 dahil et<\/code><\/pre>\n<h4>3.4. ViewSets ve Routerlar ile API Endpointleri<\/h4>\n<p><code>customers\/views.py<\/code> dosyas\u0131nda <code>Customer<\/code> modeli i\u00e7in bir <code>ViewSet<\/code> olu\u015ftural\u0131m. <code>ModelViewSet<\/code>, CRUD (Create, Retrieve, Update, Delete) operasyonlar\u0131n\u0131 otomatik olarak sa\u011flar.<\/p>\n<pre><code class=\"language-python\"># customers\/views.py\n\nfrom rest_framework import viewsets\nfrom .models import Customer\nfrom .serializers import CustomerSerializer\n\nclass CustomerViewSet(viewsets.ModelViewSet):\n    queryset = Customer.objects.all().order_by('-created_at')\n    serializer_class = CustomerSerializer<\/code><\/pre>\n<p>\u015eimdi bu <code>ViewSet<\/code> i\u00e7in URL&#8217;leri tan\u0131mlamam\u0131z gerekiyor. <code>customers<\/code> uygulamas\u0131 i\u00e7inde <code>urls.py<\/code> ad\u0131nda yeni bir dosya olu\u015ftural\u0131m:<\/p>\n<pre><code class=\"language-python\"># customers\/urls.py\n\nfrom rest_framework.routers import DefaultRouter\nfrom .views import CustomerViewSet\n\nrouter = DefaultRouter()\nrouter.register(r'customers', CustomerViewSet)\n\nurlpatterns = router.urls<\/code><\/pre>\n<p>Son olarak, ana proje <code>customer_crm_backend\/urls.py<\/code> dosyas\u0131nda bu URL&#8217;leri dahil edelim:<\/p>\n<pre><code class=\"language-python\"># customer_crm_backend\/urls.py\n\nfrom django.contrib import admin\nfrom django.urls import path, include\n\nurlpatterns = [\n    path('admin\/', admin.site.urls),\n    path('api\/', include('customers.urls')), # API URL'lerini dahil et\n]<\/code><\/pre>\n<p>Backend sunucumuzu \u00e7al\u0131\u015ft\u0131rabiliriz:<\/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\/api\/customers\/<\/code> adresine giderek DRF&#8217;nin otomatik olarak olu\u015fturdu\u011fu API aray\u00fcz\u00fcn\u00fc g\u00f6rebilirsiniz.<\/p>\n<h4>3.5. Authentication ve Yetkilendirme (Opsiyonel ama \u00d6nemli)<\/h4>\n<p>Ger\u00e7ek bir uygulamada API&#8217;lerinizi g\u00fcvence alt\u0131na alman\u0131z gerekir. Django REST Framework, Token Authentication, Session Authentication, JWT (JSON Web Token) gibi \u00e7e\u015fitli kimlik do\u011frulama y\u00f6ntemlerini destekler. Basit bir token tabanl\u0131 kimlik do\u011frulama i\u00e7in:<br \/>\n<code>settings.py<\/code> i\u00e7inde <code>REST_FRAMEWORK<\/code> ayar\u0131n\u0131 ekleyin:<\/p>\n<pre><code class=\"language-python\"># customer_crm_backend\/settings.py\n\nREST_FRAMEWORK = {\n    'DEFAULT_AUTHENTICATION_CLASSES': [\n        'rest_framework.authentication.TokenAuthentication',\n    ],\n    'DEFAULT_PERMISSION_CLASSES': [\n        'rest_framework.permissions.IsAuthenticated',\n    ]\n}\nINSTALLED_APPS += [\n    'rest_framework.authtoken',\n]<\/code><\/pre>\n<p><code>makemigrations<\/code> ve <code>migrate<\/code> komutlar\u0131n\u0131 tekrar \u00e7al\u0131\u015ft\u0131r\u0131n.<br \/>\nBir kullan\u0131c\u0131 i\u00e7in token olu\u015fturmak i\u00e7in <code>createsuperuser<\/code> ile olu\u015fturdu\u011funuz kullan\u0131c\u0131y\u0131 kullanabilir veya <code>python manage.py drf_create_token <username><\/code> komutunu kullanabilirsiniz.<\/p>\n<h3>4. React Frontend Geli\u015ftirme: Kullan\u0131c\u0131 Aray\u00fcz\u00fc Olu\u015fturma<\/h3>\n<p>\u015eimdi s\u0131ra React ile kullan\u0131c\u0131 aray\u00fcz\u00fcn\u00fc olu\u015fturmaya geldi. Backend projemizin k\u00f6k dizininden ayr\u0131 bir dizinde frontend projemizi olu\u015ftural\u0131m.<\/p>\n<pre><code class=\"language-bash\">cd .. # customer_crm dizinine geri d\u00f6n\nnpx create-react-app customer-crm-frontend\ncd customer-crm-frontend<\/code><\/pre>\n<p>Gerekli paketleri kural\u0131m:<\/p>\n<pre><code class=\"language-bash\">npm install axios react-router-dom<\/code><\/pre>\n<p><code>axios<\/code> HTTP istekleri yapmak i\u00e7in, <code>react-router-dom<\/code> ise sayfa y\u00f6nlendirmeleri i\u00e7in kullan\u0131lacak.<\/p>\n<h4>4.1. Proje Yap\u0131s\u0131 ve Bile\u015fenler<\/h4>\n<p><code>src<\/code> dizini alt\u0131nda <code>components<\/code> ve <code>pages<\/code> ad\u0131nda dizinler olu\u015ftural\u0131m.<\/p>\n<pre><code class=\"language-\">customer-crm-frontend\/\n\u251c\u2500\u2500 public\/\n\u251c\u2500\u2500 src\/\n\u2502   \u251c\u2500\u2500 components\/\n\u2502   \u2502   \u251c\u2500\u2500 CustomerForm.js\n\u2502   \u2502   \u2514\u2500\u2500 CustomerList.js\n\u2502   \u251c\u2500\u2500 pages\/\n\u2502   \u2502   \u251c\u2500\u2500 HomePage.js\n\u2502   \u2502   \u2514\u2500\u2500 CustomerDetailPage.js\n\u2502   \u251c\u2500\u2500 App.js\n\u2502   \u251c\u2500\u2500 index.js\n\u2502   \u2514\u2500\u2500 ... di\u011fer dosyalar\n\u251c\u2500\u2500 package.json\n\u2514\u2500\u2500 ...<\/code><\/pre>\n<h4>4.2. API Entegrasyonu (axios kullan\u0131m\u0131)<\/h4>\n<p>API isteklerini y\u00f6netmek i\u00e7in <code>src\/api.js<\/code> ad\u0131nda bir dosya olu\u015fturabiliriz:<\/p>\n<pre><code class=\"language-javascript\">\/\/ src\/api.js\nimport axios from 'axios';\n\nconst api = axios.create({\n    baseURL: 'http:\/\/localhost:8000\/api\/', \/\/ Django backend API adresimiz\n    headers: {\n        'Content-Type': 'application\/json',\n        \/\/ 'Authorization': <code>Token YOUR_AUTH_TOKEN<\/code> \/\/ E\u011fer kimlik do\u011frulama kullan\u0131yorsan\u0131z\n    }\n});\n\nexport default api;<\/code><\/pre>\n<h4>4.3. M\u00fc\u015fteri Listeleme Bile\u015feni (<code>CustomerList.js<\/code>)<\/h4>\n<p><code>src\/components\/CustomerList.js<\/code> dosyas\u0131n\u0131 olu\u015ftural\u0131m:<\/p>\n<pre><code class=\"language-javascript\">\/\/ src\/components\/CustomerList.js\nimport React, { useEffect, useState } from 'react';\nimport api from '..\/api';\nimport { Link } from 'react-router-dom';\n\nfunction CustomerList() {\n    const [customers, setCustomers] = useState([]);\n\n    useEffect(() => {\n        api.get('\/customers\/')\n            .then(response => setCustomers(response.data))\n            .catch(error => console.error('M\u00fc\u015fterileri \u00e7ekerken hata:', error));\n    }, []);\n\n    const handleDelete = (id) => {\n        if (window.confirm('Bu m\u00fc\u015fteriyi silmek istedi\u011finizden emin misiniz?')) {\n            api.delete(<code>\/customers\/${id}\/<\/code>)\n                .then(() => {\n                    setCustomers(customers.filter(customer => customer.id !== id));\n                })\n                .catch(error => console.error('M\u00fc\u015fteri silinirken hata:', error));\n        }\n    };\n\n    return (\n        <div>\n            <h2>M\u00fc\u015fteri Listesi<\/h2>\n            <Link to=\"\/customers\/new\" className=\"btn btn-primary\">Yeni M\u00fc\u015fteri Ekle<\/Link>\n            <ul>\n                {customers.map(customer => (\n                    <li key={customer.id}>\n                        {customer.name} - {customer.email}\n                        <Link to={<code>\/customers\/edit\/${customer.id}<\/code>} className=\"btn btn-sm btn-info\">D\u00fczenle<\/Link>\n                        <button onClick={() => handleDelete(customer.id)} className=\"btn btn-sm btn-danger\">Sil<\/button>\n                    <\/li>\n                ))}\n            <\/ul>\n        <\/div>\n    );\n}\n\nexport default CustomerList;<\/code><\/pre>\n<h4>4.4. M\u00fc\u015fteri Ekleme\/D\u00fczenleme Bile\u015feni (<code>CustomerForm.js<\/code>)<\/h4>\n<p><code>src\/components\/CustomerForm.js<\/code> dosyas\u0131n\u0131 olu\u015ftural\u0131m. Bu form hem yeni m\u00fc\u015fteri eklemek hem de mevcut m\u00fc\u015fteriyi d\u00fczenlemek i\u00e7in kullan\u0131labilir.<\/p>\n<pre><code class=\"language-javascript\">\/\/ src\/components\/CustomerForm.js\nimport React, { useState, useEffect } from 'react';\nimport { useNavigate, useParams } from 'react-router-dom';\nimport api from '..\/api';\n\nfunction CustomerForm() {\n    const [customer, setCustomer] = useState({ name: '', email: '', phone: '', address: '' });\n    const navigate = useNavigate();\n    const { id } = useParams(); \/\/ URL'den m\u00fc\u015fteri ID'sini al (d\u00fczenleme modunda)\n\n    useEffect(() => {\n        if (id) {\n            api.get(<code>\/customers\/${id}\/<\/code>)\n                .then(response => setCustomer(response.data))\n                .catch(error => console.error('M\u00fc\u015fteri bilgisi \u00e7ekilirken hata:', error));\n        }\n    }, [id]);\n\n    const handleChange = (e) => {\n        const { name, value } = e.target;\n        setCustomer(prevCustomer => ({ ...prevCustomer, [name]: value }));\n    };\n\n    const handleSubmit = (e) => {\n        e.preventDefault();\n        if (id) {\n            \/\/ D\u00fczenleme\n            api.put(<code>\/customers\/${id}\/<\/code>, customer)\n                .then(() => navigate('\/'))\n                .catch(error => console.error('M\u00fc\u015fteri g\u00fcncellenirken hata:', error));\n        } else {\n            \/\/ Yeni ekleme\n            api.post('\/customers\/', customer)\n                .then(() => navigate('\/'))\n                .catch(error => console.error('Yeni m\u00fc\u015fteri eklenirken hata:', error));\n        }\n    };\n\n    return (\n        <div>\n            <h2>{id ? 'M\u00fc\u015fteriyi D\u00fczenle' : 'Yeni M\u00fc\u015fteri Ekle'}<\/h2>\n            <form onSubmit={handleSubmit}>\n                <div>\n                    <label>Ad:<\/label>\n                    <input type=\"text\" name=\"name\" value={customer.name} onChange={handleChange} required \/>\n                <\/div>\n                <div>\n                    <label>E-posta:<\/label>\n                    <input type=\"email\" name=\"email\" value={customer.email} onChange={handleChange} required \/>\n                <\/div>\n                <div>\n                    <label>Telefon:<\/label>\n                    <input type=\"text\" name=\"phone\" value={customer.phone} onChange={handleChange} \/>\n                <\/div>\n                <div>\n                    <label>Adres:<\/label>\n                    <textarea name=\"address\" value={customer.address} onChange={handleChange}><\/textarea>\n                <\/div>\n                <button type=\"submit\">{id ? 'G\u00fcncelle' : 'Ekle'}<\/button>\n            <\/form>\n        <\/div>\n    );\n}\n\nexport default CustomerForm;<\/code><\/pre>\n<h4>4.5. Routing (<code>react-router-dom<\/code>)<\/h4>\n<p><code>src\/App.js<\/code> dosyas\u0131n\u0131 y\u00f6nlendirmeleri ayarlamak i\u00e7in g\u00fcncelleyelim:<\/p>\n<pre><code class=\"language-javascript\">\/\/ src\/App.js\nimport React from 'react';\nimport { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';\nimport CustomerList from '.\/components\/CustomerList';\nimport CustomerForm from '.\/components\/CustomerForm';\nimport '.\/App.css'; \/\/ Temel stil dosyas\u0131\n\nfunction App() {\n    return (\n        <Router>\n            <div className=\"App\">\n                <nav>\n                    <Link to=\"\/\">Ana Sayfa<\/Link>\n                    <Link to=\"\/customers\/new\">Yeni M\u00fc\u015fteri<\/Link>\n                <\/nav>\n                <div className=\"container\">\n                    <Routes>\n                        <Route path=\"\/\" element={<CustomerList \/>} \/>\n                        <Route path=\"\/customers\/new\" element={<CustomerForm \/>} \/>\n                        <Route path=\"\/customers\/edit\/:id\" element={<CustomerForm \/>} \/>\n                    <\/Routes>\n                <\/div>\n            <\/div>\n        <\/Router>\n    );\n}\n\nexport default App;<\/code><\/pre>\n<p><code>src\/App.css<\/code> dosyas\u0131nda basit stil tan\u0131mlamalar\u0131 yapabilirsiniz. Frontend uygulamas\u0131n\u0131 ba\u015flatmak i\u00e7in:<\/p>\n<pre><code class=\"language-bash\">npm start<\/code><\/pre>\n<p>Taray\u0131c\u0131n\u0131zda <code>http:\/\/localhost:3000<\/code> adresine giderek React uygulaman\u0131z\u0131 g\u00f6rebilirsiniz.<\/p>\n<h4>4.6. Durum Y\u00f6netimi (Context API veya Redux)<\/h4>\n<p>K\u00fc\u00e7\u00fck uygulamalar i\u00e7in <code>useState<\/code> ve prop drilling yeterli olabilirken, daha karma\u015f\u0131k uygulamalarda global durum y\u00f6netimi i\u00e7in React Context API veya Redux gibi k\u00fct\u00fcphaneler tercih edilir. Bu makalede basitlik ad\u0131na <code>useState<\/code> kullan\u0131lm\u0131\u015ft\u0131r, ancak b\u00fcy\u00fcyen bir uygulamada bu ara\u00e7lar\u0131 de\u011ferlendirmek \u00f6nemlidir. Context API, belirli bir alt a\u011fa\u00e7taki t\u00fcm bile\u015fenlerin ayn\u0131 veriye eri\u015fmesini sa\u011flayarak prop drilling sorununu \u00e7\u00f6zer. Redux ise daha b\u00fcy\u00fck ve karma\u015f\u0131k uygulamalar i\u00e7in merkezi bir durum deposu sunar.<\/p>\n<h3>5. Django ve React Entegrasyonu: \u0130leti\u015fim ve Da\u011f\u0131t\u0131m Yakla\u015f\u0131mlar\u0131<\/h3>\n<p>Backend ve frontend ayr\u0131 ayr\u0131 \u00e7al\u0131\u015ft\u0131\u011f\u0131 i\u00e7in birbirleriyle ileti\u015fim kurmalar\u0131 ve sonunda tek bir uygulama olarak da\u011f\u0131t\u0131lmalar\u0131 gerekmektedir.<\/p>\n<h4>5.1. CORS Yap\u0131land\u0131rmas\u0131<\/h4>\n<p>Frontend (React) ve backend (Django) farkl\u0131 portlarda \u00e7al\u0131\u015ft\u0131\u011f\u0131 i\u00e7in taray\u0131c\u0131lar g\u00fcvenlik nedeniyle &#8220;Cross-Origin Resource Sharing&#8221; (CORS) politikalar\u0131n\u0131 uygular. Django&#8217;nun React uygulamam\u0131zdan gelen isteklere izin vermesi i\u00e7in <code>django-cors-headers<\/code> paketini kullanmal\u0131y\u0131z.<br \/>\nBackend sanal ortam\u0131n\u0131z etkin durumdayken:<\/p>\n<pre><code class=\"language-bash\">pip install django-cors-headers<\/code><\/pre>\n<p><code>customer_crm_backend\/settings.py<\/code> dosyas\u0131n\u0131 g\u00fcncelleyin:<\/p>\n<pre><code class=\"language-python\"># customer_crm_backend\/settings.py\n\nINSTALLED_APPS = [\n    # ...\n    'corsheaders', # CORS uygulamas\u0131n\u0131 ekle\n    # ...\n]\n\nMIDDLEWARE = [\n    'corsheaders.middleware.CorsMiddleware', # En \u00fcste yak\u0131n ekle\n    # ... di\u011fer middleware'ler ...\n]\n\nCORS_ALLOWED_ORIGINS = [ # Belirli originlere izin ver\n    \"http:\/\/localhost:3000\",\n]\n<h2>Veya t\u00fcm originlere izin vermek i\u00e7in (sadece geli\u015ftirme ortam\u0131 i\u00e7in \u00f6nerilir)<\/h2>\n<h2>CORS_ALLOW_ALL_ORIGINS = True<\/code><\/pre>\n<\/h2>\n<h4>5.2. Statik Dosyalar ve Medya Y\u00f6netimi<\/h4>\n<p>React uygulamas\u0131 derlendi\u011finde (build edildi\u011finde) statik HTML, CSS ve JavaScript dosyalar\u0131 \u00fcretir. \u00dcretim ortam\u0131nda bu dosyalar\u0131n sunulmas\u0131 gerekir.<\/p>\n<h4>5.3. Geli\u015ftirme Ortam\u0131nda Birlikte \u00c7al\u0131\u015ft\u0131rma<\/h4>\n<p>Geli\u015ftirme s\u0131ras\u0131nda Django backend&#8217;i <code>python manage.py runserver<\/code> ile bir terminalde ve React frontend&#8217;i <code>npm start<\/code> ile ba\u015fka bir terminalde \u00e7al\u0131\u015ft\u0131r\u0131l\u0131r. CORS ayarlar\u0131 sayesinde bu iki farkl\u0131 sunucu birbirleriyle ileti\u015fim kurabilir.<\/p>\n<h4>5.4. \u00dcretim Ortam\u0131na Da\u011f\u0131t\u0131m \u0130\u00e7in Yakla\u015f\u0131mlar<\/h4>\n<p>\u00dcretim ortam\u0131nda, React uygulamas\u0131n\u0131 derleyip (build) statik dosyalar\u0131n\u0131 olu\u015ftururuz ve bu dosyalar\u0131 bir web sunucusu (Nginx gibi) arac\u0131l\u0131\u011f\u0131yla sunar\u0131z. Django backend&#8217;i ise Gunicorn gibi bir WSGI sunucusu ile \u00e7al\u0131\u015ft\u0131r\u0131l\u0131r ve Nginx bu sunucuya ters proxy olarak istekleri y\u00f6nlendirir.<\/p>\n<p><strong>Ad\u0131mlar:<\/strong><br \/>\n1.  <strong>React Uygulamas\u0131n\u0131 Derle:<\/strong><\/p>\n<pre><code class=\"language-bash\">cd customer-crm-frontend\n    npm run build<\/code><\/pre>\n<p>    Bu komut, <code>build<\/code> dizini alt\u0131nda optimize edilmi\u015f statik dosyalar\u0131 olu\u015fturur.<\/p>\n<p>2.  <strong>Gunicorn ile Django&#8217;yu \u00c7al\u0131\u015ft\u0131r:<\/strong><\/p>\n<pre><code class=\"language-bash\">cd ..\/customer_crm_backend\n    pip install gunicorn\n    gunicorn customer_crm_backend.wsgi:application --bind 0.0.0.0:8000<\/code><\/pre>\n<p>    Bu, Django uygulaman\u0131z\u0131 8000 portunda \u00e7al\u0131\u015ft\u0131r\u0131r.<\/p>\n<p>3.  <strong>Nginx ile Ters Proxy ve Statik Dosya Sunumu:<\/strong><br \/>\n    Nginx, hem React&#8217;in derlenmi\u015f statik dosyalar\u0131n\u0131 sunacak hem de API isteklerini Gunicorn&#8217;a y\u00f6nlendirecektir.<\/p>\n<pre><code class=\"language-bash\">sudo apt install nginx -y\n    sudo nano \/etc\/nginx\/sites-available\/customer_crm<\/code><\/pre>\n<p>    \u0130\u00e7eri\u011fi a\u015fa\u011f\u0131daki gibi d\u00fczenleyin:<\/p>\n<pre><code class=\"language-nginx\">server {\n        listen 80;\n        server_name your_domain_or_ip; # Kendi alan ad\u0131n\u0131z\u0131 veya IP adresinizi girin\n\n        location \/ {\n            root \/path\/to\/customer_crm\/customer-crm-frontend\/build; # React build dizini\n            try_files $uri \/index.html;\n        }\n\n        location \/api\/ {\n            proxy_pass http:\/\/127.0.0.1:8000; # Gunicorn'un \u00e7al\u0131\u015ft\u0131\u011f\u0131 adres\n            proxy_set_header Host $host;\n            proxy_set_header X-Real-IP $remote_addr;\n            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n            proxy_set_header X-Forwarded-Proto $scheme;\n        }\n\n        # Django'nun statik dosyalar\u0131 (gerekirse)\n        # location \/static\/ {\n        #     alias \/path\/to\/customer_crm\/customer_crm_backend\/static_root\/;\n        # }\n    }<\/code><\/pre>\n<p>    <code>your_domain_or_ip<\/code> ve <code>\/path\/to\/customer_crm\/<\/code> k\u0131s\u0131mlar\u0131n\u0131 kendi ortam\u0131n\u0131za g\u00f6re g\u00fcncelleyin.<br \/>\n    Nginx yap\u0131land\u0131rmas\u0131n\u0131 etkinle\u015ftirin ve yeniden ba\u015flat\u0131n:<\/p>\n<pre><code class=\"language-bash\">sudo ln -s \/etc\/nginx\/sites-available\/customer_crm \/etc\/nginx\/sites-enabled\/\n    sudo systemctl restart nginx<\/code><\/pre>\n<p>    Bu yap\u0131land\u0131rma ile, <code>your_domain_or_ip<\/code> adresine gelen t\u00fcm istekler React uygulamas\u0131n\u0131 sunacak, <code>\/api\/<\/code> ile ba\u015flayan istekler ise Django backend&#8217;ine y\u00f6nlendirilecektir.<\/p>\n<h3>6. Test ve G\u00fcvenlik<\/h3>\n<p>Her modern web uygulamas\u0131nda test ve g\u00fcvenlik kritik \u00f6neme sahiptir.<\/p>\n<h4>6.1. Backend Testleri (Django)<\/h4>\n<p>Django, testler yazmak i\u00e7in kapsaml\u0131 bir \u00e7er\u00e7eve sunar. <code>TestCase<\/code> s\u0131n\u0131f\u0131n\u0131 kullanarak model, view ve API testleri yazabilirsiniz. <code>rest_framework.test.APITestCase<\/code> API endpoint&#8217;lerini test etmek i\u00e7in \u00f6zel ara\u00e7lar sa\u011flar.<\/p>\n<pre><code class=\"language-python\"># customers\/tests.py\nfrom rest_framework.test import APITestCase\nfrom rest_framework import status\nfrom django.urls import reverse\nfrom .models import Customer\n\nclass CustomerAPITest(APITestCase):\n    def setUp(self):\n        self.customer_data = {'name': 'Test M\u00fc\u015fteri', 'email': 'test@example.com'}\n        self.customer = Customer.objects.create(<em><\/em>self.customer_data)\n        self.list_url = reverse('customer-list') # router'dan gelen URL ad\u0131\n        self.detail_url = reverse('customer-detail', kwargs={'pk': self.customer.id})\n\n    def test_create_customer(self):\n        response = self.client.post(self.list_url, {'name': 'Yeni M\u00fc\u015fteri', 'email': 'yeni@example.com'})\n        self.assertEqual(response.status_code, status.HTTP_201_CREATED)\n        self.assertEqual(Customer.objects.count(), 2)\n\n    def test_get_customer_list(self):\n        response = self.client.get(self.list_url)\n        self.assertEqual(response.status_code, status.HTTP_200_OK)\n        self.assertEqual(len(response.data), 1)\n\n    # ... di\u011fer testler (g\u00fcncelleme, silme)<\/code><\/pre>\n<p>Testleri \u00e7al\u0131\u015ft\u0131rmak i\u00e7in: <code>python manage.py test customers<\/code><\/p>\n<h4>6.2. Frontend Testleri (Jest, React Testing Library)<\/h4>\n<p>React uygulamalar\u0131 i\u00e7in Jest bir test \u00e7al\u0131\u015ft\u0131r\u0131c\u0131s\u0131, React Testing Library ise bile\u015fenlerin kullan\u0131c\u0131 etkile\u015fimlerini sim\u00fcle ederek test edilmesini sa\u011flayan pop\u00fcler ara\u00e7lard\u0131r. <code>create-react-app<\/code> varsay\u0131lan olarak bu ara\u00e7larla gelir.<\/p>\n<pre><code class=\"language-javascript\">\/\/ src\/components\/CustomerList.test.js\nimport { render, screen, waitFor } from '@testing-library\/react';\nimport CustomerList from '.\/CustomerList';\nimport api from '..\/api';\n\njest.mock('..\/api'); \/\/ api mod\u00fcl\u00fcn\u00fc mock'la\n\ntest('renders customer list', async () => {\n  api.get.mockResolvedValueOnce({ data: [{ id: 1, name: 'Ali', email: 'ali@example.com' }] });\n  render(<CustomerList \/>);\n  await waitFor(() => screen.getByText(\/Ali - ali@example.com\/i));\n  expect(screen.getByText(\/M\u00fc\u015fteri Listesi\/i)).toBeInTheDocument();\n});<\/code><\/pre>\n<p>Testleri \u00e7al\u0131\u015ft\u0131rmak i\u00e7in: <code>npm test<\/code><\/p>\n<h4>6.3. G\u00fcvenlik \u00d6nlemleri<\/h4>\n<p>*   <strong>HTTPS:<\/strong> \u00dcretim ortam\u0131nda her zaman HTTPS kullan\u0131n. Let&#8217;s Encrypt gibi hizmetlerle \u00fccretsiz SSL sertifikalar\u0131 alabilirsiniz.<br \/>\n*   <strong>CSRF (Cross-Site Request Forgery):<\/strong> Django REST Framework, varsay\u0131lan olarak CSRF korumas\u0131 sa\u011flar. React uygulaman\u0131zdan POST\/PUT\/DELETE istekleri yaparken CSRF token&#8217;\u0131n\u0131 g\u00f6ndermek isteyebilirsiniz (e\u011fer Session Authentication kullan\u0131yorsan\u0131z). Token Authentication kullan\u0131l\u0131yorsa, bu genellikle bir sorun de\u011fildir.<br \/>\n*   <strong>XSS (Cross-Site Scripting):<\/strong> React, varsay\u0131lan olarak veriyi sanitize ederek XSS sald\u0131r\u0131lar\u0131na kar\u015f\u0131 koruma sa\u011flar. Ancak, kullan\u0131c\u0131dan al\u0131nan veriyi direkt olarak <code>dangerouslySetInnerHTML<\/code> gibi \u00f6zelliklerle kullanmaktan ka\u00e7\u0131n\u0131n.<br \/>\n*   <strong>SQL Injection:<\/strong> Django ORM, parametreli sorgular kullanarak SQL Injection sald\u0131r\u0131lar\u0131na kar\u015f\u0131 koruma sa\u011flar. Ham SQL sorgular\u0131 yazmaktan ka\u00e7\u0131n\u0131n.<br \/>\n*   <strong>API Anahtarlar\u0131 ve Hassas Veriler:<\/strong> API anahtarlar\u0131, veritaban\u0131 \u015fifreleri gibi hassas bilgileri do\u011frudan kod i\u00e7ine yazmaktan ka\u00e7\u0131n\u0131n. Bunlar\u0131 ortam de\u011fi\u015fkenleri veya g\u00fcvenli yap\u0131land\u0131rma y\u00f6netimi ara\u00e7lar\u0131 arac\u0131l\u0131\u011f\u0131yla y\u00f6netin.<br \/>\n*   <strong>Yetkilendirme:<\/strong> API endpoint&#8217;lerinize kimlerin eri\u015febilece\u011fini s\u0131k\u0131 bir \u015fekilde kontrol edin. Django REST Framework&#8217;\u00fcn izin s\u0131n\u0131flar\u0131n\u0131 (permissions) etkili bir \u015fekilde kullan\u0131n.<\/p>\n<h3>7. Sonu\u00e7 ve Gelecek Ad\u0131mlar<\/h3>\n<p>Bu makalede, Ubuntu 18.04 \u00fczerinde Django ve React kullanarak temel bir m\u00fc\u015fteri y\u00f6netim sistemi i\u00e7in modern bir web uygulamas\u0131 geli\u015ftirmeyi ad\u0131m ad\u0131m inceledik. Backend i\u00e7in Django REST Framework ile g\u00fc\u00e7l\u00fc bir API olu\u015fturduk, frontend i\u00e7in React ile dinamik ve etkile\u015fimli bir kullan\u0131c\u0131 aray\u00fcz\u00fc tasarlad\u0131k ve bu iki katman\u0131 birbirine entegre etmenin yollar\u0131n\u0131 ele ald\u0131k. Ayr\u0131ca, geli\u015ftirme ve \u00fcretim ortamlar\u0131ndaki da\u011f\u0131t\u0131m yakla\u015f\u0131mlar\u0131na ve uygulaman\u0131n g\u00fcvenli\u011fine de\u011findik.<\/p>\n<p>Bu proje, modern web geli\u015ftirme paradigmas\u0131n\u0131n temelini olu\u015fturmaktad\u0131r. Buradan hareketle uygulaman\u0131z\u0131 daha da geli\u015ftirebilirsiniz:<\/p>\n<p>*   <strong>Daha Fazla \u00d6zellik:<\/strong> M\u00fc\u015fteri arama, filtreleme, raporlama, m\u00fc\u015fteri gruplar\u0131, notlar veya etkile\u015fim ge\u00e7mi\u015fi gibi \u00f6zellikler ekleyebilirsiniz.<br \/>\n*   <strong>Kullan\u0131c\u0131 Y\u00f6netimi ve Rolleri:<\/strong> Farkl\u0131 kullan\u0131c\u0131 rolleri (y\u00f6netici, sat\u0131\u015f temsilcisi) ve bunlar\u0131n farkl\u0131 verilere eri\u015fim yetkileri tan\u0131mlayabilirsiniz.<br \/>\n*   <strong>Geli\u015fmi\u015f Durum Y\u00f6netimi:<\/strong> Uygulaman\u0131z b\u00fcy\u00fcd\u00fck\u00e7e Redux, Zustand veya Recoil gibi daha geli\u015fmi\u015f durum y\u00f6netimi k\u00fct\u00fcphanelerini React taraf\u0131nda kullanmay\u0131 d\u00fc\u015f\u00fcnebilirsiniz.<br \/>\n*   <strong>Dockerizasyon:<\/strong> Uygulaman\u0131z\u0131 Docker konteynerlerine alarak geli\u015ftirme, test ve da\u011f\u0131t\u0131m s\u00fcre\u00e7lerini standartla\u015ft\u0131rabilir ve kolayla\u015ft\u0131rabilirsiniz.<br \/>\n*   <strong>CI\/CD (S\u00fcrekli Entegrasyon\/S\u00fcrekli Teslimat):<\/strong> Git tabanl\u0131 bir CI\/CD hatt\u0131 kurarak kod de\u011fi\u015fikliklerinin otomatik olarak test edilmesini ve da\u011f\u0131t\u0131lmas\u0131n\u0131 sa\u011flayabilirsiniz.<br \/>\n*   <strong>Bulut Da\u011f\u0131t\u0131m\u0131:<\/strong> Uygulaman\u0131z\u0131 AWS, Google Cloud, Azure veya DigitalOcean gibi bulut sa\u011flay\u0131c\u0131lar\u0131na da\u011f\u0131tarak \u00f6l\u00e7eklenebilirlik ve y\u00fcksek eri\u015filebilirlik sa\u011flayabilirsiniz.<br \/>\n*   <strong>Test Kapsam\u0131:<\/strong> Uygulaman\u0131z\u0131n kritik k\u0131s\u0131mlar\u0131 i\u00e7in daha kapsaml\u0131 birim, entegrasyon ve u\u00e7tan uca (end-to-end) testler yazarak yaz\u0131l\u0131m kalitesini art\u0131r\u0131n.<\/p>\n<p>Django ve React&#8217;\u0131n g\u00fcc\u00fcn\u00fc birle\u015ftirerek, hem performansl\u0131 hem de bak\u0131m\u0131 kolay, modern ve \u00f6l\u00e7eklenebilir web uygulamalar\u0131 geli\u015ftirebilirsiniz. Bu makale, bu heyecan verici yolculuk i\u00e7in sa\u011flam bir temel sunmaktad\u0131r.<\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Django ve React ile M\u00fc\u015fteri Bilgilerini Y\u00f6neten Modern Bir Web Uygulamas\u0131 Nas\u0131l Geli\u015ftirilir? (Ubuntu 18.04 \u00dczerinde)\nModern web uygulamalar\u0131","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":[1468],"tags":[],"class_list":{"0":"post-33840","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-ubuntu","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>Django ve React ile M\u00fc\u015fteri Bilgilerini Y\u00f6neten Modern Bir Web Uygulamas\u0131 Nas\u0131l Geli\u015ftirilir? (Ubuntu 18.04 \u00dczerinde) - 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\/django-ve-react-ile-musteri-bilgilerini-yoneten-modern-bir-web-uygulamasi-nasil-gelistirilir-ubuntu-18-04-uzerinde\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Django ve React ile M\u00fc\u015fteri Bilgilerini Y\u00f6neten Modern Bir Web Uygulamas\u0131 Nas\u0131l Geli\u015ftirilir? (Ubuntu 18.04 \u00dczerinde)\" \/>\n<meta property=\"og:description\" content=\"Django ve React ile M\u00fc\u015fteri Bilgilerini Y\u00f6neten Modern Bir Web Uygulamas\u0131 Nas\u0131l Geli\u015ftirilir? (Ubuntu 18.04 \u00dczerinde) Modern web uygulamalar\u0131\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/django-ve-react-ile-musteri-bilgilerini-yoneten-modern-bir-web-uygulamasi-nasil-gelistirilir-ubuntu-18-04-uzerinde\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-11-07T17:40:56+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=\"18 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/django-ve-react-ile-musteri-bilgilerini-yoneten-modern-bir-web-uygulamasi-nasil-gelistirilir-ubuntu-18-04-uzerinde\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/django-ve-react-ile-musteri-bilgilerini-yoneten-modern-bir-web-uygulamasi-nasil-gelistirilir-ubuntu-18-04-uzerinde\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Django ve React ile M\u00fc\u015fteri Bilgilerini Y\u00f6neten Modern Bir Web Uygulamas\u0131 Nas\u0131l Geli\u015ftirilir? (Ubuntu 18.04 \u00dczerinde)\",\"datePublished\":\"2025-11-07T17:40:56+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/django-ve-react-ile-musteri-bilgilerini-yoneten-modern-bir-web-uygulamasi-nasil-gelistirilir-ubuntu-18-04-uzerinde\/\"},\"wordCount\":2365,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"articleSection\":[\"Ubuntu\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/django-ve-react-ile-musteri-bilgilerini-yoneten-modern-bir-web-uygulamasi-nasil-gelistirilir-ubuntu-18-04-uzerinde\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/django-ve-react-ile-musteri-bilgilerini-yoneten-modern-bir-web-uygulamasi-nasil-gelistirilir-ubuntu-18-04-uzerinde\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/django-ve-react-ile-musteri-bilgilerini-yoneten-modern-bir-web-uygulamasi-nasil-gelistirilir-ubuntu-18-04-uzerinde\/\",\"name\":\"Django ve React ile M\u00fc\u015fteri Bilgilerini Y\u00f6neten Modern Bir Web Uygulamas\u0131 Nas\u0131l Geli\u015ftirilir? (Ubuntu 18.04 \u00dczerinde) - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-11-07T17:40:56+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/django-ve-react-ile-musteri-bilgilerini-yoneten-modern-bir-web-uygulamasi-nasil-gelistirilir-ubuntu-18-04-uzerinde\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/django-ve-react-ile-musteri-bilgilerini-yoneten-modern-bir-web-uygulamasi-nasil-gelistirilir-ubuntu-18-04-uzerinde\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/django-ve-react-ile-musteri-bilgilerini-yoneten-modern-bir-web-uygulamasi-nasil-gelistirilir-ubuntu-18-04-uzerinde\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Django ve React ile M\u00fc\u015fteri Bilgilerini Y\u00f6neten Modern Bir Web Uygulamas\u0131 Nas\u0131l Geli\u015ftirilir? (Ubuntu 18.04 \u00dczerinde)\"}]},{\"@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":"Django ve React ile M\u00fc\u015fteri Bilgilerini Y\u00f6neten Modern Bir Web Uygulamas\u0131 Nas\u0131l Geli\u015ftirilir? (Ubuntu 18.04 \u00dczerinde) - 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\/django-ve-react-ile-musteri-bilgilerini-yoneten-modern-bir-web-uygulamasi-nasil-gelistirilir-ubuntu-18-04-uzerinde\/","og_locale":"tr_TR","og_type":"article","og_title":"Django ve React ile M\u00fc\u015fteri Bilgilerini Y\u00f6neten Modern Bir Web Uygulamas\u0131 Nas\u0131l Geli\u015ftirilir? (Ubuntu 18.04 \u00dczerinde)","og_description":"Django ve React ile M\u00fc\u015fteri Bilgilerini Y\u00f6neten Modern Bir Web Uygulamas\u0131 Nas\u0131l Geli\u015ftirilir? (Ubuntu 18.04 \u00dczerinde) Modern web uygulamalar\u0131","og_url":"https:\/\/fatihsoysal.com\/blog\/django-ve-react-ile-musteri-bilgilerini-yoneten-modern-bir-web-uygulamasi-nasil-gelistirilir-ubuntu-18-04-uzerinde\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-11-07T17:40:56+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"18 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/django-ve-react-ile-musteri-bilgilerini-yoneten-modern-bir-web-uygulamasi-nasil-gelistirilir-ubuntu-18-04-uzerinde\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/django-ve-react-ile-musteri-bilgilerini-yoneten-modern-bir-web-uygulamasi-nasil-gelistirilir-ubuntu-18-04-uzerinde\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Django ve React ile M\u00fc\u015fteri Bilgilerini Y\u00f6neten Modern Bir Web Uygulamas\u0131 Nas\u0131l Geli\u015ftirilir? (Ubuntu 18.04 \u00dczerinde)","datePublished":"2025-11-07T17:40:56+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/django-ve-react-ile-musteri-bilgilerini-yoneten-modern-bir-web-uygulamasi-nasil-gelistirilir-ubuntu-18-04-uzerinde\/"},"wordCount":2365,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"articleSection":["Ubuntu"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/django-ve-react-ile-musteri-bilgilerini-yoneten-modern-bir-web-uygulamasi-nasil-gelistirilir-ubuntu-18-04-uzerinde\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/django-ve-react-ile-musteri-bilgilerini-yoneten-modern-bir-web-uygulamasi-nasil-gelistirilir-ubuntu-18-04-uzerinde\/","url":"https:\/\/fatihsoysal.com\/blog\/django-ve-react-ile-musteri-bilgilerini-yoneten-modern-bir-web-uygulamasi-nasil-gelistirilir-ubuntu-18-04-uzerinde\/","name":"Django ve React ile M\u00fc\u015fteri Bilgilerini Y\u00f6neten Modern Bir Web Uygulamas\u0131 Nas\u0131l Geli\u015ftirilir? (Ubuntu 18.04 \u00dczerinde) - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-11-07T17:40:56+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/django-ve-react-ile-musteri-bilgilerini-yoneten-modern-bir-web-uygulamasi-nasil-gelistirilir-ubuntu-18-04-uzerinde\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/django-ve-react-ile-musteri-bilgilerini-yoneten-modern-bir-web-uygulamasi-nasil-gelistirilir-ubuntu-18-04-uzerinde\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/django-ve-react-ile-musteri-bilgilerini-yoneten-modern-bir-web-uygulamasi-nasil-gelistirilir-ubuntu-18-04-uzerinde\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Django ve React ile M\u00fc\u015fteri Bilgilerini Y\u00f6neten Modern Bir Web Uygulamas\u0131 Nas\u0131l Geli\u015ftirilir? (Ubuntu 18.04 \u00dczerinde)"}]},{"@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\/33840","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=33840"}],"version-history":[{"count":1,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/33840\/revisions"}],"predecessor-version":[{"id":33841,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/33840\/revisions\/33841"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=33840"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=33840"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=33840"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}