Slide 1

Slide 1 text

UGUR "VIGO" OZYILMAZEL - . . !1

Slide 2

Slide 2 text

Bir DJANGO projesi : !2

Slide 3

Slide 3 text

$ django-admin startproject devsummit !3

Slide 4

Slide 4 text

$ tree . ├── devsummit │ ├── __init __.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── manage.py 1 directory, 5 files !4

Slide 5

Slide 5 text

$ python manage.py startapp blog !5

Slide 6

Slide 6 text

$ tree devsummit/ devsummit/ ├── blog │ ├── migrations │ │ └── __init __.py │ ├── __init __.py │ ├── admin.py │ ├── apps.py │ ├── models.py │ ├── tests.py │ └── views.py ├── devsummit │ ├── __init __.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── manage.py 3 directories, 12 files !6

Slide 7

Slide 7 text

$ tree devsummit/ devsummit/ ├── blog │ ├── migrations │ │ └── __init __.py │ ├── __init __.py │ ├── admin.py │ ├── apps.py │ ├── models.py │ ├── tests.py │ └── views.py ├── devsummit │ ├── __init __.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── manage.py 3 directories, 12 files ? !7

Slide 8

Slide 8 text

# SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'lzir%8bs)t_dw#9-h(qt+(*6o27s6!ba+l&1*g%iypemvk%8zo' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True ALLOWED_HOSTS = [] INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ] DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } } !8

Slide 9

Slide 9 text

# SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'lzir%8bs)t_dw#9-h(qt+(*6o27s6!ba+l&1*g%iypemvk%8zo' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True ALLOWED_HOSTS = [] INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ] DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } } !9

Slide 10

Slide 10 text

Ortam İzolasyonu ? PRODUCTION STAGING TEST DEVELOPMENT CI/CD DEBUG ALLOWED_HOSTS INSTALLED_APPS DATABASES MEDIA_ROOT LOGGING !10

Slide 11

Slide 11 text

Paket Bağımlılıkları PRODUCTION STAGING TEST DEVELOPMENT CI/CD Django ==2.2 ipython ==7.4.0 django-debug-toolbar ==1.11 coverage ==4.5.3 whitenoise ==4.1.2 pylint ==2.3.1 !11

Slide 12

Slide 12 text

$ tree blog/ blog/ ├── migrations │ └── __init __.py ├── __init __.py ├── admin.py ├── apps.py ├── models.py ├── tests.py └── views.py !12

Slide 13

Slide 13 text

Uygulama Soruları ? Kaç tane uygulama olmalı Kaç tane model olmalı Kaç tane view olmalı Testler nasıl organize edilmeli !13

Slide 14

Slide 14 text

Eğer tek bir "app" içinde 20+ model varsa, uygulamanız birden fazla şeyi yapıyor anlamına gelir. Bu durumda uygulamanızı parçalayıp uygulama başına düşen model sayısını da azaltmanız önerilir. Chapter 6: Model Best Pratices !14

Slide 15

Slide 15 text

Yeni Proje Oluşturma Aşaması Son yaptığın projeyi clone'la ? Önce yeni versiyon Django ile proje oluştur, daha sonra en son yaptığın projenin settings'inden kopyala ? !15

Slide 16

Slide 16 text

Yeni Proje Oluşturma Aşaması !16

Slide 17

Slide 17 text

!17

Slide 18

Slide 18 text

$ rails new devsummit !18

Slide 19

Slide 19 text

$ tree -L 1 devsummit/ devsummit/ ├── app ├── bin ├── config ├── db ├── lib ├── log ├── public ├── storage ├── test ├── tmp ├── vendor ├── Gemfile ├── Gemfile.lock ├── README.md ├── Rakefile ├── config.ru └── package.json 11 directories, 6 files !19

Slide 20

Slide 20 text

$ tree devsummit/ devsummit/ ├── app │ ├── assets │ │ ├── config │ │ │ └── manifest.js │ │ ├── images │ │ ├── javascripts │ │ │ ├── channels │ │ │ ├── application.js │ │ │ └── cable.js │ │ └── stylesheets │ │ └── application.css │ ├── channels │ │ └── application_cable │ │ ├── channel.rb │ │ └── connection.rb │ ├── controllers │ │ ├── concerns │ │ └── application_controller.rb │ ├── helpers │ │ └── application_helper.rb │ ├── jobs │ │ └── application_job.rb │ ├── mailers │ │ └── application_mailer.rb │ ├── models │ │ ├── concerns │ │ └── application_record.rb │ └── views │ └── layouts │ ├── application.html.erb │ ├── mailer.html.erb │ └── mailer.text.erb ├── bin │ ├── bundle │ ├── rails │ ├── rake │ ├── setup │ ├── spring │ ├── update │ └── yarn ├── config │ ├── environments │ │ ├── development.rb │ │ ├── production.rb │ │ └── test.rb │ ├── initializers │ │ ├── application_controller_renderer.rb │ │ ├── assets.rb │ │ ├── backtrace_silencers.rb │ │ ├── content_security_policy.rb │ │ ├── cookies_serializer.rb │ │ ├── filter_parameter_logging.rb │ │ ├── inflections.rb │ │ ├── mime_types.rb │ │ └── wrap_parameters.rb │ ├── locales │ │ └── en.yml │ ├── application.rb │ ├── boot.rb │ ├── cable.yml │ ├── credentials.yml.enc │ ├── database.yml │ ├── environment.rb │ ├── master.key │ ├── puma.rb │ ├── routes.rb │ ├── spring.rb │ └── storage.yml ├── db │ └── seeds.rb ├── lib │ ├── assets │ └── tasks ├── log ├── public │ ├── 404.html │ ├── 422.html │ ├── 500.html │ ├── apple-touch-icon-precomposed.png │ ├── apple-touch-icon.png │ ├── favicon.ico │ └── robots.txt ├── storage ├── test │ ├── controllers │ ├── fixtures │ │ └── files │ ├── helpers │ ├── integration │ ├── mailers │ ├── models │ ├── system │ ├── application_system_test_case.rb │ └── test_helper.rb ├── tmp │ ├── cache │ │ └── assets │ └── storage ├── vendor ├── Gemfile ├── Gemfile.lock ├── README.md ├── Rakefile ├── config.ru └── package.json 44 directories, 61 files !20

Slide 21

Slide 21 text

$ bin/rails generate scaffold Post title:string body:text !21

Slide 22

Slide 22 text

class CreatePosts < ActiveRecord ::Migration[5.2] def change create_table :posts do |t| t.string :title t.text :body t.timestamps end end end Migration Model Controller (View) View (Template) !22

Slide 23

Slide 23 text

!23

Slide 24

Slide 24 text

Rails ile Hazır Gelenler • Ortam izolasyonu: "config/environments/" • Ortama göre paket organizasyonu: "Gemfile" • Tek "app" kavramı: "app/" • Model "app/models/" altında !24

Slide 25

Slide 25 text

Rails ile Hazır Gelenler • Controller (View) "app/controllers" altında • Migration'lar proje kapsamında "db/migrate" altında • Tesler'ler projre kampsamında "test/" altında • Management komutları: "Rakefile" / Rake Task * !25

Slide 26

Slide 26 text

Rake • Makefile'ın Ruby'cesi • macOS sürümleriyle birlikte geliyor • 101 seviyesinde Ruby yeterli :) • Jim Weirich (1956-2014) !26

Slide 27

Slide 27 text

Rakefile task :default => [:run_server] task :check_django_environment do abort "Set DJANGO_ENV variable! via export DJANGO_ENV= ..." unless ENV['DJANGO_ENV'] end task :check_development_environment => [:check_django_environment] do abort "Set DJANGO_ENV to development" unless ENV['DJANGO_ENV'] == 'development' end desc "Run server" task :run_server => [:check_development_environment] do system "DJANGO_COLORS='dark' python manage.py runserver_plus --nothreading" end !27

Slide 28

Slide 28 text

Hayalimdeki Yapı • Ortam izolasyonu hazır olsa (dev/prod/stage/test ...) • Kolay model/view/template üretebilsem ... • Rails'deki "routes" gibi "urls.py" ı yönetsem ... • Rails'deki gibi proje yapısı olsa tek yerden erişsem ... • Temel bir modelim olsa, olmazsa olmaz field'ları barındırsa ... • Ortama göre paketleri düzenleyebilsem? (dev.pip, prod.pip ...) • Sık kullandığım paketler içinde olsa ...(django-debug-toolbar gibi) • Diğer yaptığım ve hep kullandığım tool'cuklarım da içinde olsa ... !28

Slide 29

Slide 29 text

$ bash <(curl -fsSL https: //l.vigo.io/d2install) Django Project Starter Template !29

Slide 30

Slide 30 text

Django Project Starter Template • Özelleştirilebilir Custom User modeli • BaseModel ve BaseModelWithSoftDelete * modelleri • Yeni proje dosya/dizin yapısı • Ortam ve paket izolasyonu • App ve Model üretmek için Rake task'leri (Management Commands) !30

Slide 31

Slide 31 text

Django Project Starter Template • Migration yönetimi için Rake task'leri (Management Commands) • Sadeleştirilmiş development logger • Debug için (console ve html seviyesinde) araçlar • Admin için yardımcı Widget'lar ve Storage • bulma.io entegrasyonu !31

Slide 32

Slide 32 text

Django Project Starter Template • flake8, pylint, black, isort, bandit konfigürasyonu • Gelişmiş REPL desteği (ipython/ bpython) - django-extensions ==2.1.6 • Hazır LOCALE sözlük çatısı • CustomLocaleMiddleware ile kolay i18n • HEROKU'ya hızlı deploy ... !32

Slide 33

Slide 33 text

Django Project Starter Template !33 $ tree -L 2 . ├── applications │ └── baseapp ├── config │ ├── settings │ ├── __init __.py │ ├── urls.py │ └── wsgi.py ├── db ├── locale │ └── tr ├── media │ └── avatar ├── requirements │ ├── base.pip │ ├── development.pip │ ├── heroku.pip │ └── travis.pip ├── static │ └── css ├── templates │ ├── admin │ ├── baseapp │ └── base.html ├── LICENSE.txt ├── Procfile ├── README.md ├── Rakefile ├── install.sh ├── manage.py ├── pyproject.toml ├── requirements.txt └── runtime.txt 15 directories, 17 files ├── settings │ ├── __init __.py │ ├── base.py │ ├── development.example.py │ ├── development.py │ ├── heroku.py │ ├── production.py │ ├── test.example.py │ ├── test.py │ └── travis.py

Slide 34

Slide 34 text

Django Project Starter Template $ python manage.py create_app blog $ rake new:application[blog] !34

Slide 35

Slide 35 text

Django Project Starter Template $ python manage.py create_model blog Category softdelete $ rake new:model[blog,Category,softdelete] !35

Slide 36

Slide 36 text

Django Project Starter Template $ rake db:update[blog,create_post_and_category] $ rake db:migrate !36

Slide 37

Slide 37 text

Django Project Starter Template $ rake -T rake db:migrate[database] # Run migration for given database (default: 'default') rake db:roll_back[name_of_application,name_of_migration] # Roll-back (name of application, name of migration) rake db:shell # run database shell .. rake db:show[name_of_application] # Show migrations for an application (default: 'all') rake db:update[name_of_application,name_of_migration,is_empty] # Update migration (name of application, name of migration?, is empty?) rake locale:compile # Compile locale dictionary rake locale:update # Update locale dictionary rake new:application[name_of_application] # Create new Django application rake new:model[name_of_application,name_of_model,type_of_model] # Create new Model for given application: django,basemodel,softdelete rake run_server # Run server rake shell[repl] # Run shell+ avail: ipython,bpython default: ipython rake test:browse_coverage[port] # Browse test coverage rake test:coverage[cli_args] # Show test coverage (default: ' --show-missing --ignore-errors --skip-covered') rake test:run[name_of_application,verbose] # Run tests for given application !37

Slide 38

Slide 38 text

Django Project Starter Template $ rake db:show[core] core [X] 0001_models [X] 0002_add __article_title __field_to_person [X] 0003_add __article_description __to_person [X] 0004_add __staff __to_program [X] 0005_fix_person [X] 0006_add_duty_to_person_and_title_is_nullable !38

Slide 39

Slide 39 text

Django Project Starter Template $ rake db:roll_back[core,4] Operations to perform: Target specific migration: 0004_add __staff __to_program, from core Running migrations: Rendering model states ... DONE Unapplying core.0006_add_duty_to_person_and_title_is_nullable ... OK Unapplying core.0005_fix_person ... OK !39

Slide 40

Slide 40 text

Django Project Starter Template $ rake db:show[core] core [X] 0001_models [X] 0002_add __article_title __field_to_person [X] 0003_add __article_description __to_person [X] 0004_add __staff __to_program [ ] 0005_fix_person [ ] 0006_add_duty_to_person_and_title_is_nullable !40

Slide 41

Slide 41 text

Django Project Starter Template $ rake db:roll_back[core,6] Operations to perform: Target specific migration: 0006_add_duty_to_person_and_title_is_nullable, from core Running migrations: Applying core.0005_fix_person ... OK Applying core.0006_add_duty_to_person_and_title_is_nullable ... OK !41

Slide 42

Slide 42 text

Django Project Starter Template !42

Slide 43

Slide 43 text

Django Project Starter Template console(arg, arg, ...) console.dir(obj) !43

Slide 44

Slide 44 text

Django Project Starter Template !44

Slide 45

Slide 45 text

Django Project Starter Template !45

Slide 46

Slide 46 text

Django Project Starter Template !46

Slide 47

Slide 47 text

Django Project Starter Template !47

Slide 48

Slide 48 text

Django Project Starter Template !48 https: //github.com/vigo/django2-project-template

Slide 49

Slide 49 text

Django Project Starter Template TODO • Rails'deki gibi scaffold generator • Management command için generator • 404/500 Error sayfaları • Rich Text Editor / TextArea (Widget) • Dockerfile rake new:model[blog,Post,softdelete] title:string body:text author:User !49

Slide 50

Slide 50 text

Django Project Starter Template Açık Kaynak, MIT Lisanslı Katkılarınızı bekliyorum! !50

Slide 51

Slide 51 text

Krediler • Django logosu / djangoproject.com/community/logos • Ruby on Rails logosu / rubyonrails.org • Two Scoops of Django / @pydanny • Cookiecutter / Audrey Roy Greenfeld • Jim Weirich fotoğrafı confreaks.tv !51

Slide 52

Slide 52 text

Linkler • https: // www.djangoproject.com • https: //rubyonrails.org • https: //github.com/ruby/rake • https: //github.com/audreyr/cookiecutter/ • https: //github.com/pydanny/cookiecutter-django • https: // www.twoscoopspress.com • https: //github.com/vigo/django2-project-template • https: //l.vigo.io/d2pst !52

Slide 53

Slide 53 text

!53 Teşekkürler