วิธีสร้างเว็บแอปพลิเคชันที่เหมาะกับมือถือโดยใช้ Django Framework - ตอนที่ 3
“บทความนี้ได้รับการแก้ไขและอัปเดตด้วย Django เวอร์ชันล่าสุด – พฤษภาคม 2559 ”
ในส่วนที่ 1 ของซีรีส์นี้ คุณได้เรียนรู้วิธีติดตั้งและกำหนดค่า Django ในสภาพแวดล้อมเสมือน และได้สร้างโครงร่างของโปรเจ็กต์แรกของคุณ
จากนั้นในส่วนที่ 2 เราได้สร้างแอปพลิเคชันและแบบจำลองสำหรับออบเจ็กต์ โพสต์ ซึ่งเราได้ย้ายไปยังฐานข้อมูลในภายหลัง สุดท้ายนี้ เราได้แสดงให้คุณเห็นถึงวิธีการรวมแอปพลิเคชันที่สร้างขึ้นใหม่ของคุณเข้ากับอินเทอร์เฟซผู้ใช้การดูแลระบบ Django
บทความเหล่านี้เป็นส่วนหนึ่งของชุด Django:
การติดตั้งและกำหนดค่า Django Web Framework ด้วยสภาพแวดล้อมเสมือน – ส่วนที่ 1
ทบทวนพื้นฐาน Python และการสร้าง Web Application แรกของคุณด้วย Django – ตอนที่ 2
ในคู่มือสุดท้ายนี้ เราจะพูดถึงวิธีเข้าถึงแอปพลิเคชันโดยใช้ UI และวิธีทำให้เหมาะกับอุปกรณ์พกพาทุกประเภท ที่กล่าวว่ามาเริ่มกันเลย
การสร้างวัตถุผ่านอินเทอร์เฟซผู้ดูแลระบบ Django
หากต้องการสร้างออบเจ็กต์ประเภท โพสต์ (โปรดจำไว้ว่านั่นคือโมเดลที่เรากำหนดไว้ใน ส่วนที่ 2 ของซีรีส์นี้) เราจะใช้อินเทอร์เฟซผู้ดูแลระบบ Django
ตรวจสอบให้แน่ใจว่าเว็บเซิร์ฟเวอร์ในตัวของ Django ทำงานบนพอร์ต 8000 (หรือพอร์ตอื่นที่คุณเลือก) โดยเรียกใช้คำสั่งต่อไปนี้จากไดเร็กทอรี myfirstdjangoproject ภายนอก:
cd ~/myfirstdjangoenv/myfirstdjangoproject
python manage.py runserver 0.0.0.0:8000
ตอนนี้เปิดเว็บเบราว์เซอร์ของคุณแล้วชี้ไปที่ http://ip-address:8000/admin
จากนั้นเข้าสู่ระบบโดยใช้ข้อมูลรับรองที่คุณตั้งค่าไว้ในบทความก่อนหน้านี้ และเริ่มเขียนโพสต์ (ซึ่งอีกครั้ง จะสร้างวัตถุประเภท โพสต์ และแทรกข้อมูลที่เกี่ยวข้องลงในฐานข้อมูลพื้นฐาน):
ทำซ้ำขั้นตอน 2 หรือ 3 ครั้ง:
หลังจากที่เราสร้างโพสต์ไปแล้ว มาดูกันว่าเราต้องทำอะไรเพื่อแสดงโพสต์เหล่านั้นโดยใช้เว็บเบราว์เซอร์ของเรา
มุมมองเริ่มต้นของเรา
มุมมองแรกของเรา (~/myfirstdjangoenv/myfirstdjangoproject/myblog/views.py) จะทำหน้าที่กรองออบเจ็กต์ โพสต์ ทั้งหมด และส่งคืนออบเจ็กต์ที่มีค่า whenPublished น้อยกว่าหรือเท่ากับวันที่และเวลาปัจจุบัน (whenPublished__lte=timezone.now()) เรียงลำดับจากมากไปน้อย whenPublished ซึ่งเหมือนกับการพูดว่า “ ล่าสุดก่อน“
ออบเจ็กต์เหล่านี้จะถูกบันทึกลงในตัวแปรที่มีชื่อโพสต์ที่สะดวก และจะถูกส่งกลับ (ระบุเป็น allposts) เพื่อฝังไว้ใน HTML ดังที่เราจะเห็นในส่วนถัดไป:
from django.shortcuts import render
from .models import Post
from django.utils import timezone
def posts(request):
posts = Post.objects.filter(whenPublished__lte=timezone.now()).order_by('-whenPublished')
return render(request, 'myblog/posts.html', {'allposts': posts})
สุดท้ายนี้ ขีดล่างคู่ใน whenPublished__lte
ด้านบนใช้เพื่อแยกฟิลด์ฐานข้อมูล (whenPublished) ออกจากตัวกรองหรือการดำเนินการ (lte=น้อยกว่า กว่า หรือเท่ากัน)
เมื่อเรากำหนดมุมมองเริ่มต้นแล้ว เรามาทำงานกับเทมเพลตที่เกี่ยวข้องกัน
สร้างเทมเพลตสำหรับโครงการแรกของเรา
ปฏิบัติตามคำสั่งและเส้นทางที่ให้ไว้ในส่วนก่อนหน้า เราจะจัดเก็บเทมเพลตเริ่มต้นของเราไว้ใน myblog/templates/myblog ซึ่งหมายความว่าคุณจะต้องสร้างไดเร็กทอรีชื่อ เทมเพลต และไดเร็กทอรีย่อยชื่อ myblog:
cd ~/myfirstdjangoenv/myfirstdjangoproject/myblog
mkdir -p templates/myblog
เราจะเรียกเทมเพลตว่า posts.html
และใส่โค้ดต่อไปนี้ลงไป คุณจะสังเกตเห็นว่าเรากำลังเพิ่มการอ้างอิงออนไลน์ให้กับแบบอักษร jQuery, Bootstrap, FontAwesome และ Google
นอกจากนี้เรายังได้ใส่โค้ด Python ไว้ในวงเล็บปีกกาภายใน HTML โปรดทราบว่าสำหรับโพสต์ทุกประเภท เราจะแสดงชื่อเรื่อง วันที่เผยแพร่ ผู้เขียน และสุดท้ายคือข้อความ สุดท้ายนี้ คุณจะเห็นด้วยสีแดงว่าเราอ้างอิงถึงออบเจ็กต์ที่ส่งคืนผ่าน myblog/views.py:
ตกลง นี่คือไฟล์ posts.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link href='https://fonts.googleapis.com/css?family=Indie+Flower' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Pacifico' rel='stylesheet' type='text/css'>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css" rel="stylesheet" type='text/css'">
<script src="https://code.jquery.com/jquery-2.1.4.min.js">
</script>
<style>
.title {
font-family: 'Indie Flower', serif;
font-size: 30px;
color: #1E90FF;
}
h1 {
font-family: 'Pacifico', serif;
font-size: 45px;
color: #1E90FF;
}
</style>
</head>
<body>
<div class="container"><h1>My blog</h1><br>
{% for post in allposts %}
<div>
<div class="title">{{ post.title }}</div>
<strong>Published on {{ post.whenPublished }} by {{ post.author }}.</strong>
<p>{{ post.text|linebreaks }}</p>
</div>
{% endfor %}
</div>
</body>
</html>
ในเทมเพลตด้านบน ตัวกรองการแบ่งบรรทัดใช้เพื่อแทนที่การขึ้นบรรทัดใหม่ในข้อความธรรมดาด้วย HTML ที่เทียบเท่ากัน (
หรือ
ต่อไป เราต้องตั้งค่าการแมประหว่าง URL ในแอปพลิเคชันของเรากับมุมมองที่เกี่ยวข้องซึ่งส่งคืนข้อมูล โดยสร้างไฟล์ชื่อ urls.py ภายใน myblog โดยมีเนื้อหาดังต่อไปนี้:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.posts, name='posts'),
]
r'^$'
สมควรได้รับคำอธิบายเพิ่มเติมเล็กน้อย r
นำหน้าสั่งให้ Django ถือว่าสตริงที่อยู่ในเครื่องหมายคำพูดเดี่ยวเป็นนิพจน์ทั่วไป
โดยเฉพาะอย่างยิ่ง r'^$'
แสดงถึงสตริงว่าง ดังนั้นเมื่อเราชี้เบราว์เซอร์ของเราไปที่ http://ip-address:8000
(และไม่มีอะไรอื่น) ข้อมูลที่ส่งคืนโดยตัวแปร โพสต์ ภายใน views.py
(อ้างอิงถึงส่วนก่อนหน้า) จะถูกนำเสนอในหน้าแรกของเรา:
สุดท้ายแต่ไม่ท้ายสุด เราจะรวมไฟล์ urls.py ของแอปพลิเคชันบล็อกของเรา (~/myfirstdjangoenv/myfirstdjangoproject/myblog/urls.py) ลงใน urls.py ของโครงการหลักของเรา (~/myfirstdjangoenv/myfirstdjangoproject/myfirstdjangoproject/urls.py):
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'', include('myblog.urls')),
]
จากนั้นเรามาเริ่มเว็บเซิร์ฟเวอร์กันดีกว่า:
cd ~/myfirstdjangoenv/myfirstdjangoproject
python manage.py runserver 0.0.0.0:8000
ตอนนี้เราควรจะสามารถดูรายการโพสต์ที่เราสร้างไว้ก่อนหน้านี้:
ด้วย Bootstrap คุณยังคงสามารถมีการแสดงภาพที่ยอดเยี่ยมในอุปกรณ์ขนาดเล็ก:
สรุป
ตอนนี้เรามาทบทวนแนวคิดที่เราได้กล่าวถึงในบทความนี้และตลอดทั้งซีรีส์นี้กัน:
1. โมเดล แต่ละอันกำหนดวัตถุและแมปไปยังตารางฐานข้อมูล ซึ่งฟิลด์ต่างๆ จะแมปกับคุณสมบัติของวัตถุนั้น ในทางกลับกัน เทมเพลต กำหนดอินเทอร์เฟซผู้ใช้ที่จะแสดงข้อมูลที่ส่งคืนโดยมุมมอง
สมมติว่าเราต้องการแก้ไขโมเดลของเราโดยเพิ่มฟิลด์ชื่อ สรุป ให้กับออบเจ็กต์ โพสต์ ซึ่งเราจะจัดเก็บคำอธิบายสั้น ๆ ของแต่ละโพสต์ (ไม่บังคับ) มาเพิ่มบรรทัดต่อไปนี้ใน myblog/models.py:
summary = models.CharField(max_length=350, blank=True, null=True)
ดังที่เราได้เรียนรู้ในบทความที่แล้ว เราต้องย้ายการเปลี่ยนแปลงไปยังฐานข้อมูล:
python manage.py makemigrations myblog
python manage.py migrate myblog
จากนั้นใช้อินเทอร์เฟซผู้ดูแลระบบเพื่อแก้ไขโพสต์และเพิ่มข้อมูลสรุปโดยย่อในแต่ละโพสต์ สุดท้าย ให้แทนที่บรรทัดต่อไปนี้ในเทมเพลต (posts.html):
<p>{{ post.text|linebreaks }}</p>
กับ
<p>{{ post.summary }}</p>
รีเฟรชหน้าแรกเพื่อดูการเปลี่ยนแปลง:
2. ฟังก์ชัน มุมมอง รับคำขอ HTTP และส่งกลับการตอบสนอง HTTP ในบทความนี้ def โพสต์ (คำขอ) ใน views.py จะทำการเรียกไปยังฐานข้อมูลที่เกี่ยวข้องเพื่อดึงข้อมูลโพสต์ทั้งหมด หากเราต้องการดึงข้อมูลโพสต์ทั้งหมดที่มีคำว่า ansible ในชื่อเรื่อง เราควรแทนที่
posts = Post.objects.filter(whenPublished__lte=timezone.now()).order_by('-whenPublished')
กับ
posts = Post.objects.filter(title__icontains="ansible").order_by('-whenPublished')
ด้วยการแยกอินเทอร์เฟซผู้ใช้ออกจากตรรกะของแอปพลิเคชันในแอปพลิเคชันเว็บ Django ช่วยให้งานดูแลรักษาและขยายขนาดแอปสะดวกขึ้น
3. หากคุณทำตามคำแนะนำที่ให้ไว้ในชุดนี้ โครงสร้างโครงการของคุณควรเป็นดังนี้:
myfirstdjangoenv/myfirstdjangoproject
├── db.sqlite3
├── manage.py
├── myblog
│ ├── admin.py
│ ├── admin.pyc
│ ├── __init__.py
│ ├── __init__.pyc
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ ├── 0001_initial.pyc
│ │ ├── __init__.py
│ │ └── __init__.pyc
│ ├── models.py
│ ├── models.pyc
│ ├── templates
│ │ └── myblog
│ │ └── posts.html
│ ├── tests.py
│ ├── urls.py
│ ├── urls.pyc
│ ├── views.py
│ └── views.pyc
└── myfirstdjangoproject
├── __init__.py
├── __init__.pyc
├── settings.py
├── settings.pyc
├── urls.py
├── urls.pyc
├── wsgi.py
└── wsgi.pyc
ในกรณีที่รายการด้านบนแสดงไม่ถูกต้องในเบราว์เซอร์ของคุณ นี่คือภาพหน้าจอของผลลัพธ์ของคำสั่งต่อไปนี้:
tree myfirstdjangoenv/myfirstdjangoproject
สรุป
แม้ว่าแนวคิดทั้งหมดนี้อาจดูน่ากลัวเล็กน้อยในตอนแรก แต่ฉันรับรองได้เลยว่า Django คุ้มค่ากับความพยายามทั้งหมดที่จำเป็นในการทำความคุ้นเคยกับมัน
ฉันหวังว่าตัวอย่างที่เราใช้ในซีรีส์นี้เพื่อแนะนำให้คุณรู้จักกับกรอบงานเว็บที่โดดเด่นนี้ จะช่วยกระตุ้นให้คุณเรียนรู้เพิ่มเติม หากเป็นเช่นนั้น เอกสารอย่างเป็นทางการของ Django (ซึ่งมีการปรับปรุงอยู่เสมอ) คือจุดเริ่มต้นที่ดีที่สุด
ฉันรับรองได้เลยว่า Django ยังมีอะไรอีกมากมายเกินกว่าที่เราจะครอบคลุมในบทความชุดต่างๆ ได้ ดังนั้นอย่าลังเลที่จะสำรวจและเรียนรู้ด้วยการลงมือทำ!
โปรดส่งข้อความถึงเราพร้อมคำถามหรือข้อเสนอแนะโดยใช้แบบฟอร์มด้านล่าง