Two Scoops of Django 3.x by Daniel Audrey Feldroy (075-150) .En - TR

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 76

Translated from English to Turkish - www.onlinedoctranslator.

com

4.5: Alternatif: Ruby on Rails Tarzı Yaklaşımlar

davranışlar.py başına model karışımlarını bulmak için bir seçenek Bölüm 6.7.1: Model Davranışlar
aka Mixins.
sabitler.py Uygulama düzeyinde ayarların yerleştirilmesi için iyi bir ad. Onlardan yeterince varsa
Bir uygulamaya dahil olmak, onları kendi modüllerine ayırmak bir projeye netlik
katabilir.
dekoratörler.py Dekoratörlerimizi bulmayı sevdiğimiz yer. Dekoratörler hakkında daha fazla bilgi için,

görmek Bölüm 9.3: Dekoratörler Tatlıdır.


db/ Herhangi bir özel model alanı veya bileşeni için birçok projede kullanılan bir paket.
alanlar.py genellikle form alanları için kullanılır, ancak bazen model alanları için kullanılır.
oluşturmayı haklı çıkarmak için yeterli alan kodu yok db/ paket.
fabrikalar.py Test verisi fabrikalarımızı yerleştirmeyi sevdiğimiz yer. Kısaca açıklanansec-
24.3.5: Fikstürlere Güvenmeyin
helpers.py Yardımcı işlevler dediğimiz şey. Bunlar, çıkarılan kodu koyduğumuz yer
Görüntüleme (Bölüm 8.5: İş Mantığını Görüşlerden Uzak Tutmaya Çalışmak) ve modeller (Bölüm
6.7: Yağ Modellerini Anlamak) daha hafif hale getirmek için. ile eşanlamlıutils.pyyöneticiler.py
Ne zaman modeller.py çok büyürse, yaygın bir çözüm, herhangi bir geleneği taşımaktır.
model yöneticileri bu modüle.
şema.py Burası kodun arkasındaki yer GraphQL API'ler genellikle yerleştirilir.sinyaller.py
Özel sinyaller sağlamaya karşı çıkarken (bkz. ??: ??), bu yararlı olabilir
onları koyacak yer.utils.py ile
eşanlamlı helpers.py
viewmixins.py Görünüm modülleri ve paketleri, herhangi bir görünüm karışımını aşağıdakilere taşıyarak inceltilebilir:

bu modül. GörmekBölüm 10.2: Karışımların CBV'lerle Kullanılması.

Bu bölümde listelenen tüm modüller için odak noktaları global araçlar değil 'uygulama düzeyinde' olmalıdır.

Global düzeydeki modüller şurada açıklanmıştır:Bölüm 31.1: Yardımcı Programlarınız için Bir Çekirdek

Uygulama Oluşturun.

4.5 Alternatif: Ruby on Rails Tarzı Yaklaşımlar


Bazı insanlar daha fazlasını kullanarak başarıyı yakaladı raylar üzerinde yakut-stil yaklaşımları. Ruby
on Rails veyaRaylar kısacası, yaklaşık olarak Django ile aynı yaşta olan başarılı bir Ruby destekli
uygulama çerçevesidir. Kayda değer Rails projeleri arasında GitHub, GitLab, Coinbase, Stripe ve Square
bulunur. Django ve Rails ile Python ve Ruby arasında yaklaşımlarını incelemeye değer kılmak için
yeterince benzerlik var.

4.5.1 Hizmet Katmanları

Django'da kod yazarken, yeni başlayanların iş mantığının nereye gitmesi gerektiğini belirlemede
zorlanmaları yaygındır. Klasik örnek, birden çok model ve uygulamada kullanıcı nesneleri ve ilgili veriler
oluşturma sürecidir. Bizim durumumuzda Icecreamlandia temasına girmek için bir bilet

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 37


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 4: Django Uygulama Tasarımının Temelleri

park:

1 Sistem, adı verilen bir yönetici yönteminde bir kullanıcı kaydı oluşturur. create_user()

2 create_user() kullanıcının bir fotoğrafını bir dosya barındırma sistemine yüklerKullanıcı

3 oluştur() ayrıca arayarak bir bilet nesnesi oluşturur create_ticket() , adı verilen bir yönetici

yönteminde olan oluştur_bilet()

4 oluştur_bilet() üçüncü taraf bir hizmet olan konuk Icecreamlandia check-in uygulamasına
bir API çağrısı yapar

Bu eylemler için tipik yerleşim, Kullanıcı ve Bilet'e atanan yöneticiler üzerindeki yöntemlere yayılır.
Diğerleri bunun yerine sınıf yöntemlerini kullanmayı tercih eder. Böylece şunları görebiliriz:

Örnek 4.3: Tipik Django İş Mantığı Yerleştirmesi

sınıf Kullanıcı yönetici(BaseUserManager):


"""users/managers.py'de"""
tanım Kullanıcı oluştur(öz, e-posta=Hiçbiri, parola=Hiçbiri,

→ avatar_url=Hiçbiri):
kullanıcı = öz.model(
e-posta=e-posta,
aktif=NS, son giriş=saat dilimi.şimdi(),
kayıtlı_at=saat dilimi.şimdi(), avatar_url=
avatar_url

)
resize_avatar(avatar_url) Bilet.nesneler.
create_ticket(kullanıcı)dönüş kullanıcı

sınıf Bilet Yöneticisi(modeller.yönetici):


"""Görevler/managers.py'de"""
tanım create_ticket(öz, kullanıcı: Kullanıcı):
bilet = öz.model(kullanıcı=kullanıcı)
send_ticket_to_guest_checkin(bilet)dönüş bilet

Bu işe yararken, hizmet katmanı yaklaşımı, kullanıcı nesnesi ve biletler arasında endişelerin
ayrılması gerektiğini savunuyor. Spesifik olarak, Bilet kodunu çağırmak için Kullanıcı koduna
gömme mantığı, iki etki alanını sıkı bir şekilde birleştirir. Böylece endişeleri ayrı tutmak için yeni
bir katman eklenir ve buna hizmet katmanı denir. Bu mimari için kod yerleştirilirservis.py ve
seçiciler.py.

38 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


4.5: Alternatif: Ruby on Rails Tarzı Yaklaşımlar

Örnek 4.4: Hizmet Katmanları

# Servis katmanı örneği kepçe/

├── api/
├── modeller.py
├── services.py # İş mantığı için hizmet katmanı konumu
├── seçiciler.py # Sorgular için hizmet katmanı konumu
├── testler/

Hizmet katmanı tasarımı altında, yukarıdaki kod şu şekilde yürütülür:

Örnek 4.5: Hizmet Katmanı İş Mantığı Yerleştirme

# users/services.py'de
itibaren .modeller içe aktarmak kullanıcı

itibaren biletler.modeller içe aktarmak Bilet, send_ticket_to_guest_checkin

tanım Kullanıcı oluştur(e-posta: cadde, parola: cadde, avatar_url: cadde) ->



→ kullanıcı:

kullanıcı = kullanıcı(

e-posta=e-posta,
parola=parola,
avatar_url=avatar_url
)
kullanıcı.full_clean()
kullanıcı.yeniden boyutlandır_avatar()

kullanıcı.kaydetmek()

bilet = Bilet(kullanıcı=kullanıcı)
send_ticket_to_guest_checkin(bilet)dönüş
kullanıcı

Bu teknik için popüler bir açıklama şu adreste bulunabilir: github.com/HackSoftware/


Django-Styleguide#hizmetler

Bu yaklaşımın avantajları:

a Bu basit örnekte, 17 satıra karşılık 12 satır kod


a Gevşek bağlantı, kullanıcı veya biletleme kodunun daha kolay değiştirilebileceği anlamına gelir

a Endişelerin ayrılması, bireysel bileşenlerin işlevsel testlerinin yapılmasını kolaylaştırır

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 39


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 4: Django Uygulama Tasarımının Temelleri

a Bu yaklaşımla, döndürülen nesnelerin tür açıklamalarını eklemek, tipik olandan daha kolaydır.
Django

Bu yaklaşımın dezavantajları:

a Projelerin tüm modülleri tamamen yeniden yazmadan değiştirmesi çok nadir


a Küçük projeler için genellikle gereksiz karmaşıklık ekler
a Karmaşık projeler için hizmet katmanı genellikle binlerce kod satırına kadar büyür,
onu desteklemek için yeni mimarinin gelişimini zorlamak
a Kullanımı seçiciler.py her yerde basit bir ORM sorgusu her zaman fazladan bir adımı zorlar
yapılabilirdi
a Django kalıcılığı, modelin kendisine yerleştirilen içe aktarılabilir iş mantığına dayanır.
Hizmet katmanları, bazı gelişmiş teknikleri kaldırarak bu yeteneği ortadan kaldırır.

Hizmet katmanlarının daha fazla reddi veya geleneksel Django araçlarında iş mantığının nasıl organize

edileceğine ilişkin açıklamalar, uzun süredir Django sürdürücüsü James Bennett'in blogunda ve Django REST

Framework'ün kurucusu Tom Christie'nin bir makalesinde okunabilir:

a b-list.org/weblog/2020/mar/16/no-service/ b-list.org/weblog/2020/
a mar/23/still-no-service/ dabapps.com/blog/django-models-and-
a kapsülleme/

Two Scoops of Django'nun yazarları için hizmet katmanlarının kullanımı yeni değil - bunu
yıllardır görüyoruz. Temel Django uygulamalarından ayrılan herhangi bir teknikte olduğu gibi,
anekdotsal deneyimimiz, projelerin hizmet katmanlarını kullanarak biraz daha sık başarısız
olduğunu gördük. Bu, yaklaşımın değeri olmadığı anlamına gelmez, ancak ek soyutlama çabaya
değmeyebilir.

4.5.2 Büyük Tek Uygulama Projesi

Bir projenin tüm kodu tek bir uygulamaya koyduğu yer burasıdır. Küçük Django projeleri için yaygın
olsa da, daha büyük projeler genellikle bu modeli izlemez.

Bu yaklaşımın olumlu yönleri var. Özellikle, geçişler daha kolaydır ve tablo adları
basitleştirilmiş bir model izler.

Rails gibi diğer çerçevelerin bu tekniği benimsediği ve oldukça başarılı olduğu


söylenmelidir. Ancak, Rails ve diğer araçlar bu modeli takip edecek şekilde tasarlanırken,
Django bu tasarım için optimize edilmemiştir. Bu tekniği Django ile kullanmak, Django
belgelerinde nadiren açıklanan kalıplarla ilgili deneyim ve uzmanlık gerektirir.

40 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


4.6: Özet

Tipik olarak, her şey dev bir şekilde bir araya toplanır. modeller.py, görünümler.py,
testler.py, ve urls.pymodüller. Sonunda ya proje kendi artan karmaşıklığı altında çöker ya
da dosyalar, modellerin kapsadığı alanlara dayalı olarak alt modüllere bölünür.
icecreamlandia projemizi kullanarak, "Kullanıcılar" ile ilgili her şeymodeller/users.py ve
"Biletler" modeller/tickets.py.

Dikkatli bir öngörüyle yapılırsa bunun işe yarayabileceğini lütfen unutmayın. Gerçekten de, Audrey
bunu bir projeyle büyük bir başarıya imza attı, beklenenden biraz daha fazla kod hokkabazlığı
içeriyordu. Bu, yalnızca bir Djangonaut birkaç başarılı Django projesini tamamladıktan sonra
keşfedilmesi gereken bir tekniktir.

UYARI: TooDivergentDjangoArchitectures ile Dikkatli Olun

James Beith, saygı duyduğumuz kıdemli bir mühendis. Bir Django projesinin nasıl yapılandırılacağı

konusunda ilginç bir görüşü var. James, tasarımında Django için ortak kalıpları açıkça yeniden

yazıyor. Onun için çalışıyor gibi görünse de, projedeki herhangi bir yeni geliştiricinin yeni bir

paradigma öğrenmesi gerektiğinden, sürdürülmesi daha zor bir proje yapar. Django'nun cazibesi,

büyük ölçüde konfigürasyon üzerindeki konvansiyona dayanmaktadır ve tasarımı açıkça bunu

bozmaktadır. Yeni bir şeyler deneme arzusunu selamlarken, Django projelerini yeniden tasarlama

konusunda çok ileri gittiğini düşünüyoruz.

James Beith'in makalesi: jamesbeith.co.uk/blog/


nasıl yapılır-django-projeleri/

4.6 Özet
Bu bölüm, Django uygulama tasarımı sanatını ele aldı. Spesifik olarak, her Django uygulaması sıkı bir
şekilde kendi görevine odaklanmalı ve basit, hatırlaması kolay bir isme sahip olmalıdır. Bir uygulama
çok karmaşık görünüyorsa, daha küçük uygulamalara bölünmelidir. Uygulama tasarımını doğru
yapmak pratik ve çaba gerektirir, ancak bu çabaya değer.

Ayrıca mimari uygulamalara alternatif yaklaşımları ve bunların içinde mantığın nasıl çağrıldığını da ele aldık.

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 41


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 4: Django Uygulama Tasarımının Temelleri

42 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


5 | Ayarlar ve Gereksinimler Dosyaları

Django 3, çoğu varsayılan değerlerle gelen ayarlar modülünde kontrol edilebilen 150'den fazla
ayara sahiptir. Ayarlar, sunucunuz başlatıldığında yüklenir ve deneyimli Django geliştiricileri,
sunucunun yeniden başlatılmasını gerektirdiğinden, üretimde ayarları değiştirmeye çalışmaktan
uzak durur.

Şekil 5.1: Projeniz büyüdükçe Django ayarlarınız oldukça karmaşık hale gelebilir.

Takip etmeyi sevdiğimiz bazı en iyi uygulamalar:

a Tüm ayar dosyalarının sürüm kontrollü olması gerekir. Bu özellikle üretimde geçerlidir
tarih, saat ve ayar değişikliği açıklamalarının mutlaka takip edilmesi gereken
ortamlardır.
a Kendinizi Tekrar Etmeyin. yerine bir temel ayarlar dosyasından devralmalısınız.
bir dosyadan diğerine kesme ve yapıştırma.
a Gizli anahtarları güvende tutun. Versiyon kontrolünün dışında tutulmalıdırlar.

5.1 Sürümsüz Yerel Ayarlardan Kaçının


Sürümsüz olanı savunuyorduk local_settings anti-desen. Şimdi daha iyi biliyoruz.

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 43


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 5: Ayarlar ve Gereksinim Dosyaları

Geliştiriciler olarak, hazırlama veya üretim sunucuları devre dışı bırakılması (ve genellikle
yüklenmemesi) gereken hata ayıklama araçlarına ilişkin ayarlar gibi geliştirme için kendi gerekli
ayarlarımıza sahibiz.

Ayrıca, belirli ayarları genel veya özel kod havuzlarından uzak tutmak için genellikle iyi
nedenler vardır. NSGİZLİ ANAHTAR ayarı akla gelen ilk şeydir, ancak Amazon, Stripe ve diğer
parola türü değişkenler gibi hizmetlere yönelik API anahtarı ayarlarının korunması gerekir.

UYARI: Sırlarınızı Koruyun!


NS GİZLİ ANAHTAR ayar, Django'nun kriptografik imzalama işlevinde kullanılır ve sürüm kontrolünden

en iyi şekilde uzak tutulan benzersiz, öngörülemeyen bir ayara ayarlanması gerekir. Django'yu

bilinen bir programla çalıştırmaGİZLİ ANAHTAR Django'nun güvenlik korumalarının çoğunu yenerek

ciddi güvenlik açıklarına yol açabilir. Daha fazla ayrıntı için, okuyun

docs.djangoproject.com/en/3.2/topics/signing/.

için aynı uyarı GİZLİ ANAHTAR aynı zamanda üretim veritabanı parolaları, AWS anahtarları,
OAuth belirteçleri veya projenizin çalışması için ihtiyaç duyduğu diğer hassas veriler için de
geçerlidir.

Bu bölümün ilerleyen bölümlerinde, GİZLİ ANAHTAR "Ortam Ayarlarıyla Gizli


Anahtarları Dışarıda Tutun" bölümündeki sorun.

Ortak bir çözüm oluşturmaktır local_settings.py sunucu veya geliştirme makinesi başına yerel
olarak oluşturulan ve kasıtlı olarak sürüm kontrolünün dışında tutulan modüller. Geliştiriciler
artık, sürüm kontrolünde kod izlenmeden iş mantığının dahil edilmesi de dahil olmak üzere,
geliştirmeye özel ayar değişiklikleri yapıyor. Hazırlama ve dağıtım sunucuları, sürüm
kontrolünde izlenmeden konuma özgü ayarlara ve mantığa sahip olabilir.

Ne yanlış gidebilir ki?!?

Ah...

a Her makinenin izlenmeyen kodu vardır.


a Bir üretimi saatlerce kopyalayamadıktan sonra ne kadar saç çekeceksiniz?
yerel olarak hata veriyor, sorunun yalnızca üretim ortamında özel mantık olduğunu mu
keşfettiniz?
a Yerel olarak keşfettiğiniz, düzelttiğiniz ve düzelttiğiniz 'hata' herkesten ne kadar hızlı kaçacaksınız?

Üretime itilen şey aslında kendi yaptığınız özelleştirmelerden kaynaklandı.


local_settings.py modül ve şimdi siteyi kilitliyor mu?

44 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


5.2: Birden Fazla Ayar Dosyasını Kullanma

a Herkes aynı şeyi kopyalar/yapıştırır local_settings.py modül her yerde Bu bir viyo-
Kendini Tekrar Etme ama daha büyük ölçekte mi?

Farklı bir yaklaşım benimseyelim. Geliştirme, hazırlama, test ve üretim ayarlarını, sürüm
kontrolü tarafından izlenen bir ayar dosyasındaki ortak bir temel nesneden devralan ayrı
bileşenlere ayıralım. Ayrıca, bunu sunucu sırlarının gizli kalacağı şekilde yaptığımızdan
emin olacağız.

Okumaya devam edin ve nasıl yapıldığını görün!

5.2 Çoklu Ayar Dosyalarını Kullanma


İPUCU: Bu Kurulum Modelinin Tarihçesi

Burada açıklanan kurulum, Jacob Kaplan-Moss'un OSCON 2011'de Django'nun En


İyisi (ve En Kötüsü) konuşmasının “Tek Doğru Yolu”na dayanmaktadır. Bkz.
slideshare.net/jacobian/Django'nun en iyisi ve en kötüsü.

birine sahip olmak yerine ayarlar.py dosya, bu kurulumla bir ayarlar/ ayar
dosyalarınızı içeren dizin. Bu dizin tipik olarak aşağıdakine benzer bir şey içerir:

Örnek 5.1: Ayarlar Dizini

ayarlar/
├── __init__.py
├── base.py
├── local.py
├── hazırlama.py
├── test.py
├── üretim.py

UYARI: Gereksinimler + Ayarlar

Her ayar modülünün kendi ilgili gereksinim dosyası olmalıdır. Bunu bu


bölümün sonunda ele alacağızBölüm 5.5: Çoklu Gereksinim Dosyalarını
Kullanma.

İPUCU: Sürekli Entegrasyon Sunucularıyla Birden Çok Dosya

Ayrıca sahip olmak isteyeceksiniz ci.py o sunucunun ayarlarını içeren modül.


Benzer şekilde, büyük bir projeyse ve başka özel amaçlı sunucularınız varsa,

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 45


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 5: Ayarlar ve Gereksinim Dosyaları

Ayarlar dosyası Amaç


base.py Projenin tüm örnekleri için ortak olan
ayarlar.
yerel.py Bu, proje üzerinde yerel olarak çalışırken
kullandığınız ayarlar dosyasıdır. Yerel
geliştirmeye özgü ayarlar şunları içerir:
HATA AYIKLAMA modu, günlük düzeyi ve django-debug-
toolbar gibi geliştirici araçlarının etkinleştirilmesi.

staging.py Sitenin yarı özel sürümünü bir üretim


sunucusunda çalıştırmak için hazırlama
sürümü. İşiniz üretime taşınmadan önce
yöneticilerin ve müşterilerin bakmaları
gereken yer burasıdır.
test.py Test çalıştırıcıları, bellek içi veritabanı tanımları
ve günlük ayarları dahil olmak üzere test
çalıştırma ayarları.
üretim.py Bu, canlı prodüksiyon sunucularınız tarafından
kullanılan ayarlar dosyasıdır. Yani, gerçek canlı
web sitesini barındıran sunucu(lar). Bu dosya
yalnızca üretim düzeyindeki ayarları içerir. Bazen
denirürün.py.

Tablo 5.1: Ayarlar dosyaları ve amaçları

her biri için özel ayar dosyaları.

Şimdi bu kurulum ile Shell ve runserver yönetim komutlarının nasıl


kullanılacağına bir göz atalım. -ayarlar komut satırı seçeneği, bu nedenle komut
satırına aşağıdakileri gireceksiniz.

Python etkileşimli yorumlayıcısını Django ile başlatmak için, settings/local.py ayarlar dosyası:

Örnek 5.2: Yerel Ayarlar Kabuğu

python manager.py kabuğu -- ayarlar=config.settings.local

Sizinle yerel geliştirme sunucusunu çalıştırmak için settings/local.py ayarlar dosyası:

Örnek 5.3: Yerel Ayarlar Runserver

python manager.py runserver --ayarlar=config.settings.local

46 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


5.2: Birden Fazla Ayar Dosyasını Kullanma

İPUCU: DJANGO_SETTINGS_MODULE ve PYTHONPATH


Kullanmak için harika bir alternatif --ayarlar her yerde komut satırı seçeneği
ayarlamaktır DJANGO_SETTINGS_MODULE ve PİTONPATH ortam değişkeni
istediğiniz ayarlar modül yolunu mümkün. Bunu başarmak için ayarlamanız gerekir
DJANGO_SETTINGS_MODULE her ortam için ilgili ayarlar modülüne.

Virtualenvwrapper hakkında daha kapsamlı bir anlayışa sahip olanlar için, bir-
diğer alternatif ayarlamaktır DJANGO_SETTINGS_MODULE ve PİTONPATH içinde
sonradan etkinleştirmek komut dosyası ve onları sonradan devre dışı bırakmak senaryo.
Ardından, sanalenv etkinleştirildiğinde, sadece yazabilirsiniz.piton herhangi bir
yerden ve bu değerleri projenize aktarın. Bu aynı zamanda yazarakdjango-admin
komut satırında -- olmadan çalışırayarlar seçenek.

Az önce tanımladığımız ayarlar kurulumu için, -- ile kullanılacak değerler şunlardır:ayarlar


komut satırı seçeneği veya DJANGO_SETTINGS_MODULE Çevre değişkeni:

Çevre Birlikte Kullanma Seçeneği --ayarlar (veya


DJANGO_SETTINGS_MODULE değer)
Yerel geliştirme sunucunuz iki kepçe.settings.yerel
Hazırlama sunucunuz iki kepçe.settings.evreleme
Test sunucunuz iki kepçe.settings.test
Üretim sunucunuz iki kepçe.ayarlar.üretim

Tablo 5.2: Konum başına DJANGO_SETTINGS_MODULE ayarı

5.2.1 Geliştirme Ayarları Örneği


Daha önce belirtildiği gibi, konsol e-posta arka ucunu seçmek, projeyi içinde çalışacak şekilde
ayarlamak gibi geliştirme için yapılandırılmış ayarlara ihtiyacımız var. HATA AYIKLAMA modu ve yalnızca
geliştirme amacıyla kullanılan diğer yapılandırma seçeneklerini ayarlama. Aşağıdaki gibi geliştirme
ayarlarını yerleştiriyoruzsettings/local.py:

Örnek 5.4: settings/local.py

itibaren .temel içe aktarmak *

HATA AYIKLAMA = NS

EMAIL_BACKEND = 'Django.core.mail.backends.console.EmailBackend'

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 47


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 5: Ayarlar ve Gereksinim Dosyaları

VERİTABANLARI = {

'varsayılan': {
'MOTOR': 'Django.db.backends.postgresql','iki kaşık
'İSİM': toz',
'EV SAHİBİ': 'yerel ana bilgisayar',

}
}

INSTALLED_APPS += ['debug_toolbar', ]

Şimdi komut satırında şunu deneyin:

Örnek 5.5: yerel ayarlara sahip çalıştırma sunucusu

python manager.py runserver --ayarlar=config.settings.local

Açık http://127.0.0.1:8000 ve sürüm kontrolüne girmeye hazır geliştirme ayarlarınızın keyfini


çıkarın! Siz ve diğer geliştiriciler, paylaşılan projeler için harika olan aynı geliştirme ayarları
dosyalarını paylaşacaksınız.

Yine de başka bir avantaj daha var: Artık yok'eğer hata ayıklama' veya 'DEBUG değilse' projeler arasında
kopyalama/yapıştırma mantığı. Ayarlar artık çok daha basit!

Bu noktada, Django ayar dosyalarının kullanılmasını savunduğumuz tek, ıssız yer olduğunu
belirtmek isteriz. içe aktarmak *. Bunun nedeni Django ayar modüllerinin tekil durumu için
tüm ad alanını geçersiz kılmak istiyoruz.

5.2.2 Çoklu Geliştirme Ayarları


Bazen farklı geliştiricilerin farklı ayarlara ihtiyaç duyduğu ve aynı ayarları paylaştığı büyük bir
proje üzerinde çalışıyoruz. yerel.py takım arkadaşları ile ayarlar modülü yapmaz.

Herkesin aynı ayarları özelleştirmesine güvenmektense, bu ayarları sürüm kontrolünde izlemek daha iyidir.

yerel.py kendi zevklerine göre modül. Bunu yapmanın güzel bir yolu, birden çok geliştirme ayarı dosyası

kullanmaktır, örn.local_audrey.py ve local_pydanny.py:

Örnek 5.6: settings/local_pydanny.py

# settings/local_pydanny.pyitibaren
.yerel içe aktarmak *

48 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


5.3: Koddan Ayrı Yapılandırma

# Kısa önbellek zaman aşımını ayarla


CACHE_TIMEOUT = 30

Niye ya? Sadece kendi ayar dosyalarınızı sürüm kontrolünde tutmak değil, aynı zamanda takım
arkadaşlarınızın geliştirme ayarları dosyalarını görebilmek de iyidir. Bu şekilde, birinin yerel geliştirme
kurulumunda hayati veya yararlı bir ayarın eksik olup olmadığını anlayabilir ve herkesin yerel ayar
dosyalarının senkronize edildiğinden emin olabilirsiniz. Projelerimizin ayar düzeni için sıklıkla
kullandıkları şey:

Örnek 5.7: Özel Ayarlar

ayarlar/
__init__.py
base.py
local_audreyr.py
local_pydanny.py
yerel.py
staging.py
test.py
üretim.py

5.3 Koddan Ayrı Yapılandırma


local_settings anti-deseninin nedenlerinden biri, GİZLİ ANAHTAR, AWS anahtarları, API anahtarları
veya sunucuya özgü değerlere ayarlar dosyalarında sorun var:

a Yapılandırma, dağıtımlar arasında önemli ölçüde değişir, kod değişmez.

a Gizli anahtarlar, kod değil, yapılandırma değerleridir.


a Sırlar genellikle tam da bu olmalıdır: sır! Bunları sürüm kontrolünde tutmak şu anlama gelir:
depo erişimi olan herkesin bunlara erişimi vardır.
a Hizmet olarak platformlar genellikle size bireysel olarak kod düzenleme olanağı vermez.
sunucular. İzin verseler bile, bu çok tehlikeli bir uygulama.

Bunu çözmek için cevabımız kullanmaktır. Ortam Değişkenleri aramayı sevdiğimiz bir düzende,
peki,Ortam Değişkenleri Modeli.

Django (ve Python) tarafından desteklenen her işletim sistemi, ortam değişkenleri oluşturmak
için kolay yetenek sağlar.

Gizli anahtarlar için ortam değişkenlerini kullanmanın faydaları şunlardır:

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 49


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 5: Ayarlar ve Gereksinim Dosyaları

a Sırları ayarların dışında tutmak, her ayar dosyasını sürüm kontrolünde saklamanıza olanak tanır
tereddüt etmeden. Tüm Python kodunuz, ayarlarınız da dahil olmak üzere gerçekten sürüm
kontrolünde saklanmalıdır.
a Her geliştiricinin kolayca güncelliğini yitirmiş, kopyalayıp yapıştırılmış bir sürümünü sürdürmesi yerine

NS local_settings.py.örnek kendi geliştirme amaçları için dosya, herkes aynı sürüm


kontrollü paylaşır settings/local.py .
a Sistem yöneticileri, dosyaları değiştirmek zorunda kalmadan projeyi hızla dağıtabilir
Python kodunu içerir.
a Çoğu hizmet olarak platform, yapılandırma için ortam değişkenlerinin kullanılmasını önerir.
ve bunları ayarlamak ve yönetmek için yerleşik özelliklere sahiptir.

İPUCU: 12 Factor Uygulaması: Config'i Ortamda Depolayın

12 Factor App'in konfigürasyonla ilgili makalesini okuduysanız, bu kalıbı


tanıyacaksınız. Referans için bkz.12factor.net/config. Hatta bazı geliştiriciler,
ortam değişkenlerinin kullanımını tek bir ayar modülüyle birleştirmeyi
savunuyorlar. Biz bu uygulamayıBölüm 37: Ek E: Ayar Alternatifleri.

5.3.1 Sırlar için Ortam Değişkenlerini Kullanmadan Önce Dikkat Edilmesi Gerekenler

Ortam değişkenlerini ayarlamaya başlamadan önce aşağıdakilere sahip olmalısınız:

a Saklayacağınız gizli bilgileri yönetmenin bir yolu.


a Sunuculardaki ortam değişkenleriyle bash'ın nasıl çalıştığını iyi anlamak veya
projenizin bir hizmet olarak platform tarafından barındırılmasına istekli olma.

Daha fazla bilgi için bakınız en.wikipedia.org/wiki/Environment_variable.

UYARI: Ortam Değişkenleri Apache ile Çalışmaz

Hedef üretim ortamınız Apache kullanıyorsa (Elastic Beanstalk dışında), işletim sistemi
ortam değişkenlerini aşağıda açıklandığı gibi ayarlamanın işe yaramadığını
keşfedeceksiniz. Sorunun kafa karıştırıcı olması, Apache'nin kendi ortam değişken
sistemine sahip olmasıdır, bu da neredeyse ihtiyacınız olan şey değildir.
Apache kullanıyorsanız ve local_settings anti-pattern'den kaçınmak istiyorsanız,
okumanızı öneririz. Bölüm 5.4: Ortam Değişkenlerini Kullanamadığınızda bu bölümde
daha sonra.

50 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


5.3: Koddan Ayrı Yapılandırma

5.3.2 Ortam Değişkenlerini Yerel Olarak Ayarlama

Catalina öncesi Mac ve kullanan birçok Linux dağıtımında bash kabuk için, bir satırın sonuna
aşağıdaki gibi satırlar eklenebilir. .bashrc, .bash_profile, veya .profil. Catalina ve sonrasındaki
Mac'ler.zshrc. Aynı API'yi kullanan ancak farklı anahtarlarla birden fazla projeyle uğraşırken,
bunları sanalenv'lerinizin sonuna da yerleştirebilirsiniz.bin/sonraki etkinleştirsenaryo:

Örnek 5.8: Linux/OSX'te Ortam Değişkenlerini Ayarlama

ihracat SOME_SECRET_KEY=1c3-cr3am-15-nefisAUDREY_FREEZER_KEY=y34h-
ihracat r1ght-d0nt-t0uch-my-1c3-cr34m

Windows sistemlerinde, biraz daha zor. Bunları komut satırında tek tek ayarlayabilirsiniz (
cmd.exe) ile kalıcı bir şekilde setx ancak etkin olmaları için komut isteminizi kapatıp
yeniden açmanız gerekir. Bu komutları virtualenv'lerin sonuna yerleştirmek daha iyi bir
yoldur.bin/postactivate.bat komut dosyası etkinleştirildikten sonra kullanılabilirler:

Örnek 5.9: Windows'ta Ortam Değişkenlerini Ayarlama

> setx SOME_SECRET_KEY 1c3-cr3am-15-nefis

Güç kalkanı varsayılan Windows kabuğundan çok daha güçlüdür ve Windows Vista ve
üzeri ile birlikte gelir. PowerShell kullanırken ortam değişkenlerini ayarlama:

Yalnızca geçerli Windows kullanıcısı için:

Örnek 5.10: Powershell'de Ortam Değişkenlerini Ayarlama

[Çevre]::Çevre Değişkenini Ayarla('SOME_SECRET_KEY',


'1c3-cr3am-15-nefis', 'Kullanıcı')
[Çevre]::Çevre Değişkenini Ayarla('AUDREY_FREEZER_KEY',
'y34h-r1ght-d0nt-t0uch-my-1c3-cr34m', 'Kullanıcı')

Makine çapında:

Örnek 5.11: Powershell'de Ortam Değişkenlerini Global Olarak Ayarlama

[Çevre]::Çevre Değişkenini Ayarla('SOME_SECRET_KEY',


'1c3-cr3am-15-nefis', 'Makine')

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 51


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 5: Ayarlar ve Gereksinim Dosyaları

[Çevre]::Çevre Değişkenini Ayarla('AUDREY_FREEZER_KEY',


'y34h-r1ght-d0nt-t0uch-my-1c3-cr34m', 'Makine')

Powershell hakkında daha fazla bilgi için bkz. tr.wikipedia.org/wiki/PowerShell

İPUCU: virtualenvwrapper Bunu Kolaylaştırıyor

Bu kitapta daha önce bahsedilen, sanalenvwrapper, sanal ortam başına ortam


değişkenlerini basitleştirir. Bu harika bir araçtır. Ancak, onu kurmak, kabuk ve Mac, Linux
veya Windows hakkında temelden daha fazla bir anlayış gerektirir.

5.3.3 Ortam Değişkenlerini Yerel Olarak Ayarlama

Yukarıda listelenen komutlar aracılığıyla bir ortam değişkeni ayarladığınızda, ayarlanana veya
kabuk sona erene kadar bu terminal kabuğunda varlığını sürdürecektir. Bu, bir virtualenv'i devre
dışı bıraksanız bile ortam değişkeninin kaldığı anlamına gelir. Tecrübelerimize göre, bu zamanın
%99'unda iyidir. Ancak, ortam değişkenlerini sıkı bir şekilde kontrol etmek istediğimiz durumlar
vardır. Bunu yapmak için işletim sistemi veya kabuk varyantı için uygun komutu yürütürüz:

Örnek 5.12: Linux/OSX/Windows'ta Ortam Değişkenlerini Kaldırma

ayarsız SOME_SECRET_KEY
ayarsız AUDREY_FREEZER_KEY

Örnek 5.13: Powershell'de Ortam Değişkenlerinin Ayarını Kaldırma

[Çevre]::UnsetEnvironmentDeğişken('SOME_SECRET_KEY', 'Kullanıcı') [Çevre]


::UnsetEnvironmentDeğişken('AUDREY_FREEZER_KEY',

→ 'Kullanıcı')

Virtualenvwrapper kullanıyorsanız ve bir virtualenv devre dışı bırakıldığında ortam değişkenlerinin


ayarını kaldırmak istiyorsanız, bu komutları sonradan devre dışı bırakmak senaryo.

5.3.4 Üretimde Ortam Değişkenleri Nasıl Ayarlanır


Kendi sunucularınızı kullanıyorsanız, tam uygulamalarınız kullandığınız araçlara ve kurulumunuzun
karmaşıklığına bağlı olarak farklılık gösterecektir. Test projeleri için en basit 1 sunucu kurulumu için,

52 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


5.3: Koddan Ayrı Yapılandırma

ortam değişkenlerini manuel olarak ayarlayabilir. Ancak, otomatik sunucu sağlama ve


dağıtım için komut dosyaları veya araçlar kullanıyorsanız, yaklaşımınız daha karmaşık
olabilir. Daha fazla bilgi için dağıtım araçlarınızın belgelerine bakın.

Django projeniz Heroku, Python Anywhere, platform.sh vb. gibi bir hizmet olarak
platform (PaaS) aracılığıyla dağıtılıyorsa, belirli talimatlar için belgelere bakın.

Python tarafından ortam değişkenlerine nasıl eriştiğinizi görmek için yeni bir Python istemi açın
ve şunu yazın:

Örnek 5.14: Python'un REPL'sinde Ortam Değişkenlerine Erişme

>>> içe aktarmak işletim sistemi

> > > işletim sistemi.çevre[


'SOME_SECRET_KEY']'1c3-cr3am-15-nefis'

Ayar dosyalarınızdan birinden ortam değişkenlerine erişmek için şöyle bir şey
yapabilirsiniz:

Örnek 5.15: Python'da Ortam Değişkenlerine Erişme

# settings/production.py'nin üst kısmıiçe aktarmak

işletim sistemi

SOME_SECRET_KEY = işletim sistemi.çevre['SOME_SECRET_KEY']

Bu snippet, yalnızca SOME_SECRET_KEY işletim sisteminden ortam değişkeni ve


onu adlı bir Python değişkenine kaydeder SOME_SECRET_KEY.

Bu kalıbı takip etmek, tüm kodların sürüm kontrolünde kalabileceği ve tüm sırların güvende kalacağı anlamına gelir.

5.3.5 Eksik Gizli Anahtar İstisnalarının İşlenmesi

Yukarıdaki uygulamada, eğer GİZLİ ANAHTAR mevcut değil, bir Anahtar Hatası ,projeye
başlamayı imkansız hale getiriyor. Bu harika, ama birAnahtar Hatası aslında neyin yanlış
olduğu hakkında pek bir şey söylemez. Daha yararlı bir hata mesajı olmadan, özellikle
kullanıcılar beklerken ve dondurmanız erirken sunuculara dağıtma baskısı altında bu hata
ayıklamak zor olabilir.

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 53


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 5: Ayarlar ve Gereksinim Dosyaları

İşte bu eksik ortam değişkenlerinde sorun gidermeyi kolaylaştıran kullanışlı bir


kod parçacığı. Önerilen ortam değişken sırları yaklaşımımızı kullanıyorsanız,
bunuayarlar/base.py dosya:

Örnek 5.16: get_env_variable() İşlev

# settings/base.py
içe aktarmak işletim sistemi

# Normalde HİÇBİR ŞEYİ Django'dan doğrudan içe aktarmamalısınız


# ayarlarınıza girin, ancak ImproperlyConfigured bir istisnadır.itibaren
django.core.istisnalar içe aktarmak Yanlış Yapılandırılmış

tanım get_env_variable(var_name):
"""Ortam değişkenini alın veya istisnayı döndürün."""denemek:

dönüş işletim sistemi.çevre[var_name]


hariç Anahtar Hatası:
hata_msg = 'Yı kur {} Çevre

→ değişken'.biçim(var_name)artırmak Yanlış
Yapılandırılmış(error_msg)

Ardından, ayar dosyalarınızdan herhangi birinde ortam değişkenlerinden gizli anahtarları aşağıdaki gibi

yükleyebilirsiniz:

Örnek 5.17: Kullanma get_env_variable()

SOME_SECRET_KEY = get_env_variable('SOME_SECRET_KEY')

Şimdi, eğer yoksa SOME_SECRET_KEY bir ortam değişkeni olarak ayarladığınızda, aşağıdaki gibi faydalı
bir hata mesajıyla biten bir geri izleme elde edersiniz:

Örnek 5.18: Tarafından Oluşturulan Hata get_env_variable()

django.çekirdek.istisnalar.Yanlış Yapılandırılmış:

→ SOME_SECRET_KEY
Çevre değişkeni.

54 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


5.4: Ortam Değişkenlerini Kullanamadığınızda

UYARI: Django Bileşenlerini Ayarlar Modüllerine


Aktarmayın
Bunun pek çok öngörülemeyen yan etkisi olabilir, bu nedenle ayarlarınıza her türlü
Django bileşenini içe aktarmaktan kaçının. Yanlış Yapılandırılmış İstisnadır çünkü
bu,...iyi...uygunsuz şekilde yapılandırılmış projeler için resmi Django istisnasıdır. Ve
yardımcı olmak için, hata mesajına sorun ayarının adını ekliyoruz.

PAKET İPUCU: Ayarlar Yönetimi için Paketler

Bir dizi üçüncü taraf paketi bizim fikrimizi alır. get_env_variable() varsayılanlar ve türler ve
destekleme gibi özellikler dahil olmak üzere işlev ve genişletme .ortamDosyalar.
Dezavantajı, herhangi bir karmaşık pakette elde ettiğinizle aynıdır: bazen uç durumlar
sorunlara neden olur. Bununla birlikte, çoğu oldukça kullanışlıdır ve favorilerimizden
bazılarını listeledik:
a github.com/joke2k/django-environ (Cookieecutter Django'da kullanılır)
a github.com/jazzband/django-configurations

İPUCU: Manage.py Yerine Django-admin Kullanımı

Resmi Django belgeleri, kullanmanız gerektiğini söylüyor django-admin ziyade


yönetmek.py birden fazla ayar dosyasıyla çalışırken:
docs.djangoproject.com/en/3.2/ref/django-admin/

Bununla birlikte, almakta zorlanıyorsanız django-admin çalışmak için, sitenizi çalıştıran


sitenizi geliştirmek ve başlatmak tamamen sorun değil yönetmek.py.

5.4 Ortam Değişkenlerini Kullanamadığınızda


Sırları saklamak için ortam değişkenlerini kullanmanın sorunu, her zaman çalışmamasıdır. Bunun
için en yaygın senaryo, Apache'nin HTTP sunmak için kullanılmasıdır, ancak bu, işlemlerin belirli
bir şekilde yapmak istediği Nginx tabanlı ortamlarda bile olur. Bu gerçekleştiğinde, geri dönmek
yerinelocal_settings anti-desenolarak adlandırmayı sevdiğimiz bir yöntemde sürüm kontrolü
dışında tutulan yürütülemez dosyaların kullanılmasını savunuyoruz. sırlar dosya kalıbı.

uygulamak için sırlar dosya kalıbı, şu üç adımı izleyin:

1 JSON, .env, Config, YAML ve hatta XML olsun, tercih ettiğiniz yapılandırma biçimini kullanarak bir gizli

dizi dosyası oluşturun.

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 55


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 5: Ayarlar ve Gereksinim Dosyaları

2 Gizli dizileri uyumlu ve açık bir şekilde yönetmek için bir gizli dizi yükleyici (aşağıda JSON
destekli örnek) ekleyin.
3 Gizli dosya adını projenin .gitignore dosya.

5.4.1 JSON Dosyalarını Kullanma

Tercihimiz sığ JSON dosyalarını kullanmaktır. JSON formatı, hem Python hem de Python dışı araçlar için
tercih edilen bir format olma avantajına sahiptir. Bunu yapmak için önce birsırlar.jsondosya:

Örnek 5.19: secrets.json

{
"DOSYA ADI": "gizler.json","GİZLİ ANAHTAR":
"Bir sırrım var!","VERİTABANLARI_HOST":
"127.0.0.1","LİMAN": "5432"

kullanmak için sırlar.json dosya, temel ayarlar modülünüze aşağıdaki kodu ekleyin.

Örnek 5.20: get_settings() İşlevi

# settings/base.py
içe aktarmak json

# Normalde HİÇBİR ŞEYİ Django'dan doğrudan içe aktarmamalısınız


# ayarlarınıza girin, ancak ImproperlyConfigured bir istisnadır.itibaren
django.core.istisnalar içe aktarmak Yanlış Yapılandırılmış

# JSON tabanlı sırlar modülüile birlikte


açık('gizler.json') olarak F:
sırlar = json.yük(f)

tanım get_secret(ayar, sırlar=sırlar):


'''Gizli değişkeni al veya açık istisnayı döndür.'''denemek:

dönüş sırlar[ayar]hariç
Anahtar Hatası:
hata_msg = 'Yı kur {0} Çevre

→ değişken'.biçim(ayar)artırmak Yanlış
Yapılandırılmış(error_msg)

56 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


5.5: Çoklu Gereksinim Dosyalarını Kullanma

GİZLİ ANAHTAR = get_secret('GİZLİ ANAHTAR')

Artık, sürümlendirilmemiş yürütülebilir kod yerine yürütülemez JSON dosyalarından sırlar


yüklüyoruz. Yaşasın!

PAKET İPUCU: Zappa Güçlü Seçenekler Sağlar

AWS Lambda'ya dağıtım için Zappa'yı tercih etmemizin nedenlerinden biri, ortam değişkeni
yönetimi için sunduğu farklı ve güçlü seçeneklerdir. Kesinlikle bir göz atmaya değer ve diğer
araçların ve barındırma platformlarının benimsemesini görmek istediğimiz bir şey.
Referans: github.com/Miserlou/Zappa#setting-environment-variables

5.4.2 .env, Config, YAML ve XML Dosya Biçimlerini Kullanma

Biz sığ JSON'un zorunlu basitliğini tercih ederken, diğerleri diğer dosya biçimlerini
tercih edebilir. Ek oluşturmayı okuyucuya bırakacağız.get_secret() bu formatlarla çalışan
alternatifler. Sadece gibi şeylere aşina olmayı unutmayınyaml.safe_load()
ve XML bombaları. GörmekBölüm 28.10: Python Kod Enjeksiyon Saldırılarına Karşı Savunma.

5.5 Çoklu Gereksinim Dosyalarını Kullanma


Son olarak, birden çok ayar dosyası kurulumu hakkında bilmeniz gereken bir şey daha var. Her
ayar dosyasının kendi ilgili gereksinim dosyasına sahip olması iyi bir uygulamadır. Bu, her
sunucuya yalnızca gerekli olanı yüklediğimiz anlamına gelir.

Jeff Triplett tarafından bize önerilen bu kalıbı takip etmek için önce bir
Gereksinimler/ içindeki dizin <depo_kök>. Sonra oluştur'.txt' ayarlar dizininizin
içeriğiyle eşleşen dosyalar. Sonuçlar şöyle görünmelidir:

Örnek 5.21: Bölümlere Ayrılmış Gereksinimler

Gereksinimler/
├── base.txt
├── local.txt
├── hazırlama.txt
├── üretim.txt

İçinde base.txt dosyası, tüm ortamlarda kullanılan bağımlılıkları yerleştirin. Örneğin,


orada aşağıdaki gibi bir şey olabilir:

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 57


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 5: Ayarlar ve Gereksinim Dosyaları

Örnek 5.22: gereksinimler/base.txt

Django==3.2.0
psycopg2-ikili==2.8.8
djangorest çerçevesi==3.11.0

Sizin yerel.txt dosyası, yerel geliştirme için kullanılan bağımlılıklara sahip olmalıdır, örneğin:

Örnek 5.23: gereksinimler/local.txt

- r base.txt #, base.txt gereksinimleri dosyasını içerir

kapsam==5.1
django-debug-araç çubuğu==2.2

Bir sürekli tümleştirme sunucusunun gereksinimleri, aşağıdakileri isteyebilir: ci.txt dosya:

Örnek 5.24: gereksinimler/ci.txt

- r base.txt #, base.txt gereksinimleri dosyasını içerir

kapsam==5.1

Üretim tesisleri diğer lokasyonlarda kullanılanlara yakın olmalıdır, bu nedenle üretim.txt


genellikle sadece arar base.txt:

Örnek 5.25: gereksinimler/üretim.txt

- r base.txt #, base.txt gereksinimleri dosyasını içerir

5.5.1 Çoklu Gereksinim Dosyalarından Yükleme

Yerel kalkınma için:

Örnek 5.26: Yerel Gereksinimleri Yükleme

pip kurulum -r gereksinimleri/local.txt

Prodüksiyon için:

58 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


5.6: Ayarlarda Dosya Yollarını İşleme

Örnek 5.27: Üretim Gereksinimlerini Yükleme

pip kurulum -r gereksinimleri/üretim.txt

İPUCU: Pin Gereksinimleri Tam Olarak

Bu bölümdeki tüm pip gereksinimleri.txt örnekleri açıkça bir paket sürümüne


ayarlanmıştır. Bu daha istikrarlı bir proje sağlar. Bunu uzun uzadıya ele alıyoruzBölüm
23.7.2: Adım 2: Gereksinimlerinize Paket ve Sürüm Numarası Ekleyin.

İPUCU: PaaS ile Çoklu Gereksinim Dosyalarını Kullanma

Biz bunu kapsarız ??: ??

5.6 Ayarlarda Dosya Yollarını İşleme


Birden çok ayar kurulumuna geçerseniz ve şablonlar ve medya gibi şeylerde yeni dosya yolu
hataları alırsanız telaşlanmayın. Bu bölüm, bu hataları çözmenize yardımcı olacaktır.

Okuyucuya, Django ayar dosyalarındaki dosya yollarını asla sabit kodlamaması için alçakgönüllülükle yalvarıyoruz. Bugerçekten

kötü:

Örnek 5.28: Dosya Yollarını Asla Sabit Kodlama

# settings/base.py

# MEDIA_ROOT'u Yapılandırma
#BUNU YAPMA! Yalnızca bir kullanıcının tercihlerine göre kodlanmış
MEDYA_KÖK = '/Users/pydanny/twoscoops_project/media'

# STATIC_ROOT'u yapılandırma
#BUNU YAPMA! Yalnızca bir kullanıcının tercihlerine göre kodlanmışSTATIC_ROOT = '/
Users/pydanny/twoscoops_project/collected_static'

# STATICFILES_DIRS yapılandırması
#BUNU YAPMA! Yalnızca bir kullanıcının tercihlerine göre kodlanmışSTATICFILES_DIRS
= ['/Users/pydanny/twoscoops_project/statik']

# ŞABLONLARI Yapılandırma
#BUNU YAPMA! Yalnızca bir kullanıcının tercihlerine göre kodlanmış
ŞABLONLAR = [
{

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 59


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 5: Ayarlar ve Gereksinim Dosyaları

'GERİ UÇ':

→ 'Django.template.backends.django.DjangoTemplates', DIRS: ['/Users/
pydanny/twoscoops_project/şablonlar',]
},
]

Yukarıdaki kod, adı verilen yaygın bir tuzağı temsil eder. sabit kodlama. Adı verilen
yukarıdaki kodsabit yol, kötü çünkü bildiğiniz kadarıyla, pirzola (Daniel Feldroy),
bilgisayarını bu yol yapısına uyacak şekilde kuran tek kişidir. Bu örneği kullanmaya çalışan
herhangi biri, proje kesintilerini görecek ve onları dizin yapılarını değiştirmeye (olası değil)
veya ayarlar modülünü tercihlerine uyacak şekilde değiştirmeye zorlayacaktır (pydanny
dahil herkes için sorunlara neden olur).

Yollarınızı sabit kodlamayın!

Yol sorununu çözmek için, sezgisel olarak adlandırılmış bir proje kök değişkenini dinamik olarak belirledik BASE_DIR

temel ayarlar modülünün en üstünde. Dan beriBASE_DIR base.py'nin konumu ile ilgili olarak belirlenir,
projeniz herhangi bir geliştirme bilgisayarı veya sunucusundaki herhangi bir yerden çalıştırılabilir.

Şekil 5.2: Hazır gelmişken bu yoldan gidelim.

ayarlamanın en temiz yolunu buluyoruz. BASE_DIR-ayar ile olduğu gibi Pathlib, zarif, temiz yol
hesaplamaları yapan 3.4'ten beri Python'un bir parçası:

Örnek 5.29: Proje kökünü keşfetmek için Pathlib'i kullanma

# settings/base.py'nin en üstündeitibaren yol


kütüphanesi içe aktarmak Yol

BASE_DIR = Yol(__dosya__).çözmek().ebeveyn.ebeveyn.üst MEDIA_ROOT =


BASE_DIR / 'medya'STATIC_ROOT = BASE_DIR / 'statik_kök'

60 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


5.6: Ayarlarda Dosya Yollarını İşleme

STATICFILES_DIRS = [BASE_DIR / 'statik'] ŞABLONLAR = [

{
'GERİ UÇ':

→ 'Django.template.backends.django.DjangoTemplates','DIRS':
[BASE_DIR / 'şablonlar']
},
]

gerçekten ayarlamak istiyorsanız BASE_DIR Python standart kitaplığı ile os.path kütüphane
olsa da, bu, yolları hesaba katacak şekilde yapmanın bir yoludur:

Örnek 5.30: Proje kökünü keşfetmek için os.path kullanma

# settings/base.py'nin en üstündeitibaren os.path içe


aktarmak abspath, dirname, katılmak

tanım kök(*dizinler):
base_dir = birleş(dirname(__dosya__), '..', '..')dönüş
abspath(join(base_dir, *yön))

BASE_DIR = kök()
MEDIA_ROOT = kök('medya')
STATIC_ROOT = kök('statik_kök')
STATICFILES_DIRS = [kök('statik')]
ŞABLONLAR = [
{
'GERİ UÇ':

→ 'Django.template.backends.django.DjangoTemplates','DIRS': [kök(
'şablonlar')],
},
]

Bağlı olarak çeşitli yol ayarlarınızla BASE_DIR, dosya yolu ayarlarınızın çalışması gerekir, bu da
şablonlarınızın ve medyanızın hatasız yüklenmesi gerektiği anlamına gelir.

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 61


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 5: Ayarlar ve Gereksinim Dosyaları

İPUCU: Ayarlarınız Django Varsayılanlarından Ne Kadar


Farklı?

Projenizdeki şeylerin Django'nun varsayılanlarından nasıl farklı olduğunu bilmek istiyorsanız,

farklar yönetim komutu.

5.7 Özet
Parolalar ve API anahtarları dışındaki her şeyin sürüm kontrolünde izlenmesi gerektiğini
unutmayın.

Gerçek bir canlı prodüksiyon sunucusuna yönelik herhangi bir proje, birden çok ayar ve gereksinim
dosyasına ihtiyaç duyar. Django'ya yeni başlayanlar bile, projeleri orijinal geliştirme makinesinden
ayrılmaya hazır olduğunda bu tür ayarlar/gereksinim dosyası kurulumuna ihtiyaç duyar. Hem yeni
başlayan hem de ileri düzey geliştiriciler için iyi çalıştığından, çözümümüzün yanı sıra Apache dostu bir
çözüm sunuyoruz.

Ayrıca, sağlananlardan farklı bir kabuk tercih ederseniz, ortam değişkenleri çalışmaya devam eder.
Bunları tanımlamak için sözdizimini bilmeniz yeterlidir.

Aynı şey gereksinim dosyaları için de geçerlidir. İzlenmeyen bağımlılık farklılıklarıyla


çalışmak, izlenmeyen ayarlar kadar riski artırır.

62 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


6 | En İyi Uygulamaları Modelleyin

Modeller, çoğu Django projesinin temelidir. Üzerinde düşünmeden Django modelleri


yazmak için yarışmak, yolda sorunlara yol açabilir.

Çoğu zaman biz geliştiriciler, yaptığımız şeyin sonuçlarını düşünmeden model eklemeye veya
model değiştirmeye koşarız. Kod tabanımıza attığımız hızlı düzeltme veya özensiz "geçici"
tasarım kararı, önümüzdeki aylarda veya yıllarda bize zarar verebilir, çılgın geçici çözümlere
zorlayabilir veya mevcut verileri bozabilir.

Bu nedenle, Django'ya yeni modeller eklerken veya mevcut olanları değiştirirken bunu aklınızda bulundurun.

Bir şeyleri düşünmek için zaman ayırın ve temelinizi mümkün olduğunca güçlü ve sağlam olacak şekilde

tasarlayın.

PAKET İPUCU: Modellerle Çalışmak İçin Seçtiklerimiz

İşte hemen hemen her projede kullandığımız modelle ilgili Django paketlerinin
hızlı bir listesi.
a django-model-utils gibi ortak kalıpları işlemek için Zaman DamgalıModel.

a django uzantıları adlı güçlü bir yönetim komutuna sahiptir.


shell_plus bu, yüklü tüm uygulamalar için model sınıflarını otomatik olarak
yükler. Bu kitaplığın dezavantajı, küçük, odaklanmış uygulamalar
tercihimizden ayrılan birçok başka işlevsellik içermesidir.

6.1 Temel bilgiler

6.1.1 Uygulamaları Çok Fazla Modelle Dağıtın

Tek bir uygulamada 20'den fazla model varsa, bunu daha küçük uygulamalara ayırmanın yollarını düşünün,

çünkü bu muhtemelen uygulamanızın çok fazla şey yaptığı anlamına gelir. Pratikte, bu sayıyı uygulama başına

en fazla beş ila on modele düşürmeyi seviyoruz.

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 63


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 6: En İyi Uygulamaları Modelleyin

6.1.2 Model Kalıtımı Konusunda Dikkatli Olun

Django'da model kalıtımı zor bir konudur. Django, model kalıtımı yapmanın üç yolunu
sunar:soyut temel sınıflar, çok tablolu kalıtım, ve proxy modelleri.

UYARI: Django Soyut Temel Sınıfları <> Python Soyut Temel


Sınıfları
Django soyut temel sınıflarını Python standart kitaplığının abc modülündeki
soyut temel sınıflarla karıştırmayın, çünkü çok farklı amaçları ve davranışları
vardır.

İşte üç model kalıtım stilinin artıları ve eksileri. Tam bir karşılaştırma yapmak için,
başlangıç olarak model kalıtımı kullanma seçeneğini de ekledik:

Model Kalıtım Stili Artıları Eksileri

Model mirası yok: Django modellerinin Modeller arasında çoğaltılan


modellerin ortak bir alanı veritabanı tablolarıyla nasıl çok sayıda alan varsa, bunu
varsa, her iki modele de o eşleştiğini bir bakışta sürdürmek zor olabilir.
alanı verin. anlamayı kolaylaştırır.
Soyut temel sınıflar: tablolar Soyut bir üst sınıfta ortak Ebeveyn sınıfı izolasyonda
yalnızca türetilmiş modeller için alanlara sahip olmak, bizi kullanamayız.
oluşturulur. onları birden fazla
yazmaktan kurtarır.
Çok tablolu kalıtımdan
kaynaklanan ek tabloların
ve birleşimlerin ek yükünü
almıyoruz.
Çoklu masa miras: Her modele kendi Bir alt tablodaki her sorgu,
tablolar hem ebeveyn hem tablosunu verir, böylece tüm üst tablolarla birleştirme
de çocuk için oluşturulur. Bir ebeveyn veya alt modeli gerektirdiğinden, önemli
ima edilen OneToOneField sorgulayabiliriz. miktarda ek yük ekler.
ebeveyn ve çocuğu birbirine bağlar. Ayrıca bize bir ana biz şiddetle önermek
nesneden bir alt nesneye kullanmaya karşı çoklu masa
ulaşma yeteneği verir: miras. Aşağıdaki uyarıya
ebeveyn.çocuk bakın.
Proxy modelleri: Yalnızca Farklı Python davranışına sahip Modelin alanlarını
orijinal model için bir tablo bir modelin takma adına sahip değiştiremeyiz.
oluşturulur. olmamızı sağlar.

Tablo 6.1: Model Kalıtım Stillerinin Artıları ve Eksileri


64 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


6.1: Temel Bilgiler

UYARI: Çoklu Tablo Kalıtımından Kaçının


Bazen "somut kalıtım" olarak adlandırılan çok tablolu kalıtım, yazarlar ve diğer birçok
geliştirici tarafından kötü bir şey olarak kabul edilir. Kullanmamanızı şiddetle tavsiye
ederiz. Birazdan bunun hakkında daha fazla ayrıntıya gireceğiz.

Hangi tür kalıtımın ne zaman kullanılacağını bilmek için bazı basit kurallar:

a Modeller arasındaki örtüşme minimum ise (örneğin, yalnızca birkaç modeliniz varsa)
bir veya iki aynı adlandırılmış alanı paylaşan), model mirasına gerek olmayabilir.
Sadece alanları her iki modele de ekleyin.
a Modellerin tekrarlanan alanlarının bakımını yapan modeller arasında yeterli örtüşme varsa
karışıklığa ve kasıtsız hatalara neden olursa, çoğu durumda ortak alanların soyut bir
temel modelde olması için kodun yeniden düzenlenmesi gerekir.
a Proxy modelleri ara sıra yararlı bir kolaylık özelliğidir, ancak çok farklıdırlar.
diğer iki model miras stilinden.
a Ne pahasına olursa olsun, herkes çok tablolu mirastan kaçınmalıdır (yukarıdaki uyarıya bakın), çünkü

hem kafa karışıklığı hem de önemli miktarda ek yük ekler. Çok tablolu devralma yerine açık
kullanınOneToOneFields ve Yabancı anahtarlar modeller arasında, böylece birleşimlerin ne zaman
geçildiğini kontrol edebilirsiniz. 20 yılı aşkın süredir Django yaparken çok tablolu kalıtımın
beladan başka bir şeye neden olduğunu hiç görmedik.

6.1.3 Uygulamada Model Kalıtımı: TimeStampedModel


Django projelerinde bir yaratıldı ve değiştirilmiş tüm modellerinizde zaman
damgası alanı. Bu alanları her modele manuel olarak ekleyebiliriz, ancak bu çok
fazla iş ve insan hatası riskini artırır. yazmak daha iyi bir çözümdür.
Zaman DamgalıModel işi bizim için yapmak için:

Örnek 6.1: core/models.py

itibaren django.db içe aktarmak modeller

sınıf Zaman DamgalıModel(modeller.modeli):


"""
Kendi kendini güncelleyen "yaratılan" ve "değiştirilen" alanlar
sağlayan soyut bir temel sınıf modeli. """

yaratıldı = modeller.DateTimeField(auto_now_add=NS)

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 65


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 6: En İyi Uygulamaları Modelleyin

değiştirilmiş = modeller.DateTimeField(auto_now=NS)

sınıf Meta:
Öz = NS

Örneğimizi soyut bir temel sınıfa dönüştüren örnekteki son iki satırı dikkatlice not
edin:

Örnek 6.2: Soyut bir temel sınıf tanımlama

sınıf Meta:
Öz = NS

tanımlayarak Zaman DamgalıModel soyut bir temel sınıf olarak, ondan miras alan yeni
bir sınıf tanımladığımızda, Django bir core_timestampedmodel masa ne zaman göç
çalıştırılır.

Hadi test edelim:

Örnek 6.3: tatlar/models.py

# tatlar/models.py
itibaren django.db içe aktarmak modeller

itibaren çekirdek.modeller içe aktarmak Zaman DamgalıModel

sınıf Lezzet(Zaman Damgalı Model):


Başlık = modeller.CharField(maks_uzunluk=200)

Bu yalnızca bir tablo oluşturur: tatlar_flavor veritabanı tablosu. Tam olarak istediğimiz davranış
buydu.

Öte yandan, eğer Zaman DamgalıModel soyut bir temel sınıf değildi (yani, çok tablolu
kalıtım yoluyla somut bir temel sınıf), aynı zamanda bir core_timestampedmodel
tablo. Sadece bu değil, tüm alt sınıfları da dahil olmak üzereLezzet alanlardan yoksun olurdu ve örtük
yabancı anahtarlara geri dönerdi Zaman DamgalıModel sadece işlemek için oluşturuldu/değiştirildi
zaman damgaları. herhangi bir referansLezzet okuyan veya yazan Zaman DamgalıModel
iki tabloyu etkiler. (Şükürler olsun ki soyut!)

66 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


6.2: Veritabanı Taşımaları

Unutmayın, somut mirasın kötü bir performans darboğazı olma potansiyeli vardır. Bu,
somut bir model sınıfını birden çok kez alt sınıfladığınızda daha da doğrudur.

Daha fazla okuma:

a docs.djangoproject.com/en/3.2/topics/db/models/
# model kalıtımı

6.2 Veritabanı Taşımaları


Django, uygun bir şekilde “adlı güçlü bir veritabanı değişikliği yayma kitaplığı ile birlikte gelir.
göçler” veya kitapta atıfta bulunmayı tercih ettiğimiz gibi, django.db.migrations.

6.2.1 Taşıma Oluşturma İpuçları

a Yeni bir uygulama veya model oluşturulur oluşturulmaz, bu fazladan dakikayı


ilk django.db.migrations bu yeni model için. Tek yaptığımız yazmakpiton
Manage.py makemigrations.
a Oluşturulan taşıma kodunu çalıştırmadan önce, özellikle karmaşık olduğunda inceleyin
değişiklikler söz konusudur. Ayrıca, kullanılacak SQL'i de gözden geçirin.sqlmigrate
emretmek.
a Kullan MIGRATION_MODULES üçüncü taraf için yazma geçişlerini yönetme ayarı
kendilerine ait olmayan uygulamalar django.db.migrations-tarzı göçler.
a Kaç tane geçiş oluşturulduğu konusunda endişelenmeyin. Göç sayısı ise
hantal hale gelir, kullanın kabak göçü onları dize getirmek için.
a Taşıma işlemini çalıştırmadan önce her zaman verilerinizi yedekleyin.

6.2.2 Geçişlere Python İşlevleri ve Özel SQL Ekleme


django.db.migrations verilerinizde veya verilerinizle etkileşime giren harici bileşenlerde karmaşık

değişiklikleri tahmin edemez. İşte o zaman, geçişleri çalıştırmaya yardımcı olmak için python veya özel
SQL yazmayı araştırmak yararlıdır. Üretime giren herhangi bir projenin bir noktasında, ikisinden birini
kullanmak için bir neden bulacaksınız.RunPython veya RunSQL sınıflar:

a docs.djangoproject.com/en/3.2/ref/migration-operations/
# runpython
a docs.djangoproject.com/en/3.2/ref/migration-operations/#runsql

Değeri ne olursa olsun, tercihimiz kullanmaktır. RunPython önce RunSQL, ama güçlü yönlerinizin olduğu
yerde kalmanızı tavsiye ederiz.

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 67


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 6: En İyi Uygulamaları Modelleyin

6.3 RunPython'un Ortak Engellerini Aşmak


RunPython denilen fonksiyonları yazdığımızda bir kaç acı nokta ile karşılaşıyoruz. Bunların çoğu,
ancak hepsi çözülemez.

6.3.1 Özel Model Yöneticisinin Yöntemlerine Erişim


Bazen özel model yöneticisi yöntemlerini kullanarak kayıtları filtrelemek, hariç tutmak,
oluşturmak veya değiştirmek istersiniz. Ancak, varsayılan olarakdjango.db.migrations
bu bileşenleri hariç tutar. Neyse ki, bir ekleyerek bu davranışı geçersiz kılabiliriz.
use_in_migrations = NS özel yöneticilerimize bayrak.

Görmek: docs.djangoproject.com/en/3.2/topics/migrations/#model-managers

6.3.2 Özel Model Yöntemine Erişim


nasıl nedeniyle django.db.migrations modelleri serileştirir, bu sınırlamayı aşmanın bir yolu yoktur.
Taşıma sırasında herhangi bir özel yöntemi çağıramazsınız. Aşağıdaki referans bağlantısına
bakın:

docs.djangoproject.com/en/3.2/topics/migrations/#historical-models

UYARI: Özel Kaydetme ve Silme Yöntemlerine Dikkat Edin


Bir modelin kaydetme ve silme yöntemlerini geçersiz kılarsanız, RunPython tarafından

çağrıldıklarında bunlar çağrılmaz. Kendinizi uyarılmış düşünün, bu yıkıcı bir sonuç olabilir.

6.3.3 Hiçbir Şey Yapmamak için RunPython.noop Kullanın

Ters geçişlerin çalışması için RunPython'a bir ters_kod callable kodunun etkilerini
geri almak için callable. Ancak, yazdığımız kod çağrılarının bazıları önemsizdir.
Örneğin, mevcut verileri yeni eklenen bir alanda birleştirirler. Bir ... Yazmak
ters_kod Bu işlevler için callable seçeneği ya imkansız ya da anlamsızdır. Bu
olduğunda, kullanınRunPython.noop olarak ters_kod .

Örneğin “Cone” adında yeni bir model oluşturduğumuzu varsayalım. Mevcut tüm
kepçelerin kendi konilerine ihtiyacı var, bu yüzden bir yazıyoruz.add_cones veri tabanına
koni ekleme işlevi. Ancak, geçişi tersine çevirirken, konileri kaldırmak için kod yazmak
anlamsızdır;göçler.Model Oluştur.database_backwards coni.cone tablosunu ve tüm
kayıtlarını bizim için silecektir. Bu nedenle, kullanmalıyızRunPython.noop için ters_kod :

68 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


6.3: RunPython'un Ortak Engellerini Aşmak

Örnek 6.4: RunPython.noop ile RunPython Ters Çevirme

itibaren django.db içe aktarmak göçler, modeller

tanım add_cones(uygulamalar, schema_editor):


Kepçe = uygulamalar.get_model('kepçe', 'Kepçe') koni =
uygulamalar.get_model('koni', 'Koni')

için kepçe içinde Kepçe.nesneler.herşey():


koni.nesneler.oluşturmak(
kepçe=kepçe,
stil='Şeker'
)

sınıf Göç(göçler.Göç):

ilk = NS

bağımlılıklar =[
('kepçe', '0051_auto_20670724'),
]

operasyonlar = [
göçler.Model Oluştur(
isim='Koni',
alanlar=[
('İD', modeller.AutoField(auto_created=NS,

→ birincil anahtar=NS,
seri hale getirmek=YANLIŞ, ayrıntılı_adı='İD')) ('stil',
modeller.CharField(maks_uzunluk=10),
seçimler=[('Şeker', 'Şeker'), ('gözleme',

→ 'Gözleme')]),
('kepçe', modeller.OneToOneField(boş=NS,

→ ile='kepçe.Kepçe'
on_delete=django.db.modeller.silme.SET_NULL,

→ ) ),
],
),
# RunPython.noop ters geçişlere izin vermekten başka bir şey yapmaz

→ ceryan etmek

göçler.RunPython(add_cones, geçişler.RunPython.hayır)
]

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 69


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 6: En İyi Uygulamaları Modelleyin

6.3.4 Geçişlerin Dağıtımı ve Yönetimi


a Söylemeye gerek yok, ama yine de söyleyeceğiz: Çalıştırmadan önce daima verilerinizi yedekleyin-

göç veriyor.
a Dağıtımdan önce, geçişleri geri alıp alamayacağınızı kontrol edin! her zaman sahip olamayız
mükemmel gidiş-dönüşler, ancak daha önceki bir duruma geri dönememek, hata izlemeyi ve bazen

daha büyük projelerde devreye almayı gerçekten incitir.

a Bir projede milyonlarca satır içeren tablolar varsa verilere karşı kapsamlı testler yapın
bir üretim sunucusunda bir geçiş çalıştırmadan önce hazırlama sunucularında bu boyuttan.
Gerçek veriler üzerindeki geçişler, tahmin edilenden çok, çok, çok daha fazla zaman alabilir.
a MySQL kullanıyorsanız:
a Herhangi bir şema değişikliğinden önce kesinlikle olumlu bir şekilde veritabanını yedeklemelisiniz.

MySQL, şema değişiklikleri etrafında işlem desteğinden yoksundur, bu nedenle geri alma

imkansızdır.

a Yapabiliyorsanız, değişikliği gerçekleştirmeden önce projeyi salt okunur moda getirin.

a Dikkatli olunmazsa, yoğun olarak doldurulmuş tablolardaki şema değişiklikleri uzun zaman alabilir.

Saniyeler veya dakikalar değil, saatler.

Şekil 6.1: Kış için güneye göç eden koniler. Django'nun yerleşik geçiş sistemi, South
adlı harici bir proje olarak başladı.

İPUCU: Veri Taşıma Kodunu Daima Kaynak Kontrolüne Girin

VCS'ye geçiş kodunun dahil edilmesi mutlak bir zorunluluktur. Sürüm kontrolüne geçiş
kodunun dahil edilmemesi, VCS'deki ayar dosyalarının dahil edilmemesine benzer:
Geliştirme yapabilirsiniz, ancak makineleri değiştirirseniz veya projeye başka birini
getirirseniz, her şey bozulur.

6.4 Django Model Tasarımı


En az dikkat çeken en zor konulardan biri, iyi Django modellerinin nasıl
tasarlanacağıdır.

70 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


6.4: Django Model Tasarımı

Erken optimizasyon yapmadan performans için nasıl tasarım yaparsınız? Burada bazı stratejileri
keşfedelim.

6.4.1 Normalleştirilmiş Başlat

Bu kitabın okuyucularının aşina olması gerektiğini öneriyoruz. veritabanı normalleştirme.


Veritabanı normalleştirmeye aşina değilseniz, Django'da modellerle etkin bir şekilde çalışmak bu
konuda bir çalışma bilgisi gerektirdiğinden, bir anlayış kazanmayı kendi sorumluluğunuzda
yapın. Konunun ayrıntılı bir açıklaması bu kitabın kapsamı dışında olduğundan, aşağıdaki
kaynakları öneriyoruz:

a en.wikipedia.org/wiki/Database_normalization en.wikibooks.org/wiki/
a Relational_Database_Design/Normalization

Django modellerinizi tasarlarken, her zaman normalleştirilmiş olarak başlayın. Hiçbir modelin başka bir
modelde depolanmış verileri içermediğinden emin olmak için zaman ayırın.

Bu aşamada ilişki alanlarını özgürce kullanın. Erken denormalize etmeyin. Verilerinizin şekli
hakkında iyi bir fikir sahibi olmak istiyorsunuz.

6.4.2 Denormalize Etmeden Önce Önbellek

Çoğu zaman, önbelleğe almayı doğru yerlerde ayarlamak, modellerinizi denormalize etme zahmetinden

kurtarabilir. Önbelleğe almayı çok daha ayrıntılı olarak şurada ele alacağız:Bölüm 26: Darboğazları Bulma ve

Azaltma, bu yüzden şu anda bunun için çok fazla endişelenme.

6.4.3 Denormalize Sadece Kesinlikle Gerekiyorsa

Özellikle veri normalleştirme kavramlarına yeni başlayanlar için zamanından önce denormalize
etmek cazip gelebilir. yapma! Denormalizasyon, bir projede sorunlara neden olan şey için her
derde deva gibi görünebilir. Ancak, projenize karmaşıklık ekleme riskini taşıyan ve veri kaybetme
riskini önemli ölçüde artıran zor bir süreçtir.

Lütfen, lütfen, lütfen denormalizasyondan önce önbelleğe almayı keşfedin.

Bir proje, aşağıda açıklanan tekniklerin sınırlarına ulaştığında Bölüm 26: Darboğazları
Bulma ve Azaltma ele alabilir, o zaman veritabanı denormalizasyonunun kavramları ve
kalıpları üzerine araştırma başlamalıdır.

6.4.4 Boş ve Boş Ne Zaman Kullanılır

Bir model alanı tanımlarken, null=Doğru ve


boş=Doğru seçenekler. Varsayılan olarak, bunlar False'dır.

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 71


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 6: En İyi Uygulamaları Modelleyin

Bu seçeneklerin ne zaman kullanılacağını bilmek, geliştiriciler için yaygın bir kafa karışıklığı kaynağıdır.

masa koyduk Tablo 6.2: Alana Göre Boş ve Boş Ne Zaman Kullanılır birlikte bu model alan argümanlarının

standart kullanımı için bir rehber olarak hizmet etmek üzere.

Şekil 6.2: Yaygın bir karışıklık kaynağı.

6.4.5 BinaryField Ne Zaman Kullanılır

Bu alan, ham ikili verilerin veya bayt. Sahada filtreler, hariç tutmalar veya diğer SQL eylemleri
gerçekleştiremiyoruz, ancak bunun için kullanım durumları var. Örneğin, şunları saklayabiliriz:

a MessagePack biçimli içerik.


a Ham sensör verileri.
a Sıkıştırılmış veriler, örneğin Sentry'nin bir BLOB olarak sakladığı veri türü, ancak
eski sorunlar nedeniyle base64-encode.

Olasılıklar sonsuzdur, ancak ikili verilerin büyük parçalar halinde gelebileceğini ve veritabanlarını
yavaşlatabileceğini unutmayın. Bu meydana gelir ve bir darboğaz haline gelirse, çözüm ikili
verileri bir dosyaya kaydetmek ve ona birDosya Alanı.

UYARI: BinaryField'den Dosya Sunmayın!

Dosyaları bir veritabanı alanında saklamak asla gerçekleşmemelidir. Bir soruna çözüm
olarak görülüyorsa, sertifikalı bir veritabanı uzmanı bulun ve ikinci bir görüş isteyin.

PostgreSQL uzmanı Frank Wiles'ı bir dosya deposu olarak bir veritabanı kullanmayla ilgili
sorunları özetlemek için:
a 'bir DB'ye okuma/yazma her zaman bir dosya sisteminden daha yavaştır'

72 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


6.4: Django Model Tasarımı

Alan türü null ayarı=Doğru Boş ayar=Doğru


charAlan, Peki sen de ayarladıysan Peki ilgili form widget'ını
Metin alanı, ikisi birden benzersiz=Doğru ve istiyorsanız
SlugField, boş=Doğru. Bu durumda, boş değerleri kabul etmek için
E-posta Alanı, null=Doğru boş değerlerle Bunu ayarlarsanız, boş değerler
Virgülle ayrılmış- birden çok nesneyi şu şekilde depolanır:BOŞ
Tamsayı Alanı, kaydederken benzersiz veritabanında ise null=Doğru
UUIDF Alanı kısıtlama ihlallerini ve benzersiz=Doğru ayrıca
önlemek için gereklidir. Ayarlamak. Aksi takdirde, boş
dizeler olarak saklanırlar.
dosya Alanı, Bunu yapma. Peki.
Resim Alanı Django yolu saklar CharField için aynı model
itibaren MEDIA_ROOT için burada da geçerlidir.
dosyaya veya bir CharField'deki
görüntüye, bu nedenle aynı
model FileFields için de geçerlidir.
Boole Alanı Peki. Varsayılan boş=Doğru.
Tamsayı Alanı, Peki değerini Peki karşılık gelen form pencere
FloatAlan, ayarlayabilmek istiyorsanız öğesinin boş değerleri kabul
OndalıkAlan, BOŞ veritabanında. etmesini istiyorsanız. Eğer öyleyse,
SüreAlan, vesaire ayrıca ayarlamak isteyeceksiniz
boş=Doğru.
TarihSaatAlan, Peki değerini Peki karşılık gelen form
Tarih Alanı, ayarlayabilmek istiyorsanız pencere öğesinin boş değerleri
Zaman Alanı, vesaire. BOŞ veritabanında. kabul etmesini istiyorsanız veya
auto_now veya auto_now_add
kullanıyorsanız. Eğer eskiyse,
sen de isteyeceksin
kurmak boş=Doğru.
Yabancı anahtar, Peki değerini Peki ilgili form widget'ını
OneToOneField ayarlayabilmek istiyorsanız istiyorsanız
BOŞ veritabanında. (örn. seçim kutusu) boş değerleri
kabul etmek için. Eğer öyleyse,
ayrıca ayarlamak isteyeceksiniz
boş=Doğru.
ManyToManyField Null'un etkisi yok Peki karşılık gelen form
pencere öğesinin (örn. seçim
kutusu) boş değerleri kabul
etmesini istiyorsanız.
GenelIPAdresiAlan Peki değerini Peki karşılık gelen alan pencere
ayarlayabilmek istiyorsanız öğesinin boş değerleri kabul
BOŞ veritabanında. etmesini istiyorsanız. Eğer
öyleyse, siz de isteyeceksiniz
Ayarlamak boş=Doğru.

JSONField Peki. Peki.

Tablo 6.2: Alana Göre Boş ve Boş Ne Zaman Kullanılır

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 73


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 6: En İyi Uygulamaları Modelleyin

a 'DB yedeklemeleriniz büyür ve çok daha fazla zaman alır'


a 'dosyalara erişim artık uygulamanızdan (Django) ve DB'den geçmeyi gerektiriyor
katmanlar'

Görmek revsys.com/blog/2012/may/01/ three-things-you-should-never-putyour-


database/

Birisi bir veritabanından dosya sunmak için iyi bir kullanım örneği olduğunu düşündüğünde ve

aşağıdaki gibi bir başarıdan alıntı yaptığında npmjs.org (CouchDB'de saklanan dosyalar),

araştırmanızı yapmanın zamanı geldi. Gerçek şu kinpmjs.org, dosya deposu olarak veritabanı

sistemini yıllar önce daha geleneksel bir dosya sunma yöntemine taşıdı.

6.4.6 Genel İlişkiler Kullanmaktan Kaçınmaya Çalışın

İçinde Genel Biz savunucu karşısında Genel ilişkiler ve kullanmak ile ilgili

modeller.field.GenericForeignKey. Genellikle değerlerinden daha fazla sorun çıkarırlar.


Bunları kullanmak genellikle zahmetli kestirme yolların kullanıldığının, yanlış çözümün
araştırıldığının bir işaretidir.

Genel ilişkiler fikri, bir tabloyu diğerine kısıtlanmamış bir yabancı anahtar aracılığıyla bağlamamızdır (
GenelYabancıAnahtar). Bunu kullanmak, gerçekten yabancı anahtar kısıtlamaları kullanabilecek projeler

için temel olarak yabancı anahtar kısıtlamaları olmayan bir NoSQL veri deposu kullanmaya benzer. Bu,
aşağıdakilere neden olur:

a Modeller arasında indeksleme eksikliği nedeniyle sorguların hızında azalma.


a Bir tablo olarak veri bozulması tehlikesi, var olmayan bir kayda karşı başka bir tabloya başvurabilir.

Bu kısıtlama eksikliğinin iyi tarafı, genel ilişkilerin, yaratmış olabileceğimiz çok sayıda model türüyle
etkileşime girmesi gereken şeyler için uygulamalar oluşturmayı kolaylaştırmasıdır. Özellikle favoriler,
derecelendirmeler, oylama, mesajlar ve etiketleme uygulamaları gibi şeyler. Gerçekten de, bu şekilde
oluşturulmuş bir dizi mevcut uygulama var. Bunları kullanmakta tereddüt etsek de, iyi olanların tek bir
göreve (örneğin etiketleme) odaklanması bizi teselli ediyor.

Zamanla, sık kullanılanlar, derecelendirmeler, oylamalar, mesajlar ve yerleşik etiketleme uygulamaları


oluşturabileceğimizi gördük. Yabancı anahtar ve ManyToMany alan. Biraz daha geliştirme çalışması için,
kullanımından kaçınarakGenelYabancıAnahtar hız ve bütünlükten faydalanırız.

Nerede GenelYabancıAnahtar Gerçekten zahmetli hale gelmesi, kısıtlanmamış özelliğinin


bir projenin birincil verilerinin tanımlandığı yöntem haline gelmesidir. Örneğin, soslar,
tatlar arasındaki ilişkilerin olduğu Dondurma temalı bir proje yaparsak,

74 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


6.4: Django Model Tasarımı

Konteynerler, siparişler ve satışların tümü GenelYabancıAnahtar, yukarıdaki madde


işaretlerinde açıklanan sorunları yaşardık. Kısacası:

a Genel ilişkilerden kaçınmaya çalışın ve GenelYabancıAnahtar.


a Genel ilişkilere ihtiyacınız olduğunu düşünüyorsanız, sorunun daha iyi çözülüp çözülemeyeceğine bakın.

model tasarımı veya yeni PostgreSQL alanları.


a Kullanımdan kaçınılamazsa, mevcut bir üçüncü taraf uygulamasını kullanmayı deneyin. İzolasyon üçüncü bir

parti uygulaması, verileri daha temiz tutmaya yardımcı olur.

Fikrimizi paylaşan başka bir görüş için lütfen okuyunuz. lukeplant.me.uk/blog/posts/


önlemek-Django-genericforeignkey

6.4.7 Seçimler ve Alt Seçimler Yapın Model Sabitleri


Güzel bir model, tuple'larla tanımlanmış bir yapı olarak bir modele özellikler olarak seçenekler
eklemektir. Bunlar modelinize (ve temsil edilen verilere) bağlı sabitler olduğundan, bunlara her
yerden kolayca erişebilmek geliştirmeyi kolaylaştırır.

Bu teknik şurada açıklanmıştır: docs.djangoproject.com/en/3.2/ref/models/fields/


#django.db.models.Field.choices. Bunu bir dondurmaya çevirirsek-
tabanlı örnek, şunu elde ederiz:

Örnek 6.5: Seçim Modeli Niteliklerini Ayarlama

# siparişler/modeller.py
itibaren django.db içe aktarmak modeller

sınıf DondurmaSiparişi(modeller.modeli):
LEZZET_ÇİKOLATA = 'ç'
FLAVOR_VANILLA = 'vn'
LEZZET_ÇİLEK = 'NS'
FLAVOR_CHUNKY_MUNKY = 'santimetre'

LEZZET_SEÇİMLERİ = (
(LOZ_ÇİKOLATA, 'Çikolata'), (FLAVOR_VANILLA,
'Vanilya'), (LEZİ_ÇİLEK, 'Çilek'),
(FLAVOR_CHUNKY_MUNKY, 'Tıknaz Mıknatıs')

lezzet = modeller.Karakter Alanı(


maksimum uzunluk=2,

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 75


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 6: En İyi Uygulamaları Modelleyin

seçimler=LEZZET_CHOICES
)

Bu modeli kullanarak şunları yapabiliriz:

Örnek 6.6: Seçim Modeli Niteliklerine Erişme

>>> itibaren siparişler.modeller içe aktarmak DondurmaSiparişi

>>>


→ DondurmaSiparişi.nesneler.filtre (tat=DondurmaSiparişi.LEZZET_ÇİKOLATA) [<dondurma
siparişi: 35>, <dondurma siparişi: 42>, <dondurma siparişi: 49>]

Bu, hem Python kodunda hem de şablonlarda çalışır ve özniteliğe, sınıftan veya
örneklenmiş model nesnesinden erişilebilir.

6.4.8 Seçimler için Numaralandırma Türlerini Kullanma

Nate Cox, seçimler için Django'nun numaralandırma türlerinin kullanılmasını önerir. 3.0 sürümünden itibaren

Django'ya entegre edilmiştir, kullanımı daha da kolaydır.

Örnek 6.7: Seçim Modeli Niteliklerini Ayarlama

itibaren django.db içe aktarmak modeller

sınıf DondurmaSiparişi(modeller.modeli):
sınıf tatlar(modeller.MetinSeçenekleri):
ÇİKOLATA = 'ç', 'Çikolata'VANİLYA = 'vn', 'Vanilya'
ÇİLEK = 'NS', 'Çilek'CHUNKY_MUNKY =
'santimetre', 'Tıknaz Mıknatıs'

lezzet = modeller.Karakter Alanı(


maksimum uzunluk=2,

seçimler=tatlar.seçimler
)

Bu kodu kullanarak şunları yapabiliriz:

76 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


6.5: Model _meta API

Örnek 6.8: Numaralandırma Tabanlı Seçim Modeli Niteliklerine Erişme

>>> itibaren siparişler.modeller içe aktarmak DondurmaSiparişi

>>>


→ DondurmaSiparişi.nesneler.filtre (tat=DondurmaSiparişi.tatlar.ÇİKOLATA) [<dondurma
siparişi: 35>, <dondurma siparişi: 42>, <dondurma siparişi: 49>]

Önceki yönteme göre numaralandırma türlerini kullanmanın birkaç dezavantajı vardır. özellikle:

a Adlandırılmış gruplar, numaralandırma türleriyle mümkün değildir. Bunun anlamı, eğer


seçimlerimizin içinde kategoriler olmasını istiyorsak, daha eski demet tabanlı yaklaşımı kullanmamız

gerekecek.

a Bunun dışında başka türler istiyorsak cadde ve int, bunları kendimiz tanımlamalıyız.

Seçim alanları için numaralandırma türleri, hoş bir API sağlar. Bunları kullanmak için mükemmel bir
yaklaşım bulduk, yukarıda listelenen dezavantajlarla karşılaşana kadar onlara bağlı kalmak. Daha
sonra eski tuple tabanlı yönteme geçiyoruz.

6.4.9 PostgreSQL'e Özgü Alanlar: Ne Zaman Boş ve Boş Kullanılır


Alan türü null ayarı=Doğru Boş ayar=Doğru
Dizi Alanı Peki. Peki.
HStoreField Peki. Peki.
TamsayıAralık Alanı, Peki değerini Peki karşılık gelen form pencere
BigIntegerRangeField, ayarlayabilmek istiyorsanız öğesinin boş değerleri kabul
ve FloatRangeField BOŞ veritabanında. etmesini istiyorsanız. Eğer öyleyse,
ayrıca ayarlamak isteyeceksiniz
boş=Doğru.
DatetimeRangeField Peki değerini Peki karşılık gelen form
ve DateRangeField ayarlayabilmek istiyorsanız pencere öğesinin boş değerleri
BOŞ veritabanında. kabul etmesini istiyorsanız veya
auto_now veya auto_now_add
kullanıyorsanız. Eğer öyleyse,
ayrıca ayarlamak isteyeceksiniz
boş=Doğru.

Tablo 6.3: Postgres Alanları için Ne Zaman Boş ve Boş Kullanılır

6.5 Model _meta API


Bu _meta API, aşağıdaki açılardan olağandışıdır:

a “_” ön ekine sahiptir, ancak genel, belgelenmiş bir API'dir.

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 77


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 6: En İyi Uygulamaları Modelleyin

a Django'nun diğer _-önekli bileşenlerinden farklı olarak _meta aynı kullanımdan kaldırmayı takip eder

çerçevenin geri kalanı olarak desenler.

Bunun nedeni, Django 1.8'den önceki modelin _meta API, bildirimde bulunmaksızın değiştirilebilir
herhangi bir API'de normal olduğu gibi gayri resmiydi ve kasıtlı olarak belgelenmedi. _'nin asıl amacı
meta Django'nun kendi kullanımı için modeller hakkında fazladan bilgi depolamasıydı. Ancak, o kadar

kullanışlı olduğunu kanıtladı ki artık belgelenmiş bir API oldu.

Çoğu proje için _meta. Bunun ana kullanımları, ihtiyacınız olduğunda:

a Bir modelin alanlarının listesini alın.

a Bir model için belirli bir alanın sınıfını (veya miras zincirini veya diğer bilgileri) alın
türetilmiştir).
a Bu bilgiyi nasıl edindiğinizin gelecekteki Django sürümlerinde sabit kaldığından emin olun.
iyonlar.

Bu tür durumlara örnekler:

a Bir Django modeli iç gözlem aracı oluşturma.


a Kendi özel özelleştirilmiş Django form kitaplığınızı oluşturma.
a Django model verilerini düzenlemek veya bunlarla etkileşim kurmak için yönetici benzeri araçlar oluşturma.

a Görselleştirme veya analiz kitaplıkları yazma, ör. yalnızca alanlarla ilgili bilgileri analiz etme
"foo" ile başlayın.

Daha fazla okuma:

a modeli _meta belgeler: docs.djangoproject.com/en/3.2/ref/models/meta/

6.6 Model Yöneticileri


Bir modeli sorgulamak için Django ORM'yi her kullandığımızda,model yöneticisi veritabanı ile
etkileşime geçmek için. Model yöneticilerinin, birlikte çalışmak istediklerinizi kısıtlamak için bu
model sınıfının tüm olası örneklerinin (tablodaki tüm verilerin) tam kümesi üzerinde hareket
ettiği söylenir. Django, her model sınıfı için varsayılan bir model yöneticisi sağlar, ancak
kendimizinkini tanımlayabiliriz.

İşte özel bir model yöneticisinin basit bir örneği:

Örnek 6.9: Özel Model Yöneticisi: yayınlandı

itibaren django.db içe aktarmak modelleritibaren

django.utils içe aktarmak saat dilimi

78 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


6.6: Model Yöneticileri

sınıf YayınlananYönetici(modeller.Yönetici):

tanım yayınlanan(öz, **kwarglar):


dönüş öz.filtre(pub_date__lte=saat dilimi.şimdi(), **kwarglar)

sınıf Lezzetİnceleme(modeller.modeli):
gözden geçirmek = modeller.CharField(maks_uzunluk=255)=
pub_date modeller.TarihSaatAlan()

# özel model yöneticimizi ekleyinnesneler


= PublishedManager()

Şimdi, önce tüm dondurma aroması incelemelerinin bir sayısını ve ardından sadece yayınlananların bir
sayısını görüntülemek istiyorsak, aşağıdakileri yapabiliriz:

Örnek 6.10: Özel Model Yöneticisi: yayınlandı

>>> itibaren incelemeler.modeller içe aktarmak Lezzetİnceleme

> > > Lezzetİnceleme.nesneler.saymak()35

> > > Lezzetİnceleme.nesneler.yayınlanan().saymak()31

Kolay değil mi? Yine de ikinci bir model yöneticisi ekleseniz daha mantıklı olmaz mıydı? Bu
şekilde şöyle bir şeye sahip olabilirsiniz:

Örnek 6.11: İki Model Yöneticisi Kullanmanın Hayali Faydaları

> > > itibaren incelemeler.modeller içe aktarmak Lezzetİnceleme


> > > FlavorReview.objects.filter().count()35

> > > FlavorReview.published.filter().count()31

Yüzeyde, varsayılan model yöneticisini değiştirmek akıllıca bir şey gibi görünüyor. Ne yazık ki,
gerçek proje geliştirme konusundaki deneyimlerimiz bu yöntemi kullanırken bizi çok dikkatli
yapıyor. Niye ya?

Öncelikle, model mirasını kullanırken, soyut temel sınıfların çocukları ebeveynlerinin


model yöneticisi ve somut temel sınıfların çocukları yoktur.

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 79


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 6: En İyi Uygulamaları Modelleyin

İkinci, bir model sınıfına uygulanan ilk yönetici, Django'nun


varsayılan. Bu, normal Python modeliyle önemli ölçüde bozulur ve QuerySets'ten
öngörülemeyen sonuçlar gibi görünen sonuçlara neden olur.

Bu bilgiyi akılda tutarak, model sınıfınızda, nesneler = modeller.Yönetici()


herhangi bir özel model yöneticisinin üzerinde manuel olarak tanımlanmalıdır.

UYARI: Model Yöneticisi İşlem Sırasını öğrenin

Her zaman ayarla nesneler = modeller.Yönetici() yeni bir ada sahip herhangi bir özel
model yöneticisinin üstünde. Bu kural çiğnenebilir olsa da, çoğu proje için
önermediğimiz gelişmiş bir tekniktir.

Ek okuma: docs.djangoproject.com/en/3.2/topics/db/managers/

6.7 Yağ Modellerini Anlamak


kavramı şişman modeller veriyle ilgili kodu görünümlere ve şablonlara koymak yerine, mantığı model
yöntemlerinde, sınıf yöntemlerinde, özelliklerde, hatta yönetici yöntemlerinde kapsüllememizdir. Bu
şekilde, herhangi bir görünüm veya görev aynı mantığı kullanabilir. Örneğin, Dondurma incelemelerini
temsil eden bir modelimiz varsa, ona aşağıdaki yöntemleri ekleyebiliriz:

a Review.create_review(cls, kullanıcı, derecelendirme, başlık, açıklama) A


sınıf yöntemi yorumlar oluşturmak için. Model sınıfının kendisi, HTML ve REST görünümlerinden

ve ayrıca elektronik tabloları kabul eden bir içe aktarma aracından çağrılır.
a İnceleme.product_average İnceleneni döndüren bir inceleme örneği özelliği
ürünün ortalama puanı. Okuyucunun sayfadan ayrılmadan genel görüş hakkında bir fikir edinebilmesi

için ayrıntılı inceleme görünümlerinde kullanılır.

a Review.found_useful(kendi, kullanıcı, evet) olup olmadığını belirleyen bir yöntem.


okuyucular incelemeyi yararlı buldu veya bulmadı. Hem HTML hem de REST uygulamaları için ayrıntılı

ve liste görünümlerinde kullanılır.

Bu listeden de anlaşılacağı gibi, şişman modeller, bir projede kodun yeniden kullanımını
iyileştirmenin harika bir yoludur. Aslında, mantığı görünümlerden ve şablonlardan modellere
taşıma pratiği, projeler, çerçeveler ve diller arasında yıllardır büyüyor. Bu iyi bir şey, değil mi?

Şart değil.

Tüm mantığı modellere yerleştirmekle ilgili sorun, modellerin kod boyutunda patlamasına ve ' olarak

adlandırılan hale gelmesine neden olabilmesidir.tanrı nesnesi'. Bu anti-kalıp, şu model sınıflarıyla sonuçlanır:

80 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


6.8: Ek Kaynaklar

yüzlerce, binlerce, hatta on binlerce kod satırıdır. Boyutları ve karmaşıklıkları nedeniyle


tanrı nesnelerini anlamak zordur, bu nedenle test edilmesi ve bakımı zordur.

Mantığı modellere taşırken, nesne yönelimli programlamanın temel fikirlerinden birini


hatırlamaya çalışırız, bu büyük problemlerin daha küçük problemlere bölündüğünde çözülmesi
daha kolaydır. Bir model boyut olarak hantal hale gelmeye başlarsa, diğer modeller arasında
yeniden kullanım için öncelikli olan veya karmaşıklığı daha iyi yönetim gerektiren kodu ayırmaya
başlarız. Yöntemler, sınıf yöntemleri ve özellikler korunur, ancak içerdikleri mantık,Model
Davranışları veya Durum Bilgisiz Yardımcı İşlevler. Her iki tekniği de aşağıdaki alt bölümlerde ele
alalım:

6.7.1 Model Davranışları, diğer adıyla Mixins

Model davranışlar, karışımların kullanımı yoluyla kompozisyon ve kapsülleme fikrini benimser.


Modeller, mantığı soyut modellerden miras alır. Daha fazla bilgi için aşağıdaki kaynaklara bakın:

a blog.kevinastone.com/django-model-behaviors.html Kevin Stone'un eseri


kodun kopyalanmasını azaltmak için kompozisyonu kullanmaya devam edin.

a Bölüm 10.2: Karışımların CBV'lerle Kullanılması.

6.7.2 Durum Bilgisiz Yardımcı İşlevler

Mantığı modellerden ve faydalı fonksiyonlara taşıyarak daha izole hale gelir. Bu izolasyon,
mantık için testler yazmayı kolaylaştırır. Dezavantajı, işlevlerin durumsuz olmasıdır, bu
nedenle tüm argümanların iletilmesi gerekir.

Biz bunu kapsarız Bölüm 31: Ya Rastgele Yardımcı Programlar?

6.7.3 Model Davranışları ve Yardımcı İşlevler

Bize göre, bu tekniklerin hiçbiri tek başına mükemmel değildir. Ancak her ikisi de akıllıca
kullanıldığında projelerin parlamasını sağlayabilir. Her ikisinin de ne zaman kullanılacağını anlamak
statik bir bilim değil, gelişen bir süreçtir. Bu tür bir evrim yanıltıcıdır ve bizim önerimizi yağ
modellerinin bileşenleri için testler yaptırmamıza neden olur.

6.8 Ek Kaynaklar
İşte bu bölümde örneklediklerimizi temel alan birkaç makale:

a hakibenita.com/bullet-proofing-django-models - Haki Benita'nın mükemmel


Django modellerine çok ciddi kurallar uygulama hakkında makale. Tüm blogu
mükemmel bilgilerle dolu.

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 81


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 6: En İyi Uygulamaları Modelleyin

a- Andrew Brooks'un Django'nun ORM'sine yaptığı derin dalış herkes için okumaya değer
model tasarımının performansıyla ilgilenirler. Spellbookpress.com/
kitaplar/tapınak-django-veritabanı-performans/

6.9 Özet
Modeller çoğu Django projesinin temelidir, bu yüzden onları dikkatlice tasarlamak için
zaman ayırın.

Normalleştirmeye başlayın ve yalnızca diğer seçenekleri iyice araştırdıysanız


normalleştirmeyi kaldırın. Ham SQL'e geçerek yavaş, karmaşık sorguları basitleştirebilir
veya performans sorunlarınızı doğru yerlerde önbelleğe alma ile çözebilirsiniz.

Model mirasını kullanmaya karar verirseniz, somut modeller yerine soyut temel sınıflardan miras alın.
Kendinizi örtük, gereksiz birleştirmelerle uğraşmanın karmaşasından kurtaracaksınız.

Kullanırken “gotchas” a dikkat edin. null=Doğru ve boş=Doğru model alanı seçenekleri.


Rehberlik için kullanışlı tablomuza bakın.

Django-model-utils ve Django-extensions'ı oldukça kullanışlı bulabilirsiniz.

Son olarak, şişman modeller, modellerde mantığı kapsüllemenin bir yoludur, ancak hepsi çok kolay bir şekilde tanrı nesnelerine

dönüşebilir.

Bir sonraki bölümümüz, sorgular ve veritabanı katmanı hakkında konuşmaya başlayacağımız yerdir.

82 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


7 | Sorgular ve Veritabanı Katmanı

Yazdığımız sorguların çoğu basittir. Django'nunNesne-İlişkisel Model veya ORM harika bir
üretkenlik kısayolu sağlar: yalnızca yaygın kullanım durumları için uygun SQL sorguları
oluşturmakla kalmaz, aynı zamanda doğrulama ve güvenlikle birlikte gelen model erişimi/
güncelleme işlevselliği sağlar. Farklı veritabanı motorlarıyla çalışan önemsiz bir şekilde kod
yazmamızı sağlar. ORM'lerin bu özelliği, Django üçüncü taraf paket ekosisteminin çoğuna güç
sağlar. ORM ile sorgunuzu kolayca yazabiliyorsanız, bundan yararlanın!

Django ORM, herhangi bir ORM gibi, farklı türlerdeki verileri desteklenen veritabanlarında oldukça
tutarlı bir şekilde kullanabileceğimiz nesnelere dönüştürür. Ardından, bu nesnelerle etkileşim için bir
dizi yöntem sağlar. Çoğunlukla, Django yapmak için tasarlandığı şeyde oldukça iyi bir iş çıkarıyor.
Ancak, tuhaflıkları vardır ve bu tuhaflıkları anlamak, Django'nun nasıl kullanılacağını öğrenmenin bir
parçasıdır. Bazılarının üzerinden geçelim, olur mu?

7.1 Tek Nesneler için get_object_or_404() kullanın


Tek bir nesneyi almak ve bir şeyler yapmak istediğiniz detay sayfaları gibi görünümlerde
onunla, kullan get_object_or_404() onun yerine elde etmek().

UYARI: get_object_or_404() Yalnızca Görüntülemeler İçindir

a Yalnızca görünümlerde kullanın.

a Yardımcı işlevlerde, formlarda, model yöntemlerinde veya herhangi bir şeyde kullanmayın.

bir görünüm veya doğrudan görünümle ilgili değil.

Yıllar önce, Daniel adında belirli bir Python kodlayıcısı ve yazarı ilk Django
projesini dağıtıyordu. O kadar büyülenmişti ki Django'nunget_object_or_404()
her yerde, görünümlerde, modellerde, formlarda, her yerde kullandığı işlevi.
Geliştirmede bu harika çalıştı ve testleri geçti. Ne yazık ki, bu kısıtlamasız kullanım,
yönetici personel tarafından belirli kayıtlar silindiğinde tüm sitenin bozulması anlamına
geliyordu.

Kale get_object_or_404() senin görüşlerinde!

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 83


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 7: Sorgular ve Veritabanı Katmanı

7.2 İstisnalar Oluşturabilecek Sorgulara


Dikkat Edin
İle tek bir Django model örneği aldığınızda get_object_or_404()
kısayol, bir try-except bloğuna sarmanız gerekmez. O yüzden
get_object_or_404() bunu zaten sizin için yapıyor.

Ancak, diğer birçok durumda bir try-except bloğu kullanmanız gerekir. Bazı ipuçları:

7.2.1 ObjectDoesNotExist ve DoesNotExist karşılaştırması

Nesne Yok Yok herhangi bir model nesnesine uygulanabilir, oysa Bulunmuyor belirli bir
model içindir.

Örnek 7.1: ObjectDoesNotExist için Örnek Kullanım

itibaren django.core.istisnalar içe aktarmak Nesne Yok Yok

itibaren tatlar.modeller içe aktarmak Lezzetitibaren

mağaza.istisnalar içe aktarmak Stoklar tükendi

tanım list_flavor_line_item(sku):
denemek:

dönüş Lezzet.nesneler.get(sku=sku, miktar__gt=0)hariç Lezzet.


Bulunmuyor:
mesaj = 'Biz bittik {0}'.biçim(sku)artırmak Stok
Dışı(mesaj)

tanım list_any_line_item(model, sku):


denemek:

dönüş model.nesneler.get(sku=sku, miktar__gt=0)hariç


ObjectDoesNotExist:
mesaj = 'Biz bittik {0}'.biçim(sku)artırmak Stok
Dışı(mesaj)

7.2.2 Sadece Bir Nesne İsteyip Üçünü Geri Aldığınızda

Sorgunuzun birden fazla nesne döndürmesi mümkünse,


ÇokluNesne Döndürüldü istisna. Ardından, istisna yan tümcesinde, mantıklı olan her şeyi yapabilirsiniz,

örneğin özel bir istisna oluştur veya hatayı günlüğe kaydet.

84 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


7.3: Sorguları Okunabilir Hale Getirmek için Tembel Değerlendirmeyi Kullanın

Örnek 7.2: MultipleObjectsReturned'in Örnek Kullanımı

itibaren tatlar.modeller içe aktarmak Lezzet


itibaren mağaza.istisnalar içe aktarmak Stok Dışı, BozukVeritabanı

tanım list_flavor_line_item(sku):
denemek:

dönüş Lezzet.nesneler.get(sku=sku, miktar__gt=0)hariç Lezzet.


Bulunmuyor:
mesaj = 'Biz bittik {}'.biçim(sku)artırmak Stok
Dışı(mesaj)
hariç Lezzet.Birden Çok Nesne Döndürüldü:
mesaj = 'Birden çok öğenin SKU'su var {}. Lütfen düzelt!'.biçim(sku)artırmak
BozukVeritabanı(mesaj)

7.3 Sorguları Okunabilir Hale Getirmek için Tembel Değerlendirmeyi Kullanın


Django'nun ORM'si çok güçlüdür. Ve böyle bir güçle birlikte kodu okunaklı, dolayısıyla
sürdürülebilir hale getirme sorumluluğu gelir. Karmaşık sorgularda, küçük bir satır kümesinde
çok fazla işlevi zincirlemekten kaçınmaya çalışın:

Örnek 7.3: Okunamayan Sorgular

# Bunu yapma!
itibaren django.db.modelleri içe aktarmak Q

itibaren promosyonlar.modeller içe aktarmak promosyon

tanım eğlence_fonksiyonu(isim=Hiçbiri):

"""Çalışan dondurma promosyonunu bul"""


→ # Çok fazla sorgu zinciri, kodun ekrandan veya sayfadan çıkmasına neden olur. İyi değil.
dönüş

→ Promo.objects.active().filter(Q(name__startswith=name)|Q(description__icontains

Bu hoş değil, değil mi? Yine de gelişmiş Django ORM araçlarını eklersek, o zaman tatsızdan
sriracha bazlı bir dondurma kadar korkunç hale gelir. Bu tatsızlığı azaltmak için, ORM
kodumuzu temiz tutmak için Django sorgularının tembel değerlendirme özelliğini
kullanabiliriz.

Tembel değerlendirme ile, Django ORM'nin verilere gerçekten ihtiyaç duyulana kadar SQL çağrıları
yapmadığını kastediyoruz. ORM metodlarını ve fonksiyonlarını istediğimiz kadar zincirleyebiliriz,

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 85


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 7: Sorgular ve Veritabanı Katmanı

ve biz sonuç arasında dolaşmaya çalışana kadar Django veritabanına dokunmaz. Birçok
yöntemi ve gelişmiş veritabanı özelliklerini tek bir satırda zincirlemek zorunda kalmak
yerine, bunları gerektiği kadar satıra bölebiliriz. Bu, okunabilirliği artırır, bu da bakım
kolaylığını artırır, bu da dondurma alma süresini artırır.

Buradan kodu alıyoruz kötü örnek 7.3 ve daha okunaklı bir koda bölün:

Örnek 7.4: Okunabilir Sorgular

# Bunu yap!
itibaren django.db.modelleri içe aktarmak Q

itibaren promosyonlar.modeller içe aktarmak promosyon

tanım eğlence_fonksiyonu(isim=Hiçbiri):

"""Çalışan dondurma promosyonunu bul"""


Sonuçlar = promosyon.nesneler.aktif()=
Sonuçlar Sonuçlar.filtre(
Q(name__startwith=isim) |
Q(açıklama__icontains=isim)
)
Sonuçlar = Sonuçlar.hariç tut(durum='erimiş')= Sonuçlar.
Sonuçlar seçici_ilgili('tatlar') Sonuçlar
dönüş

Düzeltilmiş kodda da görüldüğü gibi, sonucun ne olacağını daha kolay söyleyebiliriz. Daha
da iyisi, sorgu ifadesini bölerek belirli kod satırları hakkında yorum yapabiliriz.

7.3.1 Okunabilirlik için Sorguları Zincirleme

Bu teknik, Pandalar ve JavaScript topluluklarından ödünç alınmıştır. Tembel değerlendirme kullanmak yerine

sorguları şu şekilde zincirlemek mümkündür:

Örnek 7.5: Zincirleme Sorguları

# Bunu yap!
itibaren django.db.modelleri içe aktarmak Q

itibaren promosyonlar.modeller içe aktarmak promosyon

tanım eğlence_fonksiyonu(isim=Hiçbiri):

"""Çalışan dondurma promosyonunu bul"""

86 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


7.4: Gelişmiş Sorgu Araçlarından Yararlanın

qs = (promosyon

. nesneler
. aktif()
. filtre(
Q(name__startwith=isim) |
Q(açıklama__icontains=isim)
)
. hariç tut(durum='erimiş')
. seçici_ilgili('tatlar')
)
dönüş qs

Bu yaklaşımın dezavantajı, hata ayıklamanın, bir sorgu yazmanın tembel değerlendirme yöntemini kullanmak kadar

kolay olmamasıdır. Biz sadece bir tane yapıştıramayızPDB veya IPDB bu şekilde tanımlanmış bir sorgunun ortasında

çağrı yapın.

Bunu aşmak için biraz yorum yapmalıyız:

Örnek 7.6: Zincirleme Sorgularla Hata Ayıklama

tanım eğlence_fonksiyonu(isim=Hiçbiri):

"""Çalışan dondurma promosyonunu bul"""qs


=(
promosyon

. nesneler
. aktif()
# . filtre(
# S(isim__startswith=isim) |
# S(açıklama__icontains=ad)
#)
# . hariç tut(durum='erimiş')
# . select_ Related('tatlar')
)
kesme noktası()
dönüş qs

7.4 Gelişmiş Sorgu Araçlarından Yararlanın


Django'nun ORM'si öğrenmesi kolay, sezgiseldir ve birçok kullanım durumunu kapsar. Yine
de iyi yapmadığı birkaç şey var. O zaman olan şey, sorgu kümesi döndürüldükten sonra
Python'da daha fazla veri işlemeye başlarız. Bu bir utanç, çünkü her veritabanı

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 87


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 7: Sorgular ve Veritabanı Katmanı

verileri Python'dan (veya Ruby, JavaScript, Go, Java ve diğerleri) daha hızlı yönetir ve dönüştürür.

Verileri Python ile yönetmek yerine, kaldırmayı yapmak için her zaman Django'nun gelişmiş sorgulama araçlarını

kullanmaya çalışıyoruz. Bunu yaparken yalnızca artırılmış performanstan faydalanmakla kalmıyoruz, aynı zamanda

oluşturduğumuz Python tabanlı geçici çözümlerden daha kanıtlanmış (Django ve çoğu veri tabanı sürekli test ediliyor)

kodu kullanmaktan keyif alıyoruz.

7.4.1 Sorgu İfadeleri


Bir veritabanında okuma gerçekleştirirken, bu okuma sırasında değerler veya hesaplamalar
oluşturmak için sorgu ifadeleri kullanılabilir. Bu kafa karıştırıcı geliyorsa, yalnız hissetme, bizim de
kafamız karıştı. Bir kod örneği bin kelimeye bedel olduğu için bize nasıl fayda sağlayabileceklerine dair
bir örnek verelim. Bizim durumumuzda, bir dondurma mağazasını ziyaret başına ortalama olarak
birden fazla kaşık sipariş eden tüm müşterileri listelemeye çalışıyoruz.

İlk olarak, sorgu ifadeleri olmadan tehlikeli de olsa bunun nasıl yapılabileceği:

Örnek 7.7: Sorgu İfadesi Yok

# Bunu yapma!
itibaren modeller.müşteriler içe aktarmak Müşteri

müşteriler = []
için Customer.objects.iterator() içindeki müşteri:
Eğer client.scoops_ordered > customer.store_visits:
müşteriler.append(müşteri)

Bu örnek bizi korkudan titretiyor. Niye ya?

a Veritabanındaki tüm Müşteri kayıtlarını tek tek dolaşmak için Python'u kullanır.
Bu yavaş ve bellek tüketiyor.
a Herhangi bir kullanım hacmi altında, yarış koşulları yaratacaktır. Bu, biz olduğumuzda ortaya çıkar

müşteriler verilerle etkileşime girerken komut dosyasını çalıştırmak. Bu basit 'OKU' örneğinde
muhtemelen bir sorun olmasa da, gerçek dünya kodunda bunu bir 'GÜNCELLEME' ile
birleştirmek veri kaybına neden olabilir.

Neyse ki, sorgu ifadeleri aracılığıyla Django, bunu daha verimli ve yarış koşulundan bağımsız hale
getirmenin bir yolunu sunar:

88 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


7.4: Gelişmiş Sorgu Araçlarından Yararlanın

Örnek 7.8: Evet Sorgu İfadeleri

itibaren django.db.modelleri içe aktarmak F

itibaren modeller.müşteriler içe aktarmak Müşteri

müşteriler =

→ Müşteri.nesneler.filtre(scoops_ordered__gt=F('mağaza_ziyaretleri'))

Bunun yaptığı, karşılaştırmayı gerçekleştirmek için veritabanının kendisini kullanmaktır. Kaputun altında,

Django muhtemelen şuna benzeyen bir şey çalıştırıyor:

Örnek 7.9: SQL Olarak İşlenen Sorgu İfadesi

SEÇME * itibaren müşteriler_müşteri nerede scoops_ordered >



→ mağaza ziyaretleri

Sorgu İfadeleri araç setinizde olmalıdır. Projelerin performansını ve istikrarını


arttırırlar.

a docs.djangoproject.com/en/3.2/ref/models/expressions/

7.4.2 Veritabanı İşlevleri

Django 1.8'den beri yaygın veritabanı fonksiyonlarını kolaylıkla kullanabiliyoruz.


olarak UPPER(), LOWER(), COALESCE(), CONCAT(), UZUNLUK() ve SUBSTR(). İle ilgili
Django tarafından sağlanan tüm gelişmiş sorgulama araçları, bunlar bizim favorilerimiz. Niye ya?

1 Yeni projelerde veya mevcut projelerde kullanımı çok kolaydır.


2 Veritabanı işlevleri, mantığın bir kısmını Python'dan veritabanına taşımamıza izin verir.
Python'da veri işlemek, bir veritabanında veri işlemek kadar hızlı olmadığından, bu bir
performans artırıcı olabilir.
3 Veritabanı işlevleri, veritabanı başına farklı şekilde uygulanır, ancak Django'nun ORM'si bunu
soyutlar. PostgreSQL üzerinde bunları kullanarak yazdığımız kod MySQL veya SQLite3 üzerinde
çalışacaktır.
4 Bunlar ayrıca sorgu ifadeleridir, yani Django ORM'nin başka bir güzel parçası tarafından
zaten oluşturulmuş ortak bir kalıbı takip ederler.

Referans:

a docs.djangoproject.com/en/3.2/ref/models/database-functions/

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 89


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 7: Sorgular ve Veritabanı Katmanı

7.5 Gerekmedikçe Ham SQL'e Düşmeyin


Ne zaman ham SQL yazsak, güvenlik ve yeniden kullanılabilirlik unsurlarını kaybederiz. Bu sadece
dahili proje kodu için değil, aynı zamanda Django dünyasının geri kalanı için de geçerlidir. Özellikle,
Django uygulamalarınızdan birini üçüncü taraf paketi olarak yayınlarsanız, ham SQL kullanmak işin
taşınabilirliğini azaltacaktır. Ayrıca, verilerin bir veritabanından diğerine taşınması gerektiği gibi nadir
durumlarda, SQL sorgularınızda kullandığınız veritabanına özgü tüm özellikler, taşıma işlemini
zorlaştıracaktır.

Peki ne zaman ham SQL yazmalısınız? Sorgunuzu ham SQL olarak ifade etmek Python kodunuzu
veya ORM tarafından oluşturulan SQL'i büyük ölçüde basitleştirecekse, devam edin ve yapın.
Örneğin, her biri büyük bir veri kümesi üzerinde çalışan bir dizi QuerySet işlemini
zincirliyorsanız, onu ham SQL olarak yazmanın daha verimli bir yolu olabilir.

İPUCU: Malcolm Tredinnick'in Django'da SQL Yazma Tavsiyesi

Django çekirdek geliştiricisi Malcolm Tredinnick şunları söyledi:


"ORM birçok harika şey yapabilir, ancak bazen SQL doğru cevaptır.
Django ORM'nin kaba politikası, işlevselliği uygulamak için SQL
kullanan bir depolama katmanı olmasıdır. Gelişmiş SQL yazmanız
gerekiyorsa, yazmalısınız. Aşırı kullanımına karşı uyararak bunu
dengelerdim.çiğ() ve ekstra() yöntemler.”

İPUCU: Jacob Kaplan-Moss'un Django'da SQL Yazma Tavsiyesi

Django proje eş lideri Jacob Kaplan-Moss şöyle diyor:


“SQL kullanarak sorgu yazmak Django'dan daha kolaysa, yapın.
ekstra() kötüdür ve kaçınılmalıdır; çiğ() harikadır ve uygun olan
yerlerde kullanılmalıdır.”

90 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


7.6: Gerektiğinde Dizin Ekleme

Şekil 7.1: Bu dondurma aroması ham SQL içerir. Biraz çiğnenmiş.

7.6 Gerektiğinde Dizin Ekleme


eklerken db_index=Doğru herhangi bir model alanı için kolaydır, ne zaman yapılması gerektiğini
anlamak biraz muhakeme gerektirir. Tercihimiz dizinler olmadan başlamak ve gerektiğinde
eklemektir.

Dizin ekleme ne zaman düşünülmeli:

a Dizin, tüm sorguların %10-25'inde olduğu gibi sık sık kullanılır.


a Gerçek veriler var veya gerçek verilere yaklaşan bir şey var, böylece analiz edebiliriz.
indeksleme sonuçları.

a İndekslemenin sonuçlarda bir iyileşme sağlayıp sağlamadığını belirlemek için testler yapabiliriz.

PostgreSQL kullanırken, pg_stat_activity bize gerçekte hangi indekslerin kullanıldığını söyler.

Bir proje hayata geçtiğinde, Bölüm 26: Darboğazları Bulma ve Azaltma, indeks analizi hakkında
bilgi sahibidir.

İPUCU: Sınıf Tabanlı Model İndeksleri

Django şunları sağlar: django.db.models.index'ler modül, dizin sınıf ve


Meta.index'ler seçenek. Bunlar, her türlü veritabanı indeksini oluşturmayı
kolaylaştırır: sadece alt sınıfdizin, ekle Meta.indeksler, ve sen

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 91


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 7: Sorgular ve Veritabanı Katmanı

tamamlamak! django.contrib.postgres.index'ler şu anda içerir BrinIndex


ve cinIndex, ama hayal edebilirsin HashIndex, GistIndex, SpGistIndex, ve
daha fazla.

a docs.djangoproject.com/en/3.2/ref/models/indexes/
a docs.djangoproject.com/en/3.2/ref/models/options/
# dizin

7.7 İşlemler
ORM'nin varsayılan davranışı, çağrıldığında her sorguyu otomatik olarak yerine getirmektir. Veri
değişikliği durumunda, bu, her seferinde bir .oluşturmak() veya .Güncelleme() çağrıldığında, SQL
veritabanındaki verileri hemen değiştirir. Bunun avantajı, yeni başlayan geliştiricilerin ORM'yi
anlamasını kolaylaştırmasıdır. Dezavantajı, bir görünüm (veya başka bir işlem) iki veya daha fazla
veritabanı değişikliğinin gerçekleşmesini gerektiriyorsa, bir değişiklik başarılı ve diğeri başarısız
olursa, veritabanı bozulma riski altındadır.

Veritabanı bozulması riskini çözmenin yolu, veritabanı işlemlerinin kullanılmasıdır. Bir


veritabanı işlemi, iki veya daha fazla veritabanı güncellemesinin tek biriş birimi. Tek bir
güncelleme başarısız olursa, işlemdeki tüm güncellemeler geri alınır. Bunun çalışması için,
tanımı gereği bir veritabanı işlemi olmalıdır.atomik, tutarlı, yalıtılmış vedayanıklı.
Veritabanı uygulayıcıları genellikle kısaltmayı kullanarak veritabanı işlemlerinin bu
özelliklerine atıfta bulunur.ASİT.

Django, güçlü ve nispeten kullanımı kolay bir işlem mekanizmasına sahiptir. Bu, dekoratörleri ve
bağlam yöneticilerini oldukça sezgisel bir modelde kullanarak bir projedeki veritabanı bütünlüğünü
kilitlemeyi çok daha kolaylaştırır.

7.7.1 Bir İşlemde Her HTTP İsteğini Sarma

Örnek 7.10: Her HTTP İsteğini Bir İşlemde Sarma

# settings/base.py

VERİTABANLARI = {

'varsayılan': {
#...
'ATOMİK_İSTEKLER': NS,
},
}

Django, bir işlemin içindeki tüm web isteklerini işlemeyi kolaylaştırır.

92 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


7.7: İşlemler

ATOMIC_REQUESTS ayar. olarak ayarlayarakNS yukarıda gösterildiği gibi, yalnızca veri okuyanlar da dahil

olmak üzere tüm istekler işlemlere sarılır. Bu yaklaşımın avantajı güvenliktir: görünümlerdeki tüm
veritabanı sorguları korunur, dezavantajı performansın düşebilmesidir. Bireysel veritabanı tasarımına
ve çeşitli veritabanı motorlarının kilitlemeyi ne kadar iyi idare ettiğine bağlı olduğundan, bunun
performansı ne kadar etkileyeceğini size söyleyemeyiz.

Bunun, yazma ağırlıklı bir projenin veritabanının bütünlüğünü korumasını başlangıçta sağlamak için harika bir

yol olduğunu bulduk. Ancak çok fazla trafik olduğu için geri dönüp işleri daha odaklı bir yaklaşımla değiştirmek

zorunda kaldık. Büyüklüğüne bağlı olarak bu, küçük veya anıtsal bir görev olabilir.

Kullanırken hatırlanması gereken başka bir şey ATOMİK_İSTEKLER, yalnızca veritabanı


durumunun hatalara geri döndürülmesidir. Bir onay e-postası göndermek ve ardından bir isteği
saran işlemi geri almak utanç verici. Bu sorun, veritabanı dışındaki herhangi bir "yazma" ile
ortaya çıkabilir: e-posta veya SMS göndermek, üçüncü taraf API'yi aramak, dosya sistemine
yazmak, vb. Bu nedenle, kayıtları oluşturan/güncelleyen/silen ancak etkileşime giren
görünümler yazarken veritabanı olmayan öğelerle görünümü süslemeyi seçebilirsiniz.
işlem.non_atomic_requests().

UYARI: Aymeric Augustin üzerinde non_atomic_requests()

Core Django geliştiricisi ve yeni işlem sisteminin ana uygulayıcısı Aymeric Augustin,
“Bu dekoratör, görünümler ve modeller arasında sıkı bir bağlantı gerektiriyor ve bu
da bir kod tabanının bakımını zorlaştıracak. Geriye dönük uyumluluk sağlamak
zorunda kalmasaydık daha iyi bir tasarım bulabilirdik.”

Ardından, bu süper basit API stili işlev tabanlı görünümde aşağıda açıklandığı gibi daha açık
bildirimi kullanabilirsiniz:

Örnek 7.11: Basit Atomik Olmayan Görünüm

# tatlar/views.py

itibaren django.db içe aktarmak işlemitibaren


django.http içe aktarmak HttpYanıt
itibaren django.shortcuts içe aktarmak get_object_or_404
itibaren django.utils içe aktarmak saat dilimi

itibaren .modeller içe aktarmak Lezzet

@işlem.non_atomic_requests
tanım posting_flavor_status(istek, pk, durum):

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 93


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 7: Sorgular ve Veritabanı Katmanı

lezzet = get_object_or_404(Lezzet, pk=pk)

# Bu, otomatik taahhüt modunda yürütülür (Django'nun varsayılanı).lezzet.en


son_status_change_deneme = saat dilimi.şimdi() lezzet.kaydetmek()

ile birlikte işlem.atom():


# Bu kod bir işlem içinde yürütülür.lezzet.durum = durum

lezzet.en son_status_change_success = saat dilimi.şimdi() lezzet.


kaydetmek()
dönüş HttpResponse('Yaşasın')

# İşlem başarısız olursa, uygun durumu döndüründönüş HttpResponse(


'Üzüntü', durum kodu=400)

kullanıyorsanız ATOMIC_REQUESTS=Doğru ve aşağıdaki bölümde açıklanan daha odaklı


bir yaklaşıma geçmek istiyorsanız, aşağıdakileri anlamanızı öneririz: Bölüm 26:
Darboğazları Bulma ve Azaltma, Bölüm 24: Kokuları Test Etmek Para İsrafıdır!, ve
Bölüm 34: Sürekli Entegrasyon Bu çabayı üstlenmeden önce.

İPUCU: Tıbbi veya Finansal Verilere Dokunan Projeler

Bu tür projeler için, sistemleri işlemsel bütünlük yerine nihai tutarlılık için
tasarlayın. Başka bir deyişle, işlemlerin başarısız olmasına ve geri dönüşlerin
gerçekleşmesine hazır olun. Neyse ki, işlemler nedeniyle, geri alma ile bile
veriler doğru ve temiz kalacaktır.

7.7.2 Açık İşlem Beyanı


Açık işlem bildirimi, site performansını artırmanın bir yoludur. Başka bir deyişle, hangi
görünümlerin ve iş mantığının işlemlere sarıldığını ve hangilerinin olmadığını belirtmek. Bu
yaklaşımın dezavantajı, geliştirme süresini artırmasıdır.

İPUCU: Aymeric Augustin, ATOMIC_REQUESTS ile Açık


İşlem Beyanına karşı
Aymeric Augustin, 'Performans yükü katlanılabilir olduğu sürece ATOMIC_REQUESTS
kullanın. Bu, çoğu sitede "sonsuza kadar" anlamına gelir.'

94 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


7.7: İşlemler

İşlemler söz konusu olduğunda, yaşamanız gereken bazı iyi yönergeler şunlardır:

a Veritabanını değiştirmeyen veritabanı işlemleri olmamalı transa sarılmış


hareketler.

a Veritabanını değiştiren veritabanı işlemleri olmalı bir işleme sarılır.


a Veritabanı okumaları ve performans gerektiren veritabanı değişiklikleri dahil özel durumlar
mance düşünceleri önceki iki yönergeyi etkileyebilir.

Bu yeterince açık değilse, farklı Django ORM çağrılarının işlemlere ne zaman sarılması
gerektiğini açıklayan bir tablo burada.

Amaç ORM yöntemi Genel Olarak Kullanın Transac-


konular?

Veri Oluştur . oluşturmak(), . toplu_oluştur(), 3


. get_or_create(),
Verileri Al .
get(), .filter(), .count(), .iterate(), .exists(), .exclude(), .
in_bulk, vb.
Verileri Değiştir . Güncelleme() 3
Verileri Sil . silmek() 3

Tablo 7.1: İşlemlerin Ne Zaman Kullanılacağı

Şekil 7.2: Çünkü kimse dondurmayı bir veri tabanı gibi sevmez.

Bunu da kapsıyoruz Bölüm 26: Darboğazları Bulma ve Azaltma, özellikle alt bölümBölüm
26.2.4: ATOMIC_REQUESTS'i False olarak değiştirin.

İPUCU: Asla Bireysel ORM Yöntem Çağrılarını Sarmayın

Django'nun ORM'si aslında verilerin tutarlılığını sağlamak için dahili olarak


işlemlere dayanır. Örneğin, bir güncelleme somut kalıtım nedeniyle birden çok
tabloyu etkiliyorsa, Django bunu işlemlere dahil eder.

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 95


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 7: Sorgular ve Veritabanı Katmanı

Bu nedenle, tek bir ORM yöntemini sarmak hiçbir zaman yararlı değildir [.oluşturmak(), .
güncelleme(), .delete()]bir işlemde arayın. Bunun yerine, bir görünümde, işlevde veya
yöntemde birkaç ORM yöntemini çağırırken açık işlemleri kullanın.

7.7.3 Django.http.StreamingHttpYanıt ve İşlemler


Bir görünüm dönüyorsa django.http.StreamingHttpResponse, yanıt başladıktan sonra işlem
hatalarını ele almak imkansızdır. Projeniz bu yanıt yöntemini kullanıyorsa, o zaman
ATOMIC_REQUESTS aşağıdakilerden birini yapmalıdır:

1 Ayarlamak ATOMIC_REQUESTS Django'nun varsayılanına, ki bu YANLIŞ. Daha sonra


keşfedilen teknikleri kullanabilirsiniz. Bölüm 7.7.2: Açık İşlem Beyanı. Veya...
2 Görünümü içine sarın django.db.transaction.non_atomic_requests dekor
rektör.

kullanabileceğinizi unutmayınız. ATOMIC_REQUESTS bir akış yanıtı ile, ancak işlem yalnızca
görünümün kendisine uygulanacaktır. Yanıt akışının oluşturulması ek SQL sorgularını
tetiklerse, bunlar otomatik taahhüt modunda yapılacaktır. Umarım bir yanıt oluşturmak,
veritabanı yazma işlemlerini tetiklemez ...

7.7.4 MySQL'de İşlemler


Kullanılan veritabanı ise MySQL, gibi tablo türü seçiminize bağlı olarak işlemler
desteklenmeyebilir. InnoDB veya MyISAM. İşlemler desteklenmiyorsa, Django,
aşağıdakilerden bağımsız olarak her zaman otomatik taahhüt modunda çalışır.
ATOMIC_REQUESTS veya işlemleri desteklemek için yazılmış kod. Daha fazla bilgi için
aşağıdaki makaleleri okumanızı öneririz:

a docs.djangoproject.com/en/3.2/topics/db/transactions/
# işlemler-in-mysql dev.mysql.com/doc/refman/8.0/en/sql-transactional-ifadeleri.
a html

7.7.5 Django ORM İşlem Kaynakları


a docs.djangoproject.com/en/3.2/topics/db/transactions/ Django'nun

işlemlerle ilgili belgeler.


a Real Python, işlemler konusunda harika bir öğreticiye sahiptir. için yazılırken
Django 1.6, malzemenin çoğu bu gün için geçerli olmaya devam ediyor. realpython.com/
blog/python/transaction-management-with-django-1-6

96 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


7.8: Özet

7.8 Özet
Bu bölümde, bir projenin kalıcı verilerini sorgulamanın farklı yollarını inceledik.

Verilerin proje boyunca gerçekte nasıl çalıştığına dair daha iyi bir fikir edindikten sonra dizinleri
kullanmanızı öneririz.

Artık verilerin nasıl saklanacağını ve indeksleneceğini bildiğimize göre, şimdi onu göstermeye başlayalım. Bir sonraki

bölümden başlayarak görünümlere dalıyoruz!

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 97


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 7: Sorgular ve Veritabanı Katmanı

98 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


8 | İşlev ve Sınıf Tabanlı Görünümler

Hem işlev tabanlı görünümler (FBV'ler) hem de sınıf tabanlı görünümler (CBV'ler), Django'nun temel bir

parçasıdır. Her iki görünüm türünü de nasıl kullanacağınızı anlamanızı öneririz.

8.1 FBV'ler veya CBV'ler Ne Zaman Kullanılır


Bir görüşü her uyguladığınızda, FBV olarak mı yoksa CBV olarak mı uygulamanın daha mantıklı
olacağını düşünün. Bazı görüşler en iyi şekilde CBV'ler olarak uygulanır ve diğerleri en iyi FBV'ler
olarak uygulanır.

Hangi yöntemi seçeceğinizden emin değilseniz, bir sonraki sayfada size yardımcı olabilecek bir
akış şeması ekledik.

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 99


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 8: İşlev ve Sınıf Tabanlı Görünümler

Şekil 8.1: FBV veya CBV kullanmalı mısınız? akış şeması.

Bu akış şeması, FBV'ler yerine CBV'leri kullanma tercihimizi takip eder. Çoğu görünüm için CBV'leri kullanmayı,

yalnızca özel hata görünümlerini veya CBV'lerle uygulanması zahmetli olacak karmaşık olanları uygulamak için

FBV'leri kullanmayı tercih ediyoruz.

İPUCU: Alternatif Yaklaşım - FBV'lerle Kalmak

Bazı geliştiriciler, çoğu görünüm için FBV'leri ve yalnızca alt sınıflanması gereken görünümler için

CBV'leri kullanma tarafında hata yapmayı tercih eder. Bu strateji de güzel.

8.2 Görünüm Mantığını URLConfs Dışında Tutun


İstekler, şu yollarla görüntülemelere yönlendirilir: URLConf'ler, normalde adlandırılan bir
modüldeurls.py. Django'nun URL tasarım felsefesine göre (docs.djangoproject.com/tr/3.2/
misc/design-felsefeler/#url-design), görünümlerin url'lerle bağlantısı gevşek,
sonsuz esnekliğe izin verir ve en iyi uygulamaları teşvik eder.

Yine de, Daniel'in ne zaman karmaşık görse bağırmak gibi hissettiği şey bu. urls.py Dosyalar:

“J2EE XML ve Zope ZCML konfigürasyon dosyalarını o gün yazmadım ki siz çocuklar
Django url modüllerine mantık sokabilesiniz diye!”

100 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


8.2: Görünüm Mantığını URLConfs Dışında Tutun

Django'nun URL rotalarını tanımlamanın harika ve basit bir yolu olduğunu unutmayın. Bu kitapta
bahsettiğimiz diğer her şey gibi, bu basitliğe de saygı duyulmalı ve saygı duyulmalıdır. Temel kurallar
şu şekildedir:

1 Görünüm modülleri görünüm mantığını içermelidir.


2 URL modülleri, URL mantığını içermelidir.

Hiç böyle kod gördünüz mü? Belki de Sınıf Tabanlı Görünümler için resmi belgelerde?

Örnek 8.1: Django CBV Stili URLconf Modülleri

# Bunu yapma!
itibaren django.urls içe aktarmak yol
itibaren django.views.jenerik içe aktarmak Detay Görünümü

itibaren tadımlar.modeller içe aktarmak Tatma

url kalıpları = [
yol('<int:pk>',
DetailView.as_view(
model=Tadım,
şablon_adı='tadımlar/detay.html'), isim='detay'),

yol('<int:pk>/sonuçlar/',
DetailView.as_view(
model=Tadım,
şablon_adı='tadımlar/sonuçlar.html'), isim='Sonuçlar'),

Bir bakışta bu kod uygun görünebilir, ancak Django tasarım felsefelerini ihlal ettiğini iddia
ediyoruz:

a Gevşek kaplin görünümler, url'ler ve modeller arasındaki bağlantılar, sıkı ku-


pling, yani görünüm tanımlarını asla yeniden kullanamazsınız.
a Kendinizi Tekrar Etmeyin aynı/benzer argümanları tekrar tekrar kullanarak ihlal ediliyorsa
CBV'ler arasında.
a Sonsuz esneklik (URL'ler için) yok edilir. Sınıf mirası, birincil avantaj
Sınıf Tabanlı Görünümler, bu anti-kalıp kullanılarak imkansızdır.
a Diğer birçok sorun: Kimlik doğrulama eklemeniz gerektiğinde ne olur? Ve
peki yetkilendirme? Her URLConf görünümünü iki veya

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 101


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 8: İşlev ve Sınıf Tabanlı Görünümler

daha fazla dekoratör? Görünüm kodunuzu URLConf'lerinize koymak, URLConf'lerinizi hızla


sürdürülemez bir karmaşaya dönüştürür.

Aslında, geliştiricilerden URLConfs'ta bu şekilde tanımlanan CBV'leri görmenin, onları kullanmaktan


kaçınmalarının bir nedeni olduğunu duyduk.

Tamam, yeterince kavrama. Bir sonraki bölümde tercihlerimizi göstereceğiz.

8.3 URLConfs'ta Gevşek Kuplaja Bağlı Kalma

Şekil 8.2: Çikolata parçalı kurabiye hamuru dondurmasının gevşek bağlantısı.

Önceki sayfada bahsettiğimiz sorunlardan kaçınan URLConf'leri nasıl oluşturacağınız aşağıda açıklanmıştır. İlk

olarak, görüşleri yazıyoruz:

Örnek 8.2: tadımlar/views.py

itibaren django.urls içe aktarmak ters


itibaren django.views.jenerik içe aktarmak Liste Görünümü, Detay Görünümü, Güncelleme Görünümü

itibaren .modeller içe aktarmak Tatma

sınıf Tat Listesi Görünümü(Liste görünümü):

model = Tatma

sınıf TatAyrıntılı Görünüm(Detay Görünümü):


model = Tatma

sınıf TatSonuçlarGörünüm(LezzetAyrıntılı Görünüm):


şablon adı = 'tadımlar/sonuçlar.html'

sınıf Tat Güncelleme Görünümü(Güncelleme Görünümü):

model = Tatma

102 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


8.3: URLConfs'ta Gevşek Kuplaja Bağlı Kalma

tanım get_success_url(öz):
dönüş ters('tatma:detay',
kwarglar={'pk': öz.nesne.pk})

Ardından url'leri tanımlarız:

Örnek 8.3: tadımlar/urls.py

itibaren django.urls içe aktarmak yol

itibaren . içe aktarmak Görüntüleme

url kalıpları = [
yol(
güzergah='',
görüş=Görüntüleme.Tat Listesi Görünümü.
as_view(), isim='liste'
),
yol(
güzergah='<int:pk>/',
görüş=Görüntüleme.TatAyrıntılı Görünüm.
as_view(), isim='detay'
),
yol(
güzergah='<int:pk>/sonuçlar/',
görüş=Görüntüleme.TatSonuçlarGörünüm.as_view(),
isim='Sonuçlar'
),
yol(
güzergah='<int:pk>/güncelleme/',
görüş=Görüntüleme.Tat Güncelleme Görünümü.as_view(),

isim='Güncelleme'

)
]

Bu versiyonumuza ilk cevabınız şöyle olmalı, “Bunun iyi bir fikir olduğundan emin misin? İki dosya VE
daha fazla kod satırı kullanmak için bazı şeyleri değiştirdiniz! Bu nasıl daha iyi?”

Pekala, bu şekilde yapıyoruz. İşte bu kadar yararlı bulmamızın nedenlerinden bazıları:

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 103


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 8: İşlev ve Sınıf Tabanlı Görünümler

a Kendinizi Tekrar Etmeyin : Görünümler arasında hiçbir argüman veya nitelik tekrarlanmaz.

a Gevşek kaplin: Model ve şablon adlarını URLConf'tan kaldırdık


çünkü görünümler görünümler olmalı ve URLConf'ler URLConfs olmalıdır. Görüşlerimizi bir veya
daha fazla URLConf'tan çağırabilmeliyiz ve yaklaşımımız tam da bunu yapmamıza izin veriyor.

a URLConfs bir şey yapmalı ve onu iyi yapmalıdır: Bir önceki maddemiz ile ilgili olarak,
URLConf artık yalnızca tek bir şeye odaklanıyor: URL yönlendirme. Hem görünümler hem de
URLConf'ler arasında görünüm mantığını izlemiyoruz, sadece görüşlerimize bakıyoruz.
a Görüşlerimiz sınıf temelli olmaktan yararlanır: Resmi bir tanım yaparak görüşlerimiz
görünümler modülünde diğer sınıflardan miras alabilir. Bu, kimlik doğrulama, yetkilendirme,
yeni içerik biçimleri veya önümüze atılan diğer iş gereksinimlerinin eklenmesinin çok daha kolay
olduğu anlamına gelir.
a sonsuz esneklik: Görüşlerimiz, görünümler modülünde resmi bir tanım yaparak,
kendi özel mantığını uygular.

8.3.1 Ya CBV Kullanmıyorsak?

Aynı kurallar geçerlidir.

Kapsamlı URLConf korsanlığı ile FBV'leri kullanan projelerin hata ayıklama kabuslarıyla
karşılaştık, örneğin, Python modüllerinin __file__ özniteliği ile birleştirilmiş dizin yürüyüşü ve
URLConf'leri otomatik olarak oluşturmak için düzenli ifadeler gibi ayrıntılı hileler gibi. Kulağa acı
verici geliyorsa, öyleydi.

Mantığı URLConf'lerden uzak tutun!

8.4 URL Ad Alanlarını Kullan


URL ad alanlarının yaptığı, uygulama düzeyinde ve örnek düzeyinde ad alanları için bir
tanımlayıcı sağlamaktır. URL ad alanları, yüzeyde pek yardımcı olamayacak gibi görünen
şeylerden biridir, ancak bir geliştirici onları kullanmaya başladığında neden daha önce
kullanmadığını merak eder. URL ad alanlarını kullanarak aşağıdaki gibi özetleyeceğiz:

gibi URL adları yazmak yerine tadımlar_detay onları beğen


tadımlar:detay.

Bunun neden bu kadar yararlı olduğunu açıklamadan önce, örnek 8.2'deki uygulama düzeyinde
URLConf kodunu temel alan bir kullanım örneği sunacağız. URLConf kök dizinine şunları ekleriz:

104 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


8.4: URL Ad Alanlarını Kullan

Örnek 8.4: Projenin Kökünde urls.py Snippet'i

url kalıpları += [
yol('tadım/', Dahil etmek('tadım.url',

→ ad alanı='tadım')),
]

Bunu bir görünümde çalışırken görmek için, örnek 8.1'den bir kod parçacığına bakalım:

Örnek 8.5: tadım/views.py snippet'i

# tadım/views.py snippet'isınıf Tat Güncelleme


Görünümü(Güncelleme Görünümü):
model = Tatma

tanım get_success_url(öz):
dönüş ters('tatma:detay',
kwarglar={'pk': öz.nesne.pk})

Bunu bir HTML şablonunda çalışırken görün:

Örnek 8.6: tat_list.html

{% uzanır 'temel.html' %}

{% engellemek Başlık %}Tadımlar{% uç blok Başlık %}

{% engellemek içerik %}
<ul>
{% için damak zevki içinde tadımlar %}
<li>
<a href="{% url 'tadımlar:detay' tat.pk %}">{{ tat.başlık

→ }}</a>
<küçük>
(<a href="{% url 'tadımlar:güncelleme' tat.pk %}">güncelleme</a>) </small>

</li>
{% son %}
</ul>
{% uç blok içerik %}

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 105


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 8: İşlev ve Sınıf Tabanlı Görünümler

Artık URL ad alanlarının nasıl uygulanacağını anladığımıza göre, neden yararlı olduklarını ele
alalım.

8.4.1 Daha Kısa, Daha Sezgisel ve Kendiniz URL Adlarını Tekrar


Etmeyin
Örnek 8.3'te görmediğimiz şey, “ gibi URL adlarıdır.tadımlar_detay” ve"tatma_sonuçları" modeli
veya uygulama adını kopyalayan Bunun yerine “ gibi basit, sezgisel isimler var.detay ” ve "
Sonuçlar”. Bu, özellikle yeni Django geliştiricileri için uygulamaların okunabilirliğini büyük
ölçüde artırır.

Ayrıca, kim "tadım" veya bir uygulamaya ne denirse yazmak ister ki bu kadar çok kez?

8.4.2 Üçüncü Taraf Kitaplıklarla Birlikte Çalışabilirliği Artırır

< gibi URL adları yazmanın sorunlarından biriuygulamam>_detay uygulama adlarının çakıştığı
zamandır. Bu bizim gibi şeyler için bir sorun olmasa datadımlar app, blog ve iletişim
uygulamaları ile kesinlikle yazarların başına geldi. Neyse ki, URL ad alanları bunu çözmeyi
kolaylaştırır. Mevcut bir kişi uygulamamız olduğunu, ancak ikinci bir tane eklememiz gerektiğini
varsayarsak, URL ad alanlarını kullanarak bunları şu şekilde kök URLConf'umuza entegre
edebiliriz:

Örnek 8.7: Kök URLConf Birlikte Çalışabilirliği

# urls.py projenin kökündeurl kalıpları


+= [
yol('İletişim/', Dahil etmek('contactmonger.urls',


→ ad alanı='temas tüccarı')),
yol('rapor sorunu/', Dahil etmek('contactapp.urls',


→ ad alanı='contactapp')),
]

Ardından, aşağıdakileri yaparak bunları şablonlarımızda çalışın:

Örnek 8.8: contact.html

{% uzanır "temel.html" %}
{% engellemek Başlık %}Temas{% uç blok Başlık %} {%
engellemek içerik %}

106 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


8.4: URL Ad Alanlarını Kullan

<p>
<a href="{% url 'iletişim kuryesi:oluştur' %}">Bize Ulaşın</a> </p>

<p>
<a href="{% url 'iletişim uygulaması:rapor' %}">Sorun Bildir</a> </p>

{% uç blok içerik %}

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 107


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 8: İşlev ve Sınıf Tabanlı Görünümler

8.4.3 Daha Kolay Aramalar, Yükseltmeler ve Yeniden Düzenlemeler

Django gibi PEP 8 dostu çerçeveler için adlarda alt çizgilerin yaygınlığı göz önüne
alındığında, arama kodu veya “ gibi adlartadımlar_detay” zorlayıcı olabilir. Bir sonuç
geldiğinde, bu bir görünüm adı, bir URL adı veya başka bir şey için mi?

Öte yandan, "tadımlar:detay” sezgisel arama sonucu yanıtları sağlar. Bu, yeni üçüncü taraf
kitaplıklarıyla etkileşim kurarken de dahil olmak üzere uygulamaların ve projelerin
yükseltilmesini ve yeniden düzenlenmesini kolaylaştırabilir ve yaptı.

8.4.4 Daha Fazla Uygulama ve Şablon Ters Hilelerine İzin Verir

Burada hiçbir numarayı ele almayacağız çünkü bu tür şeylerin neredeyse hiçbir zaman haklı olmadığını

düşünüyoruz. Aslında, genellikle herhangi bir somut fayda sağlamadan bir projenin karmaşıklığına katkıda

bulunurlar. Bununla birlikte, bahsetmeye değer birkaç kullanım durumu vardır:

a Hata ayıklama düzeyinde iç gözlem gerçekleştiren Django-debug-toolbar gibi geliştirme araçları


tion.
a Son kullanıcıların davranışlarını değiştirmek veya değiştirmek için “modüller” eklemesine izin veren projeler.

hesap.

Geliştiriciler, her zaman olduğu gibi, yaratıcı URL ad alanları hilelerinin kullanımını doğrulamak için bunlardan herhangi

birini kullanabilir, ancak önce en basit yaklaşımı denemenizi öneririz.

8.5 İş Mantığını Görüşlerden Uzak Tutmaya Çalışmak


Geçmişte, görüşlerimize inanılmaz miktarda sofistike iş mantığı yerleştirdik. Ne yazık ki sıra PDF
oluşturma, bir REST API ekleme veya diğer formatları sunma zamanı geldiğinde, görüşlerimize
bu kadar çok mantık yerleştirmek yeni formatlar sunmayı çok daha zor hale getirdi.

Burada tercih ettiğimiz model yöntemleri, yönetici yöntemleri veya genel yardımcı işlevler yaklaşımımız
devreye girer. İş mantığı, kolayca yeniden kullanılabilir bileşenlere yerleştirildiğinde ve görünümlerin
içinden çağrıldığında, daha fazla şeyi yapmak için projenin bileşenlerini genişletmeyi çok daha kolay
hale getirir.

Bunu bir projenin başında yapmak her zaman mümkün olmadığı için, görüşler
arasında Django ortak plakası yerine iş mantığını kopyaladığımızda temel kuralımız,
kodu görünümden çıkarmanın zamanı geldi.

8.6 Django Görünümleri İşlevlerdir


Aşağıya geldiğinde, her Django görünümü bir işlevdir. Bu işlev bir HTTP istek nesnesi alır
ve onu bir HTTP yanıt nesnesine dönüştürür. Temel matematiksel fonksiyonlar hakkında
bir şey biliyorsanız, bu değişim süreci çok tanıdık gelmelidir.

108 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


8.6: Django Görünümleri İşlevdir

Örnek 8.9: Matematiksel İşlevler Olarak Django Görünümleri

# Fonksiyon olarak Django FBVHttpYanıt =


görünüm(HttpRequest)

# Temel matematiğe deşifre edildi (cebirden fonksiyonları hatırlıyor musunuz?)y = f(x)

# . . . ve sonra bir CBV örneğine çevrildiHttpYanıt = görüş.


as_view()(HttpRequest)

Bu değişim kavramı, Django görünümleriyle, işlev veya sınıf tabanlı olsun, yapabileceğiniz her
türlü şey için bir temel görevi görür.

İPUCU: Sınıf Tabanlı Görünümler Aslında İşlev Olarak Adlandırılır

Django'nun CBV'leri FBV'lerden çok farklı görünüyor. Ancak


Görünüm.as_view() URLConfs içinde çağrılan classmethod aslında görünümün çağrılabilir
bir örneğini döndürüyor. Başka bir deyişle, istek/yanıt döngüsünü işlev tabanlı bir
görünümle tamamen aynı şekilde işleyen bir geri arama işlevi!

8.6.1 En Basit Görünümler

Bunu akılda tutarak, Django ile oluşturulabilecek olası en basit görünümleri hatırlamakta
fayda var:

Örnek 8.10: simple_views.py

itibaren django.http içe aktarmak HttpYanıtitibaren


django.views.jenerik içe aktarmak görüş

# En basit FBV
tanım en basit görünüm(rica etmek):
# İş mantığı buraya giderdönüş
HttpResponse('FBV')

# En basit CBVsınıf En Basit


Görünüm(Görüş):
tanım elde etmek(öz, rica etmek, *argümanlar, **kwarglar):

# İş mantığı buraya giderdönüş


HttpResponse('CBV')

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 109


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 8: İşlev ve Sınıf Tabanlı Görünümler

Bunu bilmek neden yararlıdır?

a Bazen küçük şeyler yapan tek seferlik görüşlere ihtiyacımız var.

a En basit Django görünümlerini anlamak, onların ne olduklarını daha iyi anlamamız anlamına gelir.

gerçekten yapıyor.

a Django FBV'lerin HTTP yönteminin nasıl tarafsız olduğunu, ancak Django CBV'lerin nasıl gerekli olduğunu gösterir

belirli HTTP yöntemi bildirimi.

8.7 Kullanmayın yerliler() Görünüm Bağlam olarak


dönüş yerliler() herhangi bir çağrılabilirden bir anti-kalıptır. Kullanışlı bir kısayol gibi görünse
de, aslında zaman alıcı bir kabus. Nedenini keşfetmek için bir örnek kullanalım. İşte bu anti-
desen izleyen bir görünüm:

Örnek 8.11: Yerellerin Uygunsuz Kullanımı()

# Bunu yapma!
tanım ice_cream_store_display(istek, mağaza_kimliği):
mağaza = get_object_or_404(Mağaza, id=store_id) tarih =
saat dilimi.now()
dönüş render (istek, 'melted_ice_cream_report.html',

→ yerliler())

Yüzeyde her şey öyle gibi iyi.

Ancak, açık bir tasarımdan örtülü anti-kalıba geçtik ve bu basit görünümün sürdürülmesi can
sıkıcı hale getirdik. Özellikle, görünümün ne döndürmesi gerektiğini bilmediğimizi. Görünüm
tarafından döndürülen değişkenlerden herhangi birinin değiştirilmesi hemen belli olmadığı için
bu bir sorun haline gelir:

Örnek 8.12: Önceki Kod Örneğinin Değiştirilmiş Versiyonu

# Bunu yapma!
tanım ice_cream_store_display(istek, mağaza_kimliği):
store = get_object_or_404(Mağaza, id=store_id) şimdi =
saat dilimi.now()
dönüş render (istek, 'melted_ice_cream_report.html',

→ yerliler())

Kötü Örnek 8.11 ile Kötü Örnek 8.12 arasındaki farkı anlamanız ne kadar sürdü? Bu basit
bir örnekti, büyük bir şablonla daha karmaşık bir örnek hayal edin. Bu nedenle, görüşlerde
açık bağlamın kullanılmasını şiddetle savunuyoruz:

110 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322


8.8: Özet

Örnek 8.13: Açık Görünüm Bağlamı

tanım ice_cream_store_display(istek, mağaza_kimliği):


dönüş render(
rica etmek,
'melted_ice_cream_report.html', {

'mağaza': get_object_or_404(Mağaza, İD=mağaza_kimliği),'şimdi':


saat dilimi.şimdi()
}
)

a Alex Martelli'nin Akıl Yürütme: stackoverflow.com/a/1901720

8.8 Özet
Bu bölüm, FBV'lerin veya CBV'lerin ne zaman kullanılacağını tartışarak başladı ve ikincisi için
kendi tercihimize uydu. Aslında, bir sonraki bölümde, FBV'ler kullanılırken yararlanılabilecek
işlevselliklerin derinliklerine inmeye başlayacağız ve bunu CBV'ler üzerine bir bölüm izleyecektir.

Ayrıca görünüm mantığını URLConf'lerin dışında tutmayı da tartıştık. Görünüm kodunun uygulamalara ait

olduğunu düşünüyoruz'görünümler.py modüller ve URLConf kodu uygulamalara aittir. urls.py modüller. Bu

uygulamaya bağlı kalmak, sınıf tabanlı görünümler, daha kolay kod yeniden kullanımı ve daha fazla tasarım

esnekliği ile kullanıldığında nesne mirasına izin verir.

Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues 111


LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322
Bölüm 8: İşlev ve Sınıf Tabanlı Görünümler

112 Lütfen sorunları şuraya gönderin: github.com/feldroy/two-scoops-of-django-3.x/issues

LAKLAK LAKLAK için özel olarak hazırlanmıştır ( 39r4ye7vy@relay.firefox.com ) İşlem: 11322

You might also like