Stok Kayıt & Takip REST API Uygulaması
Gereksinimler
virtualenv
- Minimum
python3.5
Django==2.2.2
&djangorestframework==3.11.0
Geliştirmede Kullanılan Araçlar
- Linux Mint işletim sistemi
- Visual Studio Code editörü
- Django'nun varsayılan olarak kullandığı
SQLite
veritabanı
Başlangıç
- Terminalden
virtualenv -p python3 env
diyerekenv
adında sanal bir ortam oluşturalım. source env/bin/activate
diyerek sanal ortama geçiş yapalım. Sanal ortama geçiş yaptığınızda terminaldeki bilgisayar adınızın önünde(env)<kullanıcı adınız>
gibi bir görüntü oluşacak. Bu durum sanal ortama geçiş yaptınız demektir.deactivate
diyerek sanal ortamdan çıkabilirsiniz.- Terminalden
pip install Django==2.2.2 djangorestframework==3.11.0
diyerek kurulumları gerçekleştirelim. - Kurulumlar başarıyla sonuçlandıysa projeyi başlatalım.
django-admin startproject src
diyerek projeyi başlatalım.cd src/
diyerek proje içerisine girip proje klasör yapısını görüntülersek aşağıdaki gibi bir yapı görülecektir. xxxxxxxxxx
.
├── manage.py
└── src
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
- Projenin genel adını
src
yerinestoktakip
yapıyoruz.settings.py
dosyasının bulunduğusrc
klasörü bu halde kalabilir. settings.py
modülünü açıpINSTALLED_APPS
içerisinerest_framework
yazarak Django Rest Framework'u ekliyoruz. Aşağıdaki gibi ekleyebilirsiniz.xxxxxxxxxx
INSTALLED_APPS = [
...
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework'
]
- Terminalden stoktakip projesi içerisinde iken
python manage.py runserver 5000
diyereklocalhost
yani127.0.0.1
IP adresinde5000
portunda projeyi ayağa kaldırabilirsiniz.5000
yazmasanız varsayılan olarak8000
portunda çalıştırmış olursunuz. - Aşağıdaki gibi bir çıktı terminalde görülecektir.
xxxxxxxxxx
python manage.py runserver 5000
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
You have 17 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
January 15, 2020 - 17:48:46
Django version 2.2.2, using settings 'src.settings'
Starting development server at http://127.0.0.1:5000/
Quit the server with CONTROL-C.
- Kırmızı olarak
You have unapplied migrations...
uyarısı Django'nun varsayılan olarak kullandığıadmin, auth, contenttypes, sessions
application'lar içinmodel
sınıflarının veritabanına migrate edilmediği için gelen uyarıdır.. - CTRL + C diyerek uygulamayı durdurup
python manage.py migrate
diyerek varsayılan olarak gelen modelleri veritabanına migrate edebilirsiniz. Aşağıdaki gibi bir çıktı gelecektir. xxxxxxxxxx
python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying sessions.0001_initial... OK
python manage.py createsuperuser
diyerek yönetici için kullanıcı adı, email ve parola belirleyebilirsiniz.xxxxxxxxxx
python manage.py createsuperuser
Username (leave blank to use 'adnan'): adnan
Email address: adnan@kayace.com.tr
Password:
Password (again):
Superuser created successfully.
python manage.py runserver 5000
diyerek tekrar web uygulamasını çalıştırıp127.0.0.1:5000/admin
üzerinden yönetim paneline giriş yapabilirsiniz.
Model sınıfları
python manage.py startapp stok
diyerekstoktakip
projesi içerisinde yeni birapplication
oluşturalım. Proje yapısı aşağıdaki gibi olacaktır.xxxxxxxxxx
.
├── db.sqlite3
├── manage.py
├── src
│ ├── __init__.py
│ ├── __pycache__
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── stok
├── admin.py
├── apps.py
├── __init__.py
├── migrations
│ └── __init__.py
├── models.py
├── tests.py
└── views.py
4 directories, 13 files
src/settings.py
içerisindestok
app'i de ekleyelim.xxxxxxxxxx
INSALLED_APPS = [
...
'rest_framework',
# benim uygulamalarim
'stok'
]
stok/models.py
dosyasını açıp aşağıdaki gibi model sınıflarını oluşturalım.xxxxxxxxxx
class Currency(models.Model):
"""Parabirimlerini muhafaza etmek için model. Ör: USD, TL, EUR"""
code = models.CharField(max_length=10) # USD
name = models.CharField(max_length=100) # United States Dollar
is_active = models.BooleanField(default=False) #
is_base_currency = models.BooleanField(default=False)
def __str__(self):
return self.code
class Meta:
db_table = 't_currency' #veritabanında bu modelin tablo adı
class CurrencyRate(models.Model):
"""Parabirimleri arasındaki oranları muhafaza etmek için model."""
currency = models.ForeignKey(Currency,
related_name="currency_rate",
on_delete=models.SET_NULL,
blank=True, null=True)
base_currency = models.ForeignKey(Currency,
on_delete=models.CASCADE,
blank=True, null=True)
rate = models.DecimalField(max_digits=6, decimal_places=2)
created_date = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 't_currency_rate'
Currency
veCurrencyRate
modelleri isimlerinden de anlaşılacağı gibi parabirimleri için kullanılacak modellerdir.- Terminalde aşağıdaki komutları (
python manage.py makemigrations stok
vepython manage.py migrate
) vererek bu modelleri veritabanına işleyelim. xxxxxxxxxx
(env) adnan @ ce ~ python manage.py makemigrations stok
Migrations for 'stok':
stok/migrations/0001_initial.py
- Create model Currency
- Create model CurrencyRate
(env) adnan @ ce ~ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions, stok
Running migrations:
Applying stok.0001_initial... OK
- Stok birimleri (kilogram, litre vb.) için ve Tedarikçi için aşağıdaki modelleri de ekleyelim.
stok/models.py
xxxxxxxxxx
class BasicUnit(models.Model):
'''Kilogram, liter etc..'''
code = models.CharField(max_length=10)
name = models.CharField(max_length=100)
class Meta:
db_table = 't_basic_unit'
def __str__(self):
return self.code
class Supplier(models.Model):
"""Tedarikçi için model"""
name = models.CharField(max_length=60)
phone = models.CharField(max_length=60, blank=True)
email = models.CharField(max_length=60, blank=True)
address = models.TextField()
class Meta:
db_table = 't_supplier'
def __str__(self):
return self.name
python manage.py makemigrations stok
vepython manage.py migrate
komutlarını veriyoruz.- Ve son olarak Hammadde Stok için aşağıdaki modeli ekleyelim
stok/models.py
xxxxxxxxxx
class MaterialStock(models.Model):
"""Hammadde Stok için model"""
total_amount = models.DecimalField(max_digits=8, decimal_places=2)
is_active = models.BooleanField(default=False)
stock_name = models.CharField(max_length=140, blank=True, null=True)
unit_price = models.DecimalField(max_digits=8, decimal_places=2)
currency = models.ForeignKey(Currency,
on_delete=models.SET_NULL,
blank=True, null=True)
updated_date = models.DateTimeField(auto_now_add=True, blank=True)
created_date = models.DateTimeField(auto_now_add=True, blank=True)
basic_unit = models.ForeignKey(BasicUnit,
on_delete=models.SET_NULL,
blank=True, null=True)
supplier = models.ForeignKey(Supplier,
on_delete=models.SET_NULL,
blank=True, null=True)
class Meta:
db_table = 't_material_stock'
python manage.py makemigrations stok
vepython manage.py migrate
komutlarını veriyoruz.
Shell Ortamında İşlemler
- Terminalde
python manage.py shell
diyerek shell ortamına geçiş yapalım ve aşağıdaki işlemleri gerçekleştirerek bir kaç veri girişi yapalım. xxxxxxxxxx
(env) adnan @ ce ~ python manage.py shell
Python 3.8.0 (default, Oct 28 2019, 16:14:01)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from stok.models import *
>>> Currency.objects.create(code="USD", name="United States Dollar", is_active=True, is_base_currency=True)
<Currency: USD>
>>> Currency.objects.create(code="TL", name="Turkish Lira")
<Currency: TL>
>>> Currency.objects.create(code="EUR", name="European Union Currency")
<Currency: EUR>
>>>
- 3 adet parabirimini sistemimize ekledik. Devam edelim:
xxxxxxxxxx
>>> usd = Currency.objects.get(code="USD")
>>> usd
<Currency: USD>
>>> tl = Currency.objects.get(code="TL")
>>> eur = Currency.objects.get(code="EUR")
>>>
>>> CurrencyRate.objects.create(currency=tl, base_currency=usd, rate=5.88)
<CurrencyRate: CurrencyRate object (1)>
>>> CurrencyRate.objects.create(currency=eur, base_currency=usd, rate=0.98)
<CurrencyRate: CurrencyRate object (2)>
>>>
- Parabirimleri arasındaki oranları da ekledik.
- Birimleri de ekleyelim.
xxxxxxxxxx
>>> BasicUnit.objects.create(code="kg", name="Kilogram")
<BasicUnit: kg>
>>> BasicUnit.objects.create(code="lt", name="Liter")
<BasicUnit: lt>
>>>
- Her şeyi terminalden shell üzerinden eklemeyeceğiz tabii ki :) . Bunlar sadece ısınma turları...
REST API Başlangıç
- Şimdi
stok
uygulaması içerisineapi
adında bir klasör oluşturup içerisineurls.py
,routes.py
,serializers.py
adında modüller oluşturalım. Proje yapısı aşağıdaki gibi olacaktır. xxxxxxxxxx
(env) adnan @ ce ~ find -name "*.pyc" -delete # .pyc dosyalarını silmek için
(env) adnan @ ce ~ tree . # linux'ta tree programı ile dosyaları aşağıdaki gibi görebilirsiniz
.
├── db.sqlite3
├── manage.py
├── src
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── stok
├── admin.py
├── api
│ ├── routes.py
│ ├── serializers.py
│ └── urls.py
├── apps.py
├── __init__.py
├── migrations
│ ├── __init__.py
├── models.py
├── __pycache__
├── tests.py
└── views.py
- Daha sade bir görünüm için
.pyc
dosyaları silindi ve000___.py
ile başlayan migrations dosyaları yukarıdaki gösterimden kaldırıldı.
URLS
stoktakip/src/urls.py
modülünü aşağıdaki gibi düzenleyelimxxxxxxxxxx
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include("stok.api.urls")),
]
SERIALIZERS
- stok/api/serializers.py` modülünü açarak aşağıdaki kodları ekleyelim.
xxxxxxxxxx
from rest_framework import serializers
# internal
from stok.models import Supplier
class SupplierSerializer(serializers.ModelSerializer):
class Meta:
model = Supplier
fields = ('id','name','phone','email','address')
- Tedarikçi model sınıfının attribute'larını serialize edecek sınıfı yazmış olduk.
ROUTES (API VIEWS)
stok/api/routes.py
modülünü açarak aşağıdaki kodları ekleyelimxxxxxxxxxx
from rest_framework import generics
#internal
from stok.models import Supplier
from stok.api.serializers import SupplierSerializer
class SupplierList(generics.ListAPIView): # GET istekleri için
queryset = Supplier.objects.all()
serializer_class = SupplierSerializer
stok/api/urls.py
modülünü açarak aşağıdaki kodları ekleyelim.xxxxxxxxxx
from django.urls import path
# internal
from stok.api.routes import SupplierList
urlpatterns = [
path('suppliers/',
SupplierList.as_view(),
name='api-supplier-list'),
]
- Uygulamamız için
127.0.0.1:5000/api/suppliers/
adresine istek (request) yapan istemciler (clients) için tedarikçi listesini (SupplierList) cevap olarak dönen bir api resource yazmış olduk. - Projeyi
python manage.py runserver 5000
diyerek çalıştıralım vehttp://127.0.0.1:5000/api/suppliers/
adresine gidelim. Göreceğiniz durum: xxxxxxxxxx
Supplier List
Supplier List
GET /api/suppliers/
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
[]
- Herhangi bir tedarikçi kaydı olmadığı için boş dizi
[ ]
cevap olarak döndü. Shell ortamına geçiş yapıp veri ekleyebilirsiniz veyagenerics.ListAPIView
sınıfı yerinegenerics.ListCreateAPIView
sınıfını miras alabilir ve sınıfın adından da anlaşılacağı üzere hem listeleme hem de yeni data ekleme işlemi gerçekleştirebilirsiniz. Değişikliği uygulamak için tekrarroutes.py
modülünü açalım. xxxxxxxxxx
class SupplierList(generics.ListCreateAPIView): # GET ve POST istekleri için
queryset = Supplier.objects.all()
serializer_class = SupplierSerializer
- Django Rest Framework'un sunduğu web tabanlı arayüzü göreceksiniz. Input alanlarına veri girişi yaparak birkaç tedarikçi ekleyelim.
- POST request için dönen cevap.
xxxxxxxxxx
Supplier List
POST /api/suppliers/
HTTP 201 Created
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{
"id": 1,
"name": "Adnan",
"phone": "5554444446",
"email": "adnan@kayace.com",
"address": "Fatih, Istanbul, Türkiye"
}
- GET request için dönen cevap
xxxxxxxxxx
GET /api/suppliers/
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
[
{
"id": 1,
"name": "Adnan",
"phone": "5554444446",
"email": "adnan@kayace.com",
"address": "Fatih, Istanbul, Türkiye"
},
{
"id": 2,
"name": "Murat",
"phone": "5554444423",
"email": "murat@kayace.com",
"address": "Dulkadiroğlu, Kahramanmaraş, Türkiye"
}
]
- Şimdi hammadde stok için serializers, routes ve urls modüllerinde eklemeler yapalım.
stok/api/serializers.py
xxxxxxxxxx
from rest_framework import serializers
# internal
from stok.models import Supplier, MaterialStock
class SupplierSerializer(serializers.ModelSerializer):
class Meta:
model = Supplier
fields = ('id','name','phone','email','address')
class StockSerialzer(serializers.ModelSerializer):
class Meta:
model = MaterialStock
fields = '__all__'
stok/api/routes.py
xxxxxxxxxx
from rest_framework import generics
#internal
from stok.models import Supplier, MaterialStock
from stok.api.serializers import (SupplierSerializer,
StockSerialzer)
class SupplierList(generics.ListCreateAPIView):
queryset = Supplier.objects.all()
serializer_class = SupplierSerializer
class StockList(generics.ListCreateAPIView):
queryset = MaterialStock.objects.all()
serializer_class = StockSerialzer
stok/api/urls.py
xxxxxxxxxx
from django.urls import path
# internal
from stok.api.routes import SupplierList, StockList
urlpatterns = [
path('suppliers/',
SupplierList.as_view(),
name='api-supplier-list'),
path('stocks/',
StockList.as_view(),
name='api-stock-list'),
]
- Şimdi
http://127.0.0.1:5000/api/stocks/
adresine gidelim ve Input alanlarına veri girişi yapıp select box'lardan daha önce shell ortamından girdiğimiz parabirimi (currency) , stok birimi (kg, litre vs.) ve tedarikçi seçimini yapalım. - POST request işlemi.
xxxxxxxxxx
Stock List
POST /api/stocks/
HTTP 201 Created
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{
"id": 1,
"total_amount": "1453.00",
"is_active": true,
"stock_name": "Buğday",
"unit_price": "3.54",
"updated_date": "2020-01-15T19:31:13.041079Z",
"created_date": "2020-01-15T19:31:13.041120Z",
"currency": 2,
"basic_unit": 1,
"supplier": 1
}
- GET request işlemi
xxxxxxxxxx
GET /api/stocks/
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
[
{
"id": 1,
"total_amount": "1453.00",
"is_active": true,
"stock_name": "Buğday",
"unit_price": "3.54",
"updated_date": "2020-01-15T19:31:13.041079Z",
"created_date": "2020-01-15T19:31:13.041120Z",
"currency": 2,
"basic_unit": 1,
"supplier": 1
},
{
"id": 2,
"total_amount": "1071.00",
"is_active": true,
"stock_name": "Kayısı",
"unit_price": "5.71",
"updated_date": "2020-01-15T19:35:28.709344Z",
"created_date": "2020-01-15T19:35:28.709381Z",
"currency": 1,
"basic_unit": 1,
"supplier": 2
}
]
"currency": 1, "basic_unit": 1, "supplier": 2
alanları ID'leri ile gelşmiş durumda. Bu alanlar için ID yerine görmek istediğiniz veriler için Rest Framework'un read_only class'larını kullanabilirsiniz. ÖrneğinStokSerializer
'ı aşağıdaki gibi değiştirin ve tekrar GET request yapın.xxxxxxxxxx
class StockSerialzer(serializers.ModelSerializer):
supplier_name = serializers.ReadOnlyField(source="supplier.name")
currency_code = serializers.ReadOnlyField(source="currency.code")
unit_code = serializers.ReadOnlyField(source="basic_unit.code")
class Meta:
model = MaterialStock
fields = '__all__'
- Cevap olarak aşağıdaki gibi bir sonuç alırız.
xxxxxxxxxx
GET /api/stocks/
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
[
{
"id": 1,
"supplier_name": "Adnan",
"currency_code": "TL",
"unit_code": "kg",
"total_amount": "1453.00",
"is_active": true,
"stock_name": "Buğday",
"unit_price": "3.54",
"updated_date": "2020-01-15T19:31:13.041079Z",
"created_date": "2020-01-15T19:31:13.041120Z",
"currency": 2,
"basic_unit": 1,
"supplier": 1
},
{
"id": 2,
"supplier_name": "Murat",
"currency_code": "USD",
"unit_code": "kg",
"total_amount": "1071.00",
"is_active": true,
"stock_name": "Kayısı",
"unit_price": "5.71",
"updated_date": "2020-01-15T19:35:28.709344Z",
"created_date": "2020-01-15T19:35:28.709381Z",
"currency": 1,
"basic_unit": 1,
"supplier": 2
}
]
- Başka bir çözüm olarak 2 adet serializer tanımlayıp representation (gösterim) yani GET request için farklı, kayıt ekleme yani POST request için farklı bir serializer tanımlayabilirsiniz. Bunu yaparsanız
routes.py
modülündeStockList
sınıfınaget_serializer_class
methodunu ekleyerek GET, POST, PUT, DELETE v.s. HTTP methodlarına göre hangi serializer sınıfın kullanılacağına karar verebilirsiniz. serializers.py
modülünü açıpStockCreateSerialzer
'ı ekleyip öncekiStockSerializer
sınıfını daStockListSerializer
olarak değiştirelimxxxxxxxxxx
class StockListSerialzer(serializers.ModelSerializer):
# ID olarak gösterilen alanlar override edilerek name ve code gösterimi yapıldı
supplier = serializers.ReadOnlyField(source="supplier.name")
currency = serializers.ReadOnlyField(source="currency.code")
basic_unit = serializers.ReadOnlyField(source="basic_unit.code")
class Meta:
model = MaterialStock
fields = '__all__'
class StockCreateSerialzer(serializers.ModelSerializer):
class Meta:
model = MaterialStock
fields = '__all__'
- Bu serializer sınıflarını
routes.py
modülünü açıp import ederekStockList
sınıfını aşağıdaki gibi düzenleyelim. xxxxxxxxxx
from stok.api.serializers import (SupplierSerializer,
StockListSerialzer,
StockCreateSerialzer,
)
class StockList(generics.ListCreateAPIView):
queryset = MaterialStock.objects.all()
def get_serializer_class(self):
if self.request.method == "POST":
return StockCreateSerialzer
return StockListSerialzer
- Görüldüğü üzere POST isteği gelirse
StockCreateSerializer
diğer durumlardaStockListSerializer
gelen json datasını serialize edecektir. Değişiklik yaptıktan sonra GET isteğinihttp://127.0.0.1:5000/api/stocks/
adresine yaparsanız aşağıdaki cevap döner. xxxxxxxxxx
GET /api/stocks/
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
[
{
"id": 1,
"supplier": "Adnan",
"currency": "TL",
"basic_unit": "kg",
"total_amount": "1453.00",
"is_active": true,
"stock_name": "Buğday",
"unit_price": "3.54",
"updated_date": "2020-01-15T19:31:13.041079Z",
"created_date": "2020-01-15T19:31:13.041120Z"
},
{
"id": 2,
"supplier": "Murat",
"currency": "USD",
"basic_unit": "kg",
"total_amount": "1071.00",
"is_active": true,
"stock_name": "Kayısı",
"unit_price": "5.71",
"updated_date": "2020-01-15T19:35:28.709344Z",
"created_date": "2020-01-15T19:35:28.709381Z"
}
]
- Django Rest Framework'un sunduğu arayüzde POST işlemini yapabilirsiniz.
xxxxxxxxxx
POST /api/stocks/
HTTP 201 Created
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{
"id": 3,
"total_amount": "1299.00",
"is_active": true,
"stock_name": "Süt",
"unit_price": "1.00",
"updated_date": "2020-01-19T09:44:09.464303Z",
"created_date": "2020-01-19T09:44:09.464348Z",
"currency": 2,
"basic_unit": 2,
"supplier": 1
}
- Tekrar GET isteği yaparak önceden yaptığımız stok listesini görebilirsiniz.
xxxxxxxxxx
GET /api/stocks/
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
[
{
"id": 1,
"supplier": "Adnan",
"currency": "TL",
"basic_unit": "kg",
"total_amount": "1453.00",
"is_active": true,
"stock_name": "Buğday",
"unit_price": "3.54",
"updated_date": "2020-01-15T19:31:13.041079Z",
"created_date": "2020-01-15T19:31:13.041120Z"
},
{
"id": 2,
"supplier": "Murat",
"currency": "USD",
"basic_unit": "kg",
"total_amount": "1071.00",
"is_active": true,
"stock_name": "Kayısı",
"unit_price": "5.71",
"updated_date": "2020-01-15T19:35:28.709344Z",
"created_date": "2020-01-15T19:35:28.709381Z"
},
{
"id": 3,
"supplier": "Adnan",
"currency": "TL",
"basic_unit": "lt",
"total_amount": "1299.00",
"is_active": true,
"stock_name": "Süt",
"unit_price": "1.00",
"updated_date": "2020-01-19T09:44:09.464303Z",
"created_date": "2020-01-19T09:44:09.464348Z"
}
]
- Şimdi
routes.py
modülüneStockDetail
sınıfını ekleyelim ve herhangi bir stok detayını görmek için eklemeler yapalım. xxxxxxxxxx
class StockDetail(generics.RetrieveAPIView):
queryset = MaterialStock.objects.all()
def get_serializer_class(self):
return StockListSerialzer
api/urls.py
içerisine StockDetail'i import ederek aşağıdaki path'i ekleyelim'xxxxxxxxxx
from stok.api.routes import (SupplierList,
StockList,
StockDetail)
path('stocks/<int:pk>',
StockDetail.as_view(),
name='api-stock-detail'),
http://127.0.0.1:5000/api/stocks/2
adresine GET isteği yaparsanız ID'si 2 olan stok detayını görürsünüz. Buradaserializers.py
modülündeStockListSerializer
sınıfına bir alan ekleyip direkt detay linkini edinmek için aşağıdaki düzenlemeyi yapalım.xxxxxxxxxx
class StockListSerialzer(serializers.ModelSerializer):
# ID olarak gösterilen alanlar override edilerek name ve code gösterimi yapıldı
supplier = serializers.ReadOnlyField(source="supplier.name")
currency = serializers.ReadOnlyField(source="currency.code")
basic_unit = serializers.ReadOnlyField(source="basic_unit.code")
url = serializers.HyperlinkedIdentityField(view_name='api-stock-detail',
lookup_field='pk')
class Meta:
model = MaterialStock
fields = '__all__'
- HyperlinkedIdentityField , 2 adet parametre almış durumda. view_name
urls.py
modülünde tanımladığımızStockDetail
için yazılan path(('stocks/<int:pk>'
,StockDetail.as_view()
,name='api-stock-detail'
) view name'dir.lookup_field='pk'
ise primary key yani ID baz alınarak detay sayfasına erişileceğini belirtir. http://127.0.0.1:5000/api/stocks/
adresine GET request yaparsanız aşağıdaki gibiurl
alanı da eklenmiş şekilde liste dönecektir.xxxxxxxxxx
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
[
{
"id": 1,
"supplier": "Adnan",
"currency": "TL",
"basic_unit": "kg",
"url": "http://127.0.0.1:5000/api/stocks/1",
"total_amount": "1453.00",
"is_active": true,
"stock_name": "Buğday",
"unit_price": "3.54",
"updated_date": "2020-01-15T19:31:13.041079Z",
"created_date": "2020-01-15T19:31:13.041120Z"
},
...
....
]
- Güncelleme işlemine geçebilmek için
routes.py
modülünü açıp StockDetail 'in miras aldığıRetrieveAPIView
yerineRetrieveUpdateAPIView
değişikliğini uygulayalım. xxxxxxxxxx
class StockDetail(generics.RetrieveUpdateAPIView):
queryset = MaterialStock.objects.all()
def get_serializer_class(self):
return StockListSerialzer
- Şimdi herhangi bir stok detayı için güncelleme işlemi yapalım.
http://127.0.0.1:5000/api/stocks/2
adresine giderek 2 numaralı stok için güncelleme işlemi yapalım. Güncelleme öncesi: xxxxxxxxxx
{
"id": 2,
"supplier": "Murat",
"currency": "USD",
"basic_unit": "kg",
"url": "http://127.0.0.1:5000/api/stocks/2",
"total_amount": "1071.00",
"is_active": true,
"stock_name": "Kayısı",
"unit_price": "5.71",
"updated_date": "2020-01-15T19:35:28.709344Z",
"created_date": "2020-01-15T19:35:28.709381Z"
}
- Django Rest Framework web arayüzü güncelleme yapacağımız alanları input alanlarına yerleştirmiş olacak. Değişiklik Yapıp PUT butonuna basarak güncelleme yapalım.
xxxxxxxxxx
PUT /api/stocks/2
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{
"id": 2,
"supplier": "Murat",
"currency": "USD",
"basic_unit": "kg",
"url": "http://127.0.0.1:5000/api/stocks/2",
"total_amount": "7071.00",
"is_active": true,
"stock_name": "Elma",
"unit_price": "4.44",
"updated_date": "2020-01-15T19:35:28.709344Z",
"created_date": "2020-01-15T19:35:28.709381Z"
}
- Toplam miktar, stok adı, birim fiyat güncellendi.
- Peki diğer alanları da güncellemek istersek ?..
StockList
sınıfı için yaptığımızı burada da yapabiliriz. Detay gösterimi için farklı serializer, güncelleme için farklı serializer kullanabiliriz.routes.py
'da StockDetail sınıfını aşağıdaki gibi değiştirelim. xxxxxxxxxx
class StockDetail(generics.RetrieveUpdateAPIView):
queryset = MaterialStock.objects.all()
def get_serializer_class(self):
if self.request.method == "PUT":
return StockCreateSerialzer
return StockListSerialzer
http://127.0.0.1:5000/api/stocks/2
adresine giderseniz şimdi, currency, basic_unit, supplier alanlarının da seçilip güncellenebileceğini görürsünüz. PUT request yapalım.xxxxxxxxxx
PUT /api/stocks/2
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{
"id": 2,
"total_amount": "7071.00",
"is_active": true,
"stock_name": "Elma Suyu",
"unit_price": "4.44",
"updated_date": "2020-01-15T19:35:28.709344Z",
"created_date": "2020-01-15T19:35:28.709381Z",
"currency": 2,
"basic_unit": 2,
"supplier": 1
}
- Elma -> Elma Suyu olarak, Tedarikçi Murat -> Adnan olarak, currency USD -> TL olarak, basic_unit kg -> lt olarak güncellendi. GET request;
xxxxxxxxxx
GET /api/stocks/2
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{
"id": 2,
"supplier": "Adnan",
"currency": "TL",
"basic_unit": "lt",
"url": "http://127.0.0.1:5000/api/stocks/2",
"total_amount": "7071.00",
"is_active": true,
"stock_name": "Elma Suyu",
"unit_price": "4.44",
"updated_date": "2020-01-15T19:35:28.709344Z",
"created_date": "2020-01-15T19:35:28.709381Z"
}
Yazar : Adnan KAYA
Github : https://github.com/adnankaya
Blog : https://adnankayace.blogspot.com/
Daha Fazlası için : https://www.django-rest-framework.org/
Yorumlar