ค้นหาเว็บไซต์

วิธีสร้างเว็บแอปพลิเคชันที่เหมาะกับมือถือโดยใช้ 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 ยังมีอะไรอีกมากมายเกินกว่าที่เราจะครอบคลุมในบทความชุดต่างๆ ได้ ดังนั้นอย่าลังเลที่จะสำรวจและเรียนรู้ด้วยการลงมือทำ!

โปรดส่งข้อความถึงเราพร้อมคำถามหรือข้อเสนอแนะโดยใช้แบบฟอร์มด้านล่าง