Django Introduction

Bahattin ÇİNİÇ

Software Developer @adphorus

http://bahattincinic.com

http://github.com/bahattincinic

Django Nedir ?

Olabildiğince az kodla hızlı ve sürdürülebilir uygulamalar oluşturabileceğiniz en popüler Python frameworküdür.
 

İsmi, caz gitaristi Django Reinhardt'tan gelmektedir.
 

Django Projesi'nin temel hedefi, karmaşık bir yapıda olan ve bir veritabanı kullanan web uygulamalarının gerçekleştirimini kolaylaştırmaktır.

Kimler Kullanıyor ?

  • Pinterest
  • instagram
  • Firefox
  • NASA
  • Bitbucket
  • Disqus
  • Spotify
  • New York Times
  • Washington Post
  •  The Guardian
  • Mercedes Benz
  • National Geographic
  • Discovery Channel
  • Orange

Çok daha fazlası...

Öne Çıkan Özellikleri

  • Admin Arayüzü
  • Template Engine
  • Form
  • i18n
  • Session, User management, role-based permissions
  • Object-Relational Mapping (ORM)
  • Database Migration
  • Testing Framework
  • GeoIP
  • Cache
  • Güzel ve anlaşılır dökümantasyon

Mimari

Güvenlik Avantajları

  • ORM Queryi kendisi oluşturur. SQL injection ihtimalinin önüne geçmiş olur.
  •  Otomatik olarak HTML leri Escape eder.  XSS ataklarının önüne geçmiş olur.
  • CSRF koruması. Formların botlar, scriptler tarafından gönderilmesinin engellenmesi.
  • Clickjacking protection
  • User Uploaded Content Validation
  • Host header validation
  • SSL/HTTPS opsiyonu.

Kurulum

$ pip install django



$ pip freeze

Django==1.8

https://pypi.python.org/pypi/Django

http://github.com/django/django
http://djangoproject.com

Gereksinimler: Python, PIP

>>> import django
>>> django.VERSION

Proje Oluşturmak

$ django-admin.py startproject slideshare
.
└── slideshare
    ├── manage.py
    └── slideshare
        ├── __init__.py
        ├── settings.py
        ├── urls.py
        └── wsgi.py

Uygulamalar

Bir Django projesi bir veya birden çok küçük uygulamadan oluşur.

Bunların bir kısmı kendi yazdığınız, bir kısmı dışarıdan kurduğunuz uygulamalardan oluşabilir.

 

Uygulama Oluşturmak

$ python manage.py startapp presentation
.
└── slideshare
    ├── presentation
    │   ├── __init__.py
    │   ├── admin.py
    │   ├── migrations
    │   │   └── __init__.py
    │   ├── models.py
    │   ├── tests.py
    │   └── views.py
    │   └── urls.py
    ├── manage.py
    └── slideshare
        ├── __init__.py
        ├── settings.py
        ├── urls.py
        └── wsgi.py
  • Oluşturulan Proje yapısı varsayılan olarak bu şekildedir. Yapılmak istenen proje yapısı/büyüklüğüne göre değiştirilebilir. (django two scoops project)

manage.py

Proje bu script dosyası üzerinden yönetilir.

 

  • Projenin Çalıştırılması
  • Migration
  • Management Command
  • Shell
  • ...
$ python manage.py <command> [options]

Sık Kullanılan management komutları

  • runserver
  • dbshell
  • shell
  • migrate
  • makemigrations
  • compilemessages
  • makemessages
  • loaddata
  • dumpdata
  • startapp

python manage.py

settings.py

Proje ayarları burada bulunur.

Django'nun kendi ayarları dışında siz de ekstra proje ayarlarınızı buraya koyabilirsiniz.

  • Veritabanı
  • SMTP
  • Aktif Uygulamalar
  • Dil ayarları
  • Cache
  • Logger
  • ...

models.py

Uygulamaların veritabanı ile iletişim kurduğu katmandır.

Her bir model veritabanında bir tabloya karşılık gelir. (abstract modeler dışında)

Destek Verilen ilişkisel (RDBMS) Veritabanları
PostgreSQL, MySQL, SQLite, Oracle

Object Oriented (methods, properties, inheritance, etc.)

OneToOne, ManyToOne (ForeignKey), ManyToMany ilişkiler

Generic Relation

Ne gibi şeyler yapabiliyoruz ?

models.py

from django.db import models


class Speaker(models.Model):
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)
    email = models.EmailField()
    
    def __str__(self):
        return self.first_name


class Category(models.Model):
    name = models.CharField(max_length=255)
    
    def __str__(self):
        return self.name


class Presentation(models.Model):
    title = models.CharField(max_length=255)
    speaker = models.ForeignKey(Speaker)
    link = models.URLField()
    description = models.TextField(null=True, blank=True)
    categories = models.ManyToManyField(Category)

   def __str__(self):
        return self.title

Model inheritance

from django.db import models


class Photo(models.Model):
    photo = models.ImageField(upload_to='photos/')
    is_active = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)
    
    def __str__(self):
        return self.id
    
    class Meta:
        abstract = True


class SpeakerPhoto(Photo):
    speaker = models.ForeignKey(Speaker)


class PresentationPhoto(Photo)
    presentation = models.ForeignKey(Presentation)

Model Manager (models.Manager)

  • Veritabanı işlemleri için interface dir.
  • Her modelin en az 1 Maneger'ı bulunur.
  • Varsayılan olarak objects dir.
  • Custom managerlar yazabilirsiniz.
  • Bir modelde birden fazla manager olabilir
from django.db import models


class Presentation(models.Model):
    #...

    active = ActiveManager()
    passive = PassiveManager()
    # default
    objects = models.Manager()

ORM

# All
Presentation.objects.all()

# Filter
Presentation.objects.filter(speaker__email='bahattincinic@gmail.com')

# OrderBy
Presentation.objects.all().order_by('-id')

# Exclude
Presentation.objects.exclude(categories__name='Python')
# Create
presentation = Presentation()
speaker = Speaker.objects.get(email='bahattincinic@gmail.com')
presentation.speaker = speaker
presentation.title = 'Django 101'
presentation.link = 'https://slides.com/bahattincinic/django-introduction'
presentation.save()

# Update
presentation = Presentation.objects.get(title='Django 101')
presentation.description = 'Bu bir Django 101 sunumudur.'
presentation.save()

# Delete
presentation = Presentation.objects.get(title='Django 101')
presentation.delete()

views.py

İş akışının gerçekleştiği, arayüzden gelen kullanıcı etkileşimlerinin değerlendirildiği, işlendiği, gerekli metodların çalıştırıldığı, değişkenlerin ve nesnelerin  oluşturulduğu, gerekirse modelle template bölümleri arasında iletişimin sağlandığı yer burasıdır. 

Class Based veya function based olarak yazabilirsiniz.

Web Browser

Views

URL Conf

^

HttpRequest

HttpResponse

urls.py

views.py

class PresentationList(ListView):
    template_name = 'presentation_list.html'
    model = Presentation
    paginate_by = 12


class PresentationDetail(DetailView):
    template_name = 'presentation_detail.html'
    model = Presentation

Class

Based View

def presentation_list(request):
   return render_to_response('presentation_list.html', {
        'presentation_list': Presentation.objects.all()
   })


def presentation_detail(request, id):
    presentation = get_object_or_404(Presentation, id=id)
    return render_to_response('presentation_detail.html', {
        'presentation': presentation
    })

Function

Based View

urls.py

Sitenin URL tanımlamaları bu dosyada bulunur.

Root dizin dışında her app içinde de urls dosyası tanımlayıp root urls dosyasında birleştirebilirsiniz. Bu şekilde hem bağımlılıkları kopartmış, hemde url dosyanızın büyümesini önlemiş olursunuz.

url tanımlamaları içine regex yazabilirsiniz.

from django.conf.urls import url

from presentation.views import PresentationListView, PresentationDetailView


urlpatterns = [
    url(r'^$',
        PresentationListView.as_view(),
        name="presentation-list"),
    url(r'^speaker/(?P<pk>[0-9]+)/$',
        PresentationDetailView.as_view(),
        name="presentation-detail"),
]

Template Engine

  • Front-end developer dostu
  • Kolay, anlaşılır.
  • template tags, filters
  • i18n
  • Multiple Template Engines
  • Template inheritance
  • Template include
  • context processors
  • Model altındaki methodlara erişmek.

Template Engine

<html>
    <title> {% block title %}{% endblock title %}</title>
    <head>
         {% block head %}{% endblock head %}
    </head>
    <body>
        {% block content %}{% endblock content %}
    </body>
</html>

base.html

{% extends "base.html" %}

{% block title %}{{ object.title }}{% endblock title %}

{% block content %}
  <h1>{{ object.title }}</h1>
  <p>{{ object.description }}</p>
{% endblock content %}

presentation_detail.html

admin.py

  • CRUD Operasyonlar.
  • Toplu işlemler (silme vs.)
  • Filtreleme, Arama
  • Authentication, Authorization
  • Loglama (django.contrib.admin.LogEntry)
  • Değiştirilebilir Tasarım (django-admin2, south, grappelli, flattheme)
  • Çoklu dil desteği
  • Form validation

admin.py

from django.contrib import admin

from presentation.models import Presentation, Speaker


class SpeakerAdmin(admin.ModelAdmin):
    list_display = ('first_name', 'last_name',)
    search_fields = ('first_name', 'last_name',)


class PresentationAdmin(admin.ModelAdmin):
    list_display = ('title', 'speaker')
    list_filter = ('categories',)
    search_fields = ('title',)


admin.site.register(Speaker, SpeakerAdmin)
admin.site.register(Presentation, PresentationAdmin)

tests.py

  • App-level testing
  • Simulate Request (django.test.Client)
  • Selenium Support
  • Fixtures
  • Multi-database support
  • Overriding settings
$ python manage.py test
$ python manage.py test <APP>

tests.py

from django.test import TestCase, Client
from django.core.urlresolvers import reverse

from presentation.models import Speaker, Presentation


class PresentationTestCase(TestCase):
    def setUp(self):
        self.speaker = Speaker.objects.create(
            first_name='Bahattin', last_name='Cinic',
            email='bahattincinic@gmail.com')
        self.presentation = Presentation.objects.create(
            title='test', speaker=speaker, description='fdfd',
            link='https://slides.com/bahattincinic/django-introduction')
        self.client = Client()
    
    def test_presentation_detail(self):
        response = self.client.get(reverse('presentation-detail',
                                           args=[self.presentation.id]))
        self.assertEqual(response.status_code, 200)

    def test_speaker_detail(self):
        response = self.client.get(reverse('speaker-detail',
                                           args=[self.spaker.id]))
        self.assertEqual(response.status_code, 200)

Açık Kaynak Projeler

  • Taiga                     github.com/taigaio/taiga-back
  • Argüman              github.com/arguman/arguman.org
  • PythonIstanbul    github.com/pyistanbul/website/
  • python.org           github.com/python/pythondotorg
  • djangosnippets   github.com/djangode/djangosnippets.org
  • sentry                   github.com/getsentry/sentry
  • djangoCMS          github.com/divio/django-cms
  • Oscar                    github.com/django-oscar/django-oscar 
  • Kuma                    github.com/mozilla/kuma

Çok daha fazlası...

Kullanışlı Paketler

  • South
  • django-compressor
  • django-debug-toolbar
  • django-extensions
  • django-nose
  • djangorestframework
  • django-rosetta
  • django-filter
  • django-taggit
  • django-haystack
  • django-celery
  • django-filter
  • django-taggit
  • django-mptt
  • django-hvad
  • django-haystack
  • django-celery
  • django-redis

Dinleyiciler için kaynaklar

  • https://github.com/rosarior/awesome-django
  • http://www.tangowithdjango.com/
  • http://twoscoopspress.org/
  • http://chimera.labs.oreilly.com/books/1234000000754/index.html
  • http://www.amazon.com/gp/product/B00E6TJCKU/
  • https://highperformancedjango.com/

Demo

http://github.com/bahattincinic/django-101/

Teşekkürler

?

Sorular

http://bahattincinic.com

http://github.com/bahattincinic

Django Introduction

By Bahattin Çiniç

Django Introduction

  • 3,225