Uygulamanı genişlet
Websitemizi oluşturmak için gerekli adımların hepsini tamamladık: bir modelin, url'nin, view'ün ve template'in nasıl yazılacağını biliyoruz. Websitemizi nasıl güzelleştirebiliriz onu da biliyoruz.
Pratik zamanı!
Blog'umuzda lazım olan ilk şey bir gönderiyi göstermek için bir sayfa, değil mi?
Halihazırda bir Post
modelimiz var, dolayısıyla models.py
dosyasına bir şey eklememize gerek yok.
Bir gönderinin detayı için bir template(şablon) linki oluşturun
blog/templates/blog/post_list.html
dosyasına bir link (bağlantı) ekleyerek başlayacağız. Bu dosyayı kod düzenleyicisinde açalım, şimdiye kadar yaptıklarımızın şöyle gözüküyor olması lazım:
{% extends 'blog/base.html' %}
{% block content %}
{% for post in posts %}
<div class="post">
<div class="date">
{{ post.published_date }}
</div>
<h1><a href="">{{ post.title }}</a></h1>
<p>{{ post.text|linebreaksbr }}</p>
</div>
{% endfor %}
{% endblock %}
Gönderi listesindeki bir gönderinin başlığından bir gönderinin detay sayfasına bir link (bağlantı) olsun istiyoruz. <h1><a href="">{{ post.title }}</a></h1>
'i gönderinin detay sayfasına link verecek şekilde değiştirelim:
blog/templates/blog/post_list.html
<h1><a href="{% url 'post_detail' pk=post.pk %}">{{ post.title }}</a></h1>
Gizemli {% url 'post_detail' pk=post.pk %}
satırını anlatma zamanı. Şüphelendiğiniz üzere, {% %}
notasyonu, Django template tags (şablon etiketleri) kullandığımız manasına geliyor. Bu sefer bizim için URL oluşturacak bir şablon (template) etiketi kullanacağız!
post_detail
kısmı Django'nun blog/urls.py/
dosyasının içinde post_detail adlı bir URL beklediği anlamına gelir.
Peki pk=post.pk
? pk
primary key (birincil anahtar) için kullanılan kısaltmadır, veritabanındaki her kayıt için verilen özgün (eşsiz) bir isimdir. Post
modelimiz için bir primary key tanımlamamış olduğumuz için, Django onu bizim için otomatik olarak oluşturdu (genelde, her kayıt için bir artan numara ile, örnek 1, 2, 3) ve her post için pk
adlı bir alan ekledi. Primary key'e erişmek için post.pk
yazarız, tıpkı Post
objesindeki diğer alanlara eriştiğimiz gibi (title
, author
, vb.)!
Şimdi http://127.0.0.1:8000/ adresine gittiğimizde bir hata ile karşılaşacağız (post_detail
için bir URL ya da görüntü (view) olmadığı için hatayı almamız normal). Hata böyle görünecektir:
Bir gönderinin detayı için URL oluşturun
post_detail
view'ımız için urls.py
'un içinde bir URL oluşturalım!
İlk gönderimizin detayının şu URL'de gösterilmesini istiyoruz: http://127.0.0.1:8000/post/1/
blog/urls.py
dosyasında post_detail
adında bir Django view'ına işaret eden bir URL yapalım. Bu <1>view1> bir gönderinin tümünü gösterecek. Kod düzenleyicide blog/urls.py
dosyasını açın ve path('post/<int:pk>)/', views.post_detail, name='post_detail'),
satırını ekleyin, böylece dosya şöyle görünür:
blog/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.post_list, name='post_list'),
path('post/<int:pk>/', views.post_detail, name='post_detail'),
]
post/<int:pk>/
kısmı bir URL kalıbı belirtir - sizin için bunu açıklayalım:
post/
, URL'nin post kelimesi ile başlayıp ardından / ile devam etmesi gerektiği anlamına gelir.<int:pk>
- bu bölüm daha zorlayıcı. Django'nun bir tamsayı değeri beklediği ve onupk
adlı bir değişken olarak bir görünüme(view) aktaracağı anlamına gelir./
- URL'yi bitirmeden önce / 'e tekrar ihtiyacımız var.
Bu şu demek, eğer tarayıcınıza http://127.0.0.1:8000/post/5/
yazarsanız, Django post_detail
adında bir view aradığınızı anlar ve pk
eşittir 5
bilgisini view'e aktarır.
Tamamdır.blog/urls.py
!'e yeni bir URL kalıbı ekledik! Http://127.0.0.1:8000/ sayfasını yenileyelim.Boom! Sunucu çalıştırmayı tekrar durdurdu. Konsola göz at, beklendiği gibi bir hata daha var!
Bir sonraki adımın ne olduğunu hatırlıyor musunuz? Tabi ki: view(görünüm)'ü eklemek!
Gönderi detayı için bir view ekleyin
Bu sefer view'ımıza pk
adında bir parametre ekleyeceğiz. view'ümüzün onu yakalaması gerekiyor, değil mi? Fonksiyonumuzu def post_detail(request, pk):
olarak tanımlayacağız. Dikkat edin, url'lerde kullandığımız ismin birebir aynısını kullanmamız gerekiyor (pk
). Bu değişkeni kullanmamak yanlıştır ve hataya sebep olacaktır!
Şimdi sadece ve sadece bir tane blog gönderisi almak istiyoruz. Bunu yapmak için şunun gibi sorgu setlerini/kümelerini kullanabiliriz:
blog/views.py
Post.objects.get(pk=pk)
Ama bu kodun bir problemi var. Eğer gelen primary key
(pk
- tekil anahtar) ile bir Post
(gönderi) yoksa, çok çirkin bir hatamız olacak!
Bunu istemiyoruz! Ama tabi Django'da bunu ele alan bir şey var: get_object_or_404
. Eğer verilen pk
ile bir Post
bulunamazsa, çok daha güzel bir sayfa gösterilecek (Sayfa bulunamadı 404
sayfası.
İyi haber şu, kendi Sayfa bulunamadı
sayfasını yapabilir ve istediğiniz kadar güzelleştirebilirsiniz. Ama şu anda çok önemli değil, o yüzden bu kısmı atlayacağız.
Tamam, views.py
dosyamıza bir view ekleme zamanı!
blog/urls.py
içinde views.post_detail
denilen bir görünüm ifade eden post_detail
adında bir URL kuralı oluşturduk. Bu, Django'nun ` blog/views.py </ 0> içinde post_detail </ 0> adlı bir görünüm fonksiyonu bekleyeceği anlamına gelir.</p>
blog/views.py'i açmalıyız ve diğerfrom` satırının yanına şu kodları eklemeliyiz:
blog/views.py
from django.shortcuts import render, get_object_or_404
Ve dosyanın sonuna kendi view'ımızı ekleyeceğiz:
blog/views.py
def post_detail(request, pk):
post = get_object_or_404(Post, pk=pk)
return render(request, 'blog/post_detail.html', {'post': post})
Evet. http://127.0.0.1:8000/ sayfasını tazeleme zamanı
Çalıştı! Fakat blog gönderisi başlığındaki bir bağlantıya tıkladığınızda ne oluyor?
Of hayır! Başka bir hata! Ama onu nasıl halledeceğimizi biliyoruz, di mi? Bir template eklememiz gerekiyor!
Post(gönderi) detayları için bir template(şablon) oluştur
blog/templates/blog
dizininde post_detail.html
adında bir dosya oluşturalım ve kod düzenleyicisinde açalım.
Şöyle görünmeli:
blog/templates/blog/post_detail.html
{% extends 'blog/base.html' %}
{% block content %}
<div class="post">
{% if post.published_date %}
<div class="date">
{{ post.published_date }}
</div>
{% endif %}
<h1>{{ post.title }}</h1>
<p>{{ post.text|linebreaksbr }}</p>
</div>
{% endblock %}
Bir kere daha base.html
dosyasıa ekleme yapacağız. content
blogunda bir gönderinin varsa published_date, title ve text'ini göstermek istiyoruz. Ama daha önemli şeyleri konuşmalıyız, değil mi?
{% if ... %} ... {% endif %}
bir şeyi kontrol etmek istediğimizde kullanabileceğimiz bir şablon etiketidir. ( if ... else ..
ifadelerini Python'a Giriş bölümünden hatırladın mı?) Bu durumda eğer gönderinin published_date
kısmı boş değilse kontrol etmek isteriz.
Tamam, şimdi sayfamızı yenileyerek TemplateDoesNotExist
hatası kaybolmuş mu görebiliriz.
Heyo! Çalışıyor!
Yayına alma zamanı!
Sitenizin hala PythonAnywhere'de çalışıp çalışmadığına bakmakta fayda var, değil mi? Yeniden taşımayı deneyelim.
komut satırı
$ git status
$ git add --all .
$ git status
$ git commit -m "Site için CSS ve ayrıntılı blog gönderisi için görünüm ve şablon eklendi."
$ git push
Sonra bir PythonAnywhere Bash konsol una gidip:
komut satırı
$ cd ~/<your-pythonanywhere-username>.pythonanywhere.com
$ git pull
[...]
(Açı parantezleri olmadan <your-pythonanywhere-username>
'i gerçek PythonAnywhere kullanıcı isminizle değiştirmeyi unutmayın).
Sunucudaki statik dosyaları güncelleyelim
PythonAynwhere gibi sunucular "statik dosyalar"a (CSS dosyaları gibi) Python dosyalarından farklı davranır çünkü onları daha hızlı yüklenmesi için optimize edebilir. Sonuç olarak, CSS dosyalarında her değişiklik yaptığınızda, sunucuya onları güncellediğimizi söylemek için ilave bir komut çalıştırmalıyız. Bu komuta collectstatic
adı verilir.
Daha önceden çalıştırdığın virtualenv'in hala etkin değilse tekrar aktive ederek başlayın. (PythonAnywhere bunu yapmak için workon
adlı bir komut kullanır. Kendi bilgisayarında kullandığın source myenv/bin/activate
komutu gibi.):
komut satırı
$ workon <your-pythonanywhere-username>.pythonanywhere.com
(kullaniciadiniz.pythonanywhere.com)$ python manage.py collectstatic
[...]
manage.py collectstatic
komutu biraz manage.py migrate
komutu gibidir. Kodumuzda bazı değişiklikler yapıp Django'ya bu değişiklikleri sunucunun statik dosyalar yığınına ya da veritabanına uygulamasını söyledik.
Her durumda, artık "Web" sayfasına (konsolun sağ üstündeki menü düğmesinden) atlamaya ve Yeniden Yükle seçeneğine tıklamaya hazırız ve sonucu görmek için https://adınız.pythonanywhere.com sayfasına bakın.
İşte bu kadar! Tebrikler :)