Panduan Lengkap untuk Pemula untuk Django - Bagian 2

Selamat datang di bagian kedua dari Tutorial Django kami! Dalam pelajaran sebelumnya, kami menginstal semua yang kami butuhkan. Mudah-mudahan, Anda semua setup dengan Python 3.6 diinstal dan Django 1.11 berjalan di dalam Lingkungan Virtual. Kami sudah membuat proyek yang akan kami mainkan. Dalam pelajaran ini, kita akan terus menulis kode di proyek yang sama.
Di bagian selanjutnya, kita akan berbicara sedikit tentang proyek yang akan kita kembangkan, jadi untuk memberi Anda beberapa konteks. Kemudian setelah itu, Anda akan mempelajari semua dasar-dasar Django: model, admin, tampilan, templat, dan URL.
Tangan di atas!
Proyek Dewan Web
Saya tidak tahu tentang Anda, tetapi secara pribadi, saya belajar lebih banyak dengan melihat contoh praktis dan cuplikan kode. Bagi saya, sulit untuk memproses konsep di mana dalam contoh yang Anda baca
Class A
dan Class B
, atau ketika saya melihat foo(bar)
contoh klasik . Saya tidak ingin melakukan itu dengan Anda.
Jadi, sebelum kita masuk ke bagian yang menyenangkan, bermain dengan model, pandangan, dan segalanya. Mari kita luangkan waktu sejenak dan diskusikan secara singkat tentang proyek yang akan kita kembangkan ini.
Jika Anda sudah memiliki pengalaman dengan pengembangan Web dan merasa terlalu banyak detail, Anda bisa membaca gambar untuk mengetahui apa yang akan kita buat dan kemudian melompat ke bagian Model dari tutorial ini.
Tetapi jika Anda baru dalam pengembangan Web, saya sangat menyarankan Anda terus membaca. Ini akan memberi Anda wawasan yang baik tentang pemodelan dan desain aplikasi Web. Pengembangan web, dan pengembangan perangkat lunak secara umum, bukan hanya tentang pengkodean.

Gunakan diagram kasus
Proyek kami adalah papan diskusi (forum). Idenya adalah untuk mempertahankan beberapa papan , yang akan berperilaku seperti kategori. Kemudian, di dalam papan khusus, pengguna dapat memulai diskusi baru dengan membuat topik baru . Dalam topik ini, pengguna lain dapat terlibat dalam balasan posting diskusi.
Kami perlu menemukan cara untuk membedakan pengguna biasa dari pengguna admin karena hanya admin yang seharusnya membuat papan baru. Di bawah ini, ikhtisar kasus penggunaan utama kami dan peran masing-masing jenis pengguna:

Gambar 1: Gunakan diagram kasus fungsi inti yang ditawarkan oleh Web Board
Diagram Kelas
Dari Use Case Diagram, kita dapat mulai berpikir tentang entitas proyek kita. Entitas adalah model yang akan kita buat, dan itu sangat terkait dengan data yang akan diproses aplikasi Django kita.
Agar kami dapat menerapkan kasus penggunaan yang dijelaskan di bagian sebelumnya, kami harus menerapkan setidaknya model berikut: Papan , Topik , Posting , dan Pengguna .

Gambar 2: Draf diagram kelas Dewan Web
Penting juga meluangkan waktu untuk berpikir tentang bagaimana model akan berhubungan satu sama lain. Apa yang dikatakan garis padat kepada kita adalah bahwa, dalam Topik , kita perlu memiliki bidang untuk mengidentifikasi Dewan mana yang menjadi miliknya. Demikian pula, Postingakan membutuhkan bidang untuk mewakili Topik mana yang dimiliki sehingga kita dapat mendaftar dalam diskusi yang hanya Posting yang dibuat dalam Topik tertentu . Akhirnya, kita akan membutuhkan bidang di Topik untuk mengetahui siapa yang memulai diskusi dan di Pos sehingga kita dapat mengidentifikasi siapa yang memposting balasan.
Kami juga dapat memiliki hubungan dengan Dewan dan model Pengguna , sehingga kami dapat mengidentifikasi siapa yang membuat Dewan yang diberikan . Tetapi informasi ini tidak relevan untuk aplikasi. Ada cara lain untuk melacak informasi ini, Anda akan lihat nanti.
Sekarang setelah kita memiliki representasi kelas dasar, kita harus memikirkan jenis informasi apa yang masing-masing model akan bawa. Hal semacam ini dapat menjadi sangat mudah. Jadi cobalah untuk fokus pada bit-bit penting. Informasi yang Anda butuhkan untuk memulai pengembangan. Selanjutnya, kita dapat meningkatkan model menggunakan migrasi , yang akan Anda lihat dengan sangat rinci di tutorial berikutnya.
Tetapi untuk sekarang, ini akan menjadi representasi dasar dari bidang model kami:

Gambar 3: Diagram kelas yang menekankan hubungan antara kelas (model)
Diagram kelas ini memiliki penekanan pada hubungan antara model. Garis dan panah itu pada akhirnya akan diterjemahkan ke dalam bidang nanti.
Untuk model Dewan , kita akan mulai dengan dua bidang: nama dan deskripsi . Bidang nama harus unik, sehingga untuk menghindari duplikasi nama papan. The deskripsi hanya untuk memberikan petunjuk tentang apa papan adalah semua tentang.
The Topic Model akan terdiri dari empat bidang: subjek , update terakhir tanggal yang akan digunakan untuk menentukan topik pemesanan, topik pemula untuk mengidentifikasi Penggunayang memulai Topik , dan field yang disebut papan untuk menentukan yang Dewan spesifik Topikmilik .
Model Posting akan memiliki bidang pesan , yang akan digunakan untuk menyimpan teks balasan posting, bidang yang dibuat pada tanggal dan waktu yang terutama digunakan untuk memesan Posting dalam suatu Topik , bidang yang diperbarui pada tanggal dan waktu untuk menginformasikan Pengguna kapan dan jika Postingan yang diberikan telah diedit. Seperti bidang tanggal dan waktu, kami juga harus merujuk model Pengguna : dibuat oleh dan diperbarui oleh .
Akhirnya, model Pengguna . Dalam diagram kelas, saya hanya menyebutkan kolom nama pengguna , kata sandi , email dan merupakan superuser flag karena hanya itu yang akan kita gunakan sekarang. Penting untuk dicatat bahwa kita tidak perlu membuat model Pengguna karena Django sudah dilengkapi dengan model Pengguna bawaan di dalam paket contrib . Kami akan menggunakannya.
Mengenai banyaknya dalam diagram kelas (angka
1
, 0..*
, dll), berikut adalah cara Anda membacanya:
1
) Dewan (yang berarti tidak dapat null), dan Dewan dapat berhubungan dengan banyak Topics atau tidak ada ( 0..*
). Yang berarti Dewan dapat ada tanpa Topik tunggal .
1..*
). SebuahPasang harus dikaitkan dengan satu, dan hanya satu Topic ( 1
).
1
). Dan seorang Pengguna mungkin memiliki banyak atau tidak ada Topik ( 0..*
).
1
). Sebuah Penggunamungkin memiliki banyak atau tidak Entri ( 0..*
). Hubungan kedua antara Posting dan Pengguna adalah hubungan langsung(lihat panah di akhir baris), yang berarti kami hanya tertarik pada satu sisi hubungan yang merupakan apa yang telah diedit oleh Pengguna pada Posting tertentu . Ini akan diterjemahkan ke dalam bidang yang diperbarui oleh . Multiplisitas mengatakan 0..1
, artinya bidang yang diperbarui oleh mungkin nol ( Postingtidak diedit) dan paling banyak dapat dikaitkan dengan hanya satu Pengguna .
Cara lain untuk menggambar diagram kelas ini adalah menekankan bidang daripada dalam hubungan antara model:

Gambar 4: Diagram kelas yang menekankan atribut (bidang) dari kelas (model)
Representasi di atas setara dengan yang sebelumnya, dan itu juga lebih dekat dengan apa yang akan kita rancang menggunakan Django Models API. Dalam representasi ini, kita dapat melihat lebih jelas bahwa dalam model Post topik asosiasi , dibuat oleh , dan diperbarui oleh menjadi bidang model. Hal lain yang menarik untuk dicatat adalah bahwa dalam model Topik kita sekarang memiliki operasi (metode kelas) bernama posting () . Kami akan mencapai ini dengan menerapkan hubungan terbalik, di mana Django akan secara otomatis mengeksekusi kueri dalam database untuk mengembalikan daftar semua Posting yang termasuk ke dalam Topik tertentu .
Baiklah, cukup UML untuk saat ini! Untuk menggambar diagram yang disajikan di bagian ini saya menggunakan alat StarUML .
Wireframes
Setelah menghabiskan waktu merancang model aplikasi, saya ingin membuat beberapa wireframes untuk menentukan apa yang perlu dilakukan dan juga memiliki gambaran yang jelas tentang ke mana kita akan pergi.

Kemudian berdasarkan pada wireframes kita dapat memperoleh pemahaman yang lebih dalam tentang entitas yang terlibat dalam aplikasi.
Hal pertama, kita perlu menunjukkan semua papan di beranda:

Gambar 5: Situs web papan gambar rangka proyek daftar semua papan yang tersedia.
Jika pengguna mengklik tautan, katakan di papan Django, itu harus mencantumkan semua topik:

Gambar 6: Gambar rangka proyek papan yang mencantumkan semua topik di dewan Django.
Di sini kita memiliki dua jalur utama: baik pengguna mengklik tombol "topik baru" untuk membuat topik baru, atau pengguna mengklik pada topik untuk melihat atau terlibat dalam diskusi.
Layar "topik baru":

Gambar 7: Layar topik baru
Sekarang layar topik, menampilkan posting dan diskusi:

Gambar 8: Layar daftar posting topik
Jika pengguna mengklik tombol jawab, mereka akan melihat layar di bawah ini, dengan ringkasan posting dalam urutan terbalik (terbaru lebih dulu):

Gambar 9: Layar topik balas
Model
Model-model tersebut pada dasarnya adalah representasi dari tata letak basis data aplikasi Anda. Apa yang akan kita lakukan di bagian ini adalah membuat representasi Django dari kelas yang kita modelkan di bagian sebelumnya: Board , Topic , dan Post . Model Pengguna sudah didefinisikan di dalam aplikasi bawaan bernama auth , yang terdaftar dalam
INSTALLED_APPS
konfigurasi kami dibawah namespace django.contrib.auth .
Kami akan melakukan semua pekerjaan di dalam file board / models.py . Inilah cara kami merepresentasikan diagram kelas kami dalam aplikasi Django:
from django.db import models
from django.contrib.auth.models import User
class Board(models.Model):
name = models.CharField(max_length=30, unique=True)
description = models.CharField(max_length=100)
class Topic(models.Model):
subject = models.CharField(max_length=255)
last_updated = models.DateTimeField(auto_now_add=True)
board = models.ForeignKey(Board, related_name='topics')
starter = models.ForeignKey(User, related_name='topics')
class Post(models.Model):
message = models.TextField(max_length=4000)
topic = models.ForeignKey(Topic, related_name='posts')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(null=True)
created_by = models.ForeignKey(User, related_name='posts')
updated_by = models.ForeignKey(User, null=True, related_name='+')
Semua model adalah subclass dari kelas django.db.models.Model . Setiap kelas akan diubah menjadi tabel basis data . Setiap bidang diwakili oleh instance dari django.db.models.Field subclass (built-in Django core) dan akan diterjemahkan ke dalam kolom basis data .
Field
CharField
, DateTimeField
dll., Adalah semua subclass dari django.db.models.Field dan semuanya termasuk dalam inti Django - siap digunakan.
Di sini kita hanya menggunakan
CharField
, TextField
, DateTimeField
, dan ForeignKey
bidang untuk menentukan model kami. Tapi Django menawarkan berbagai macam pilihan untuk mewakili berbagai jenis data, seperti IntegerField
, BooleanField
, DecimalField
, dan banyak lainnya. Kami akan merujuk mereka sesuai kebutuhan.
Beberapa bidang memerlukan argumen, seperti
CharField
. Kita harus selalu menetapkan max_length
. Informasi ini akan digunakan untuk membuat kolom basis data. Django perlu tahu seberapa besar kolom database yang dibutuhkan. The max_length
parameter juga akan digunakan oleh Django Formulir API, untuk memvalidasi input pengguna. Lebih lanjut tentang itu nanti.
Dalam
Board
definisi model, lebih khusus di name
lapangan, kami juga mengatur parameterunique=True
, seperti namanya, itu akan menegakkan keunikan lapangan di tingkat basis data.
Dalam
Post
model, created_at
bidang memiliki parameter opsional, auto_now_add
set ke True
. Ini akan menginstruksikan Django untuk mengatur tanggal dan waktu saat ini ketika sebuah Post
objek dibuat.
Salah satu cara untuk membuat hubungan antara model adalah dengan menggunakan
ForeignKey
bidang. Ini akan membuat tautan antara model dan membuat hubungan yang tepat di tingkat basis data. The ForeignKey
lapangan mengharapkan parameter posisional dengan mengacu pada model itu akan berhubungan dengan.
Misalnya, dalam
Topic
model, board
bidang adalah ForeignKey
ke Board
model. Memberitahu Django bahwa sebuah Topic
instance hanya berhubungan dengan satu Board
instance. The related_name
parameter akan digunakan untuk membuat hubungan terbalik dimana Board
contoh akan memiliki akses daftar Topic
contoh milik itu.
Django secara otomatis membuat hubungan terbalik ini -
related_name
opsional. Tetapi jika kita tidak menetapkan nama untuk itu, Django akan menghasilkan itu dengan nama: (class_name)_set
. Misalnya, dalam Board
model, Topic
instans akan tersedia di bawah topic_set
properti. Sebagai gantinya, kami hanya mengganti nama menjadi topics
, untuk membuatnya terasa lebih alami.
Dalam
Post
model, updated_by
bidang menetapkan related_name='+'
. Ini menginstruksikan Django bahwa kita tidak perlu hubungan terbalik ini, jadi itu akan mengabaikannya.
Di bawah ini Anda dapat melihat perbandingan antara diagram kelas dan kode sumber untuk menghasilkan model dengan Django. Garis hijau menunjukkan bagaimana kita menangani hubungan terbalik.

Pada titik ini, Anda mungkin bertanya pada diri sendiri: "bagaimana dengan kunci primer / ID"? Jika kami tidak menentukan kunci utama untuk model, Django akan secara otomatis menghasilkannya untuk kami. Jadi kita baik untuk saat ini. Di bagian selanjutnya, Anda akan melihat lebih baik cara kerjanya.
Bermigrasi Model
Langkah selanjutnya adalah memberi tahu Django untuk membuat database sehingga kita dapat mulai menggunakannya.
Buka Alat Baris Perintah , aktifkan lingkungan virtual, buka folder tempat file manage.py berada, dan jalankan perintah di bawah ini:
python manage.py makemigrations
Sebagai output, Anda akan mendapatkan sesuatu seperti ini:
Migrations for 'boards':
boards/migrations/0001_initial.py
- Create model Board
- Create model Post
- Create model Topic
- Add field topic to post
- Add field updated_by to post
Pada titik ini, Django membuat file bernama 0001_initial.py di dalam direktori boards / migrasi . Ini mewakili keadaan saat ini dari model aplikasi kita. Pada langkah berikutnya, Django akan menggunakan file ini untuk membuat tabel dan kolom.
File migrasi diterjemahkan ke dalam pernyataan SQL. Jika Anda terbiasa dengan SQL, Anda dapat menjalankan perintah berikut untuk memeriksa instruksi SQL yang akan dieksekusi dalam database:
python manage.py sqlmigrate boards 0001
Jika Anda tidak terbiasa dengan SQL, jangan khawatir. Kami tidak akan bekerja secara langsung dengan SQL dalam seri tutorial ini. Semua pekerjaan akan dilakukan hanya dengan menggunakan Django ORM, yang merupakan lapisan abstraksi yang berkomunikasi dengan database.
Langkah selanjutnya sekarang adalah menerapkan migrasi yang kami hasilkan ke database:
python manage.py migrate
Outputnya harus seperti ini:
Operations to perform:
Apply all migrations: admin, auth, boards, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying boards.0001_initial... OK
Applying sessions.0001_initial... OK
Karena ini adalah pertama kalinya kami memigrasi basis data,
migrate
perintah itu juga menerapkan file migrasi yang ada dari aplikasi contrib Django, yang tercantum dalam INSTALLED_APPS
. Ini diharapkan.
Baris
Applying boards.0001_initial... OK
adalah migrasi yang kami hasilkan di langkah sebelumnya.
Itu dia! Basis data kami siap digunakan.

Catatan: Penting untuk dicatat bahwa SQLite adalah database berkualitas-produksi. SQLite digunakan oleh banyak perusahaan di ribuan produk, seperti semua perangkat Android dan iOS, semua browser Web utama, Windows 10, macOS, dll.
Hanya saja tidak cocok untuk semua kasus. SQLite tidak bisa dibandingkan dengan database seperti MySQL, PostgreSQL atau Oracle. Situs web bervolume tinggi, aplikasi intensif, set data sangat besar, konkurensi tinggi, adalah beberapa situasi yang pada akhirnya akan menghasilkan masalah dengan menggunakan SQLite.
Kami akan menggunakan SQLite selama pengembangan proyek kami karena itu nyaman dan kami tidak perlu menginstal yang lain. Ketika kami menyebarkan proyek kami ke produksi, kami akan beralih ke PostgreSQL. Untuk situs web sederhana ini berfungsi dengan baik. Tetapi untuk situs web yang kompleks, disarankan untuk menggunakan database yang sama untuk pengembangan dan produksi.
Bereksperimen dengan API Model
Salah satu keuntungan besar pengembangan dengan Python adalah shell interaktif. Saya menggunakannya sepanjang waktu. Ini cara cepat untuk mencoba berbagai hal dan bereksperimen dengan perpustakaan dan API.
Anda dapat memulai shell Python dengan proyek kami dimuat menggunakan utilitas manage.py :
python manage.py shell
Python 3.6.2 (v3.6.2:5fd33b5, Jul 8 2017, 04:57:36) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>
Ini sangat mirip dengan memanggil konsol interaktif hanya dengan mengetik
python
, kecuali ketika kami menggunakan python manage.py shell
, kami menambahkan proyek kami ke sys.path
dan memuat Django. Itu berarti kita dapat mengimpor model kita dan sumber daya lainnya dalam proyek dan bermain dengannya.
Mari kita mulai dengan mengimpor kelas Board :
from boards.models import Board
Untuk membuat objek papan baru, kita dapat melakukan hal berikut:
board = Board(name='Django', description='This is a board about Django.')
Untuk mempertahankan objek ini dalam database, kita harus memanggil
save
metode:board.save()
The
save
metode yang digunakan baik untuk membuat dan memperbarui objek. Di sini Django membuat objek baru karena instance Board tidak memiliki id . Setelah menyimpannya untuk pertama kalinya, Django akan mengatur id secara otomatis:board.id
1
Anda bisa mengakses bidang lainnya sebagai atribut Python:
board.name
'Django'
board.description
'This is a board about Django.'
Untuk memperbarui nilai yang bisa kami lakukan:
board.description = 'Django discussion board.'
board.save()
Setiap model Django hadir dengan atribut khusus; kami menyebutnya Manajer Model . Anda dapat mengaksesnya melalui atribut Python
objects
. Ini digunakan terutama untuk mengeksekusi query dalam database. Misalnya, kita dapat menggunakannya untuk secara langsung membuat objek Dewan baru :board = Board.objects.create(name='Python', description='General discussion about Python.')
board.id
2
board.name
'Python'
Jadi, saat ini kami memiliki dua papan. Kita dapat menggunakan
objects
untuk mendaftar semua papan yang ada dalam database:Board.objects.all()
<QuerySet [<Board: Board object>, <Board: Board object>]>
Hasilnya adalah QuerySet . Kita akan belajar lebih banyak tentang itu nanti. Pada dasarnya, ini adalah daftar objek dari database. Kita dapat melihat bahwa kita memiliki dua objek, tetapi kita hanya dapat membaca objek Board . Itu karena kami belum mendefinisikan
__str__
metode dalam model Dewan .
The
__str__
metode adalah representasi String dari objek. Kita dapat menggunakan nama papan untuk mewakilinya.
Pertama, keluar dari konsol interaktif:
exit()
Sekarang edit file models.py di dalam aplikasi papan :
class Board(models.Model):
name = models.CharField(max_length=30, unique=True)
description = models.CharField(max_length=100)
def __str__(self):
return self.name
Mari kita coba kueri lagi. Buka konsol interaktif lagi:
python manage.py shell
from boards.models import Board
Board.objects.all()
<QuerySet [<Board: Django>, <Board: Python>]>
Jauh lebih baik, bukan?
Kami dapat memperlakukan QuerySet ini seperti daftar. Katakanlah kita ingin mengulanginya dan mencetak deskripsi setiap papan:
boards_list = Board.objects.all()
for board in boards_list:
print(board.description)
Hasilnya adalah:
Django discussion board.
General discussion about Python.
Demikian pula, kita bisa menggunakan model Manager untuk menanyakan database dan mengembalikan satu objek. Untuk itu kami menggunakan
get
metode:django_board = Board.objects.get(id=1)
django_board.name
'Django'
Tetapi kita harus berhati-hati dengan operasi semacam ini. Jika kami mencoba mendapatkan objek yang tidak ada, misalnya, papan dengan
id=3
, itu akan menimbulkan pengecualian:board = Board.objects.get(id=3)
boards.models.DoesNotExist: Board matching query does not exist.
Kita dapat menggunakan
get
metode dengan bidang model apa saja, tetapi lebih disukai menggunakan bidang yang secara unik dapat mengidentifikasi objek. Jika tidak, kueri dapat mengembalikan lebih dari satu objek, yang akan menyebabkan pengecualian.Board.objects.get(name='Django')
<Board: Django>
Perhatikan bahwa kueri peka huruf besar-kecil , huruf kecil "django" tidak akan cocok:
Board.objects.get(name='django')
boards.models.DoesNotExist: Board matching query does not exist.
Ringkasan Operasi Model
Temukan di bawah ini ringkasan metode dan operasi yang kami pelajari di bagian ini, menggunakan model Dewan sebagai referensi. Papan Huruf Besar mengacu pada kelas, papan huruf kecil mengacu pada instance (atau objek) dari kelas model Papan :
Operasi | Contoh kode |
---|---|
Buat objek tanpa menyimpan | board = Board() |
Simpan suatu objek (buat atau perbarui) | board.save() |
Membuat dan menyimpan objek dalam database | Board.objects.create(name='...', description='...') |
Daftar semua benda | Board.objects.all() |
Dapatkan satu objek, yang diidentifikasi oleh bidang | Board.objects.get(id=1) |
Di bagian selanjutnya, kita akan mulai menulis pandangan dan menampilkan papan kita di halaman HTML.
Tampilan, Templat, dan File Statis
Saat ini kami sudah memiliki tampilan bernama
home
menampilkan "Halo, Dunia!" Di beranda aplikasi kami.
myproject / urls.py
from django.conf.urls import url
from django.contrib import admin
from boards import views
urlpatterns = [
url(r'^$', views.home, name='home'),
url(r'^admin/', admin.site.urls),
]
papan / views.py
from django.http import HttpResponse
def home(request):
return HttpResponse('Hello, World!')
Kita bisa menggunakan ini sebagai titik awal kita. Jika Anda mengingat gambar rangka kami, Gambar 5 menunjukkan bagaimana tampilan beranda. Yang ingin kami lakukan adalah menampilkan daftar papan di sebuah meja bersama dengan beberapa informasi lainnya.
Hal pertama yang harus dilakukan adalah mengimpor model Dewan dan mendaftar semua papan yang ada:
papan / views.py
from django.http import HttpResponse
from .models import Board
def home(request):
boards = Board.objects.all()
boards_names = list()
for board in boards:
boards_names.append(board.name)
response_html = '<br>'.join(boards_names)
return HttpResponse(response_html)
Dan hasilnya adalah halaman HTML sederhana ini:

Tapi mari kita berhenti di sini. Kami tidak akan terlalu jauh merender HTML seperti ini. Untuk tampilan sederhana ini, yang kita butuhkan hanyalah daftar papan; maka bagian rendering adalah pekerjaan untuk Mesin Templat Django .
Pengaturan Mesin Template Django
Membuat folder bernama baru template bersama dengan papan dan mysite folder:
myproject/
|-- myproject/
| |-- boards/
| |-- myproject/
| |-- templates/ <-- here!
| +-- manage.py
+-- venv/
Sekarang di dalam folder template , buat file HTML bernama home.html :
templates / home.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Boards</title>
</head>
<body>
<h1>Boards</h1>
{% for board in boards %}
{{ board.name }} <br>
{% endfor %}
</body>
</html>
Pada contoh di atas kami mencampur HTML mentah dengan beberapa tag khusus dan . Mereka adalah bagian dari Bahasa Templat Django. Contoh di atas menunjukkan bagaimana cara mengulangi daftar objek menggunakan a . The menjadikan nama dewan dalam template HTML, menghasilkan dokumen HTML yang dinamis.
{% for ... in ... %}
{{ variable }}
for
{{ board.name }}
Sebelum kita dapat menggunakan halaman HTML ini, kita harus memberi tahu Django di mana menemukan template aplikasi kita.
Buka settings.py di dalam direktori myproject dan cari
TEMPLATES
variabel dan atur DIRS
kunci untuk os.path.join(BASE_DIR, 'templates')
:TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(BASE_DIR, 'templates')
],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
Pada dasarnya apa yang dilakukan baris ini adalah menemukan path lengkap direktori proyek Anda dan menambahkan "/ templat" ke sana.
Kita dapat men-debug ini menggunakan shell Python:
python manage.py shell
from django.conf import settings
settings.BASE_DIR
'/Users/vitorfs/Development/myproject'
import os
os.path.join(settings.BASE_DIR, 'templates')
'/Users/vitorfs/Development/myproject/templates'
Lihat? Itu hanya menunjuk ke folder template yang kami buat di langkah sebelumnya.
Sekarang kita dapat memperbarui tampilan beranda :
papan / views.py
from django.shortcuts import render
from .models import Board
def home(request):
boards = Board.objects.all()
return render(request, 'home.html', {'boards': boards})
HTML yang dihasilkan:

Kami dapat meningkatkan templat HTML untuk menggunakan tabel sebagai gantinya:
templates / home.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Boards</title>
</head>
<body>
<h1>Boards</h1>
<table border="1">
<thead>
<tr>
<th>Board</th>
<th>Posts</th>
<th>Topics</th>
<th>Last Post</th>
</tr>
</thead>
<tbody>
{% for board in boards %}
<tr>
<td>
{{ board.name }}<br>
<small style="color: #888">{{ board.description }}</small>
</td>
<td>0</td>
<td>0</td>
<td></td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>

Menguji Beranda

Ini akan menjadi subjek yang berulang, dan kami akan mengeksplorasi bersama berbagai konsep dan strategi di seluruh seri tutorial ini.
Mari kita tulis tes pertama kami. Untuk saat ini, kami akan bekerja di file tests.py di dalam aplikasi papan :
papan / tests.py
from django.core.urlresolvers import reverse
from django.test import TestCase
class HomeTests(TestCase):
def test_home_view_status_code(self):
url = reverse('home')
response = self.client.get(url)
self.assertEquals(response.status_code, 200)
Ini adalah test case yang sangat sederhana tetapi sangat berguna. Kami sedang menguji kode statusdari respons. Kode status 200 berarti sukses .
Kami dapat memeriksa kode status respons di konsol:

Jika ada pengecualian, kesalahan sintaks, atau apa pun yang tidak tertangkap, Django akan mengembalikan kode status 500 , yang berarti Galat Server Internal . Sekarang, bayangkan aplikasi kita memiliki 100 tampilan. Jika kami menulis hanya tes sederhana ini untuk semua tampilan kami, dengan hanya satu perintah, kami akan dapat menguji apakah semua tampilan mengembalikan kode sukses, sehingga pengguna tidak melihat pesan kesalahan di mana pun. Tanpa tes otomatis, kita perlu memeriksa setiap halaman, satu per satu.
Untuk menjalankan test suite Django:
python manage.py test
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.
----------------------------------------------------------------------
Ran 1 test in 0.041s
OK
Destroying test database for alias 'default'...
Sekarang kita dapat menguji apakah Django mengembalikan fungsi tampilan yang benar untuk URL yang diminta. Ini juga merupakan tes yang berguna karena seiring perkembangan kami, Anda akan melihat bahwa modul urls.py bisa menjadi sangat besar dan kompleks. Konfigurasi URL adalah tentang menyelesaikan regex. Ada beberapa kasus di mana kami memiliki URL yang sangat permisif, sehingga Django akhirnya dapat mengembalikan fungsi tampilan yang salah.
Inilah cara kami melakukannya:
papan / tests.py
from django.core.urlresolvers import reverse
from django.urls import resolve
from django.test import TestCase
from .views import home
class HomeTests(TestCase):
def test_home_view_status_code(self):
url = reverse('home')
response = self.client.get(url)
self.assertEquals(response.status_code, 200)
def test_home_url_resolves_home_view(self):
view = resolve('/')
self.assertEquals(view.func, home)
Dalam tes kedua, kami menggunakan
resolve
fungsi tersebut. Django menggunakannya untuk mencocokkan URL yang diminta dengan daftar URL yang tercantum dalam modul urls.py. Tes ini akan memastikan URL /
, yang merupakan URL root, mengembalikan tampilan beranda.
Uji lagi:
python manage.py test
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
..
----------------------------------------------------------------------
Ran 2 tests in 0.027s
OK
Destroying test database for alias 'default'...
Untuk melihat lebih detail tentang pelaksanaan tes, atur verbosity ke level yang lebih tinggi:
python manage.py test --verbosity=2
Creating test database for alias 'default' ('file:memorydb_default?mode=memory&cache=shared')...
Operations to perform:
Synchronize unmigrated apps: messages, staticfiles
Apply all migrations: admin, auth, boards, contenttypes, sessions
Synchronizing apps without migrations:
Creating tables...
Running deferred SQL...
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying boards.0001_initial... OK
Applying sessions.0001_initial... OK
System check identified no issues (0 silenced).
test_home_url_resolves_home_view (boards.tests.HomeTests) ... ok
test_home_view_status_code (boards.tests.HomeTests) ... ok
----------------------------------------------------------------------
Ran 2 tests in 0.017s
OK
Destroying test database for alias 'default' ('file:memorydb_default?mode=memory&cache=shared')...
Verbosity menentukan jumlah pemberitahuan dan informasi debug yang akan dicetak ke konsol; 0 tidak ada output, 1 adalah output normal, dan 2 adalah output verbose.
Pengaturan File Statis
File statis adalah CSS, JavaScripts, Fonts, Images, atau sumber daya lain apa pun yang dapat kita gunakan untuk menyusun antarmuka pengguna.
Karena itu, Django tidak melayani file-file itu. Kecuali selama proses pengembangan, sehingga membuat hidup kita lebih mudah. Tetapi Django menyediakan beberapa fitur untuk membantu kami mengelola file statis. Fitur-fitur tersebut tersedia di aplikasi django.contrib.staticfiles yang sudah terdaftar dalam
INSTALLED_APPS
konfigurasi.
Dengan begitu banyak pustaka komponen front-end yang tersedia, tidak ada alasan bagi kami untuk terus merender dokumen HTML dasar. Kami dapat dengan mudah menambahkan Bootstrap 4 ke proyek kami. Bootstrap adalah toolkit sumber terbuka untuk dikembangkan dengan HTML, CSS, dan JavaScript.
Di direktori root proyek, bersama dengan papan , templat , dan folder myproject , buat folder baru bernama statis , dan di dalam folder statis buat yang lain bernama css :
myproject/
|-- myproject/
| |-- boards/
| |-- myproject/
| |-- templates/
| |-- static/ <-- here
| | +-- css/ <-- and here
| +-- manage.py
+-- venv/

Unduh versi Kompilasi CSS dan JS .
Di komputer Anda, ekstrak file bootstrap-4.0.0-beta-dist.zip yang Anda unduh dari situs web Bootstrap, salin file css / bootstrap.min.css ke folder css proyek kami:
myproject/
|-- myproject/
| |-- boards/
| |-- myproject/
| |-- templates/
| |-- static/
| | +-- css/
| | +-- bootstrap.min.css <-- here
| +-- manage.py
+-- venv/
Langkah selanjutnya adalah menginstruksikan Django di mana menemukan file statis. Buka settings.py , gulir ke bagian bawah file dan setelah itu
STATIC_URL
, tambahkan berikut ini:STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
Sama dengan
TEMPLATES
direktori, ingat?
Sekarang kita harus memuat file statis (file CSS Bootstrap) dalam template kita:
templates / home.html
{% load static %}<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Boards</title>
<link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
</head>
<body>
<!-- body suppressed for brevity ... -->
</body>
</html>
Pertama kita memuat tag template Aplikasi File Statis dengan menggunakan di awal template.
{% load static %}
Tag templat digunakan untuk membuat URL tempat sumber daya itu hidup. Dalam hal ini, akan mengembalikan /static/css/bootstrap.min.css , yang setara dengan http://127.0.0.1:8000/static/css/bootstrap.min.css.
{% static %}
{% static 'css/bootstrap.min.css' %}
The tag template menggunakan konfigurasi di settings.py untuk menyusun URL final. Misalnya, jika Anda meng-host file statis Anda di subdomain seperti https://static.example.com/ , kami akan mengatur maka akan mengembalikan https://static.example.com/css/bootstrap.min.css.
{% static %}
STATIC_URL
STATIC_URL=https://static.example.com/
{% static 'css/bootstrap.min.css' %}
Jika tidak ada yang masuk akal untuk Anda saat ini, jangan khawatir. Ingatlah untuk menggunakan setiap kali Anda perlu merujuk ke file CSS, JavaScript atau gambar. Nantinya, ketika kami mulai bekerja dengan Penempatan, kami akan membahas lebih banyak tentangnya. Untuk saat ini, kita semua sudah siap.
{% static %}
Menyegarkan halaman 127.0.0.1:8000 kita bisa melihatnya bekerja:

Sekarang kita dapat mengedit templat sehingga memanfaatkan CSS Bootstrap:
{% load static %}<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Boards</title>
<link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
</head>
<body>
<div class="container">
<ol class="breadcrumb my-4">
<li class="breadcrumb-item active">Boards</li>
</ol>
<table class="table">
<thead class="thead-inverse">
<tr>
<th>Board</th>
<th>Posts</th>
<th>Topics</th>
<th>Last Post</th>
</tr>
</thead>
<tbody>
{% for board in boards %}
<tr>
<td>
{{ board.name }}
<small class="text-muted d-block">{{ board.description }}</small>
</td>
<td class="align-middle">0</td>
<td class="align-middle">0</td>
<td></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</body>
</html>
Hasilnya sekarang:

Sejauh ini kami menambahkan papan baru menggunakan konsol interaktif (
python manage.py shell
). Tetapi kita membutuhkan cara yang lebih baik untuk melakukannya. Di bagian selanjutnya, kita akan mengimplementasikan antarmuka admin untuk administrator situs web mengelolanya.Pengantar Django Admin
Ketika kami memulai proyek baru, Django sudah dikonfigurasi dengan Admin Django yang terdaftar di
INSTALLED_APPS
.
Contoh penggunaan yang baik dari Admin Django misalnya di blog; dapat digunakan oleh penulis untuk menulis dan menerbitkan artikel. Contoh lain adalah situs web e-commerce, di mana anggota staf dapat membuat, mengedit, menghapus produk.
Untuk saat ini, kita akan mengkonfigurasi Admin Django untuk mempertahankan papan aplikasi kita.
Mari kita mulai dengan membuat akun administrator:
python manage.py createsuperuser
Ikuti petunjuk:
Username (leave blank to use 'vitorfs'): admin
Email address: admin@example.com
Password:
Password (again):
Superuser created successfully.
Sekarang buka URL di browser web: http://127.0.0.1:8000/admin/

Masukkan nama pengguna dan kata sandi untuk masuk ke antarmuka administrasi:

Sudah dilengkapi dengan beberapa fitur yang dikonfigurasi. Di sini kita dapat menambahkan Pengguna dan Grup untuk mengelola izin. Kami akan mengeksplorasi lebih dari konsep-konsep itu nanti.
Untuk menambah model Board sangat mudah. Buka file admin.py di direktori papan , dan tambahkan kode berikut:
papan / admin.py
from django.contrib import admin
from .models import Board
admin.site.register(Board)
Simpan file admin.py , dan segarkan halaman di browser web Anda:

Dan itu dia! Sudah siap digunakan. Klik tautan Papan untuk melihat daftar papan yang ada:

Kami dapat menambahkan papan baru dengan mengklik tombol Tambahkan Papan :

Klik pada tombol simpan :

Kami dapat memeriksa apakah semuanya berfungsi membuka URL http://127.0.0.1:8000 :

Kesimpulan
Dalam tutorial ini, kami mengeksplorasi banyak konsep baru. Kami menetapkan beberapa persyaratan untuk proyek kami, membuat model pertama, memigrasikan basis data, mulai bermain dengan API Model. Kami menciptakan tampilan pertama kami dan menulis beberapa tes unit. Kami juga mengkonfigurasi Mesin Templat Django, File Statis, dan menambahkan perpustakaan Bootstrap 4 ke proyek. Akhirnya, kami memiliki pengantar singkat antarmuka Django Admin.
Saya harap Anda menikmati bagian kedua dari seri tutorial ini! Bagian ketiga akan keluar minggu depan, pada 18 Sep 2017. Di bagian berikutnya, kita akan menjelajahi perutean URL Django, form API, templat yang dapat digunakan kembali, dan lebih banyak pengujian. Jika Anda ingin mendapat pemberitahuan saat bagian ketiga keluar
Kode sumber proyek tersedia di GitHub. Keadaan saat ini dari proyek dapat ditemukan di bawah tag rilis v0.2-lw . Tautan di bawah ini akan membawa Anda ke tempat yang tepat:
Komentar
Posting Komentar