Django - 複習與功能加強
日期:2020/05/10
講師:Arashi
Outline
-
複習 - 建立APP
-
複習 - 複習 - 建立 Models 與 Admin 帳號
-
複習 - 建立首頁
-
複習 - 建立 Posts
-
複習 - CSS 與 Base
-
功能增加 - Navbar
-
功能增加 - 照片牆
-
功能增加 - Admin 介面調整
-
References
複習 - 建立 APP
設置虛擬環境
$ cd [your project]
$ python -m venv [virtual-environment-name]
$ pip install virtualenv
$ cd [your project]
$ virtualenv [virtual-environment-name]
- Windows
- Mac
進入虛擬環境
$ venv\Scripts\activate
$ source venv/bin/activate
- Windows
- Mac
安裝 Django
(venv) django$ pip install django
(venv) django$ django-admin startproject mysite
venv
mysite
├── manage.py
└── mysite
├── __init__.py
├── settings.py
├── urls.py
├── wsgi.py
└── asgi.py
更改時間與語言設定
LANGUAGE_CODE = 'zh-Hant'
TIME_ZONE = 'Asia/Taipei'
mysite/mysite/settings.py
建立 APP
$ python manage.py startapp trips
venv
mysite/
├── manage.py
├── mysite
└── trips
├── __init__.py
├── admin.py
├── app.py
├── migrations
├── model.py
├── tests.py
└── views.py
設定檔增加剛建立的 APP
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
#新增
'trips',
]
mysite/mysite/settings.py
複習 - 建立 Models 與 Admin 帳號
from django.conf import settings
from django.db import models
from django.utils import timezone
class Post(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField(max_length=200)
text = models.TextField()
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
定義 object
mysite/trips/models.py
$ cd 到 manage.py 在的地方
$ python manage.py makemigrations
$ python manage.py migrate
新增 tables 到 資料庫內
from django.contrib import admin
# 新增
from .models import Post
# 新增
admin.site.register(Post)
設定管理後台
mysite/trips/admin.py
$ python manage.py createsuperuser
建立 Admin 帳號
$ python manage.py runserver
測試看看
複習 - 建立首頁
建立首頁
from django.shortcuts import render
# 新增
from trips.models import Post
# 新增
def home(request):
post_list = Post.objects.all()
return render(request, 'home.html', {
'post_list': post_list,
})
mysite/trips/views.py
建立首頁
from django.contrib import admin
from django.urls import path
# 新增
from trips.views import home
urlpatterns = [
path('admin/', admin.site.urls),
# 新增
path('home/', home),
]
mysite/mysite/urls.py
建立首頁
在trips 同層的資料夾內 建立一個 templates 資料夾
venv
mysite/
├── manage.py
├── mysite
├── trips
└── templates
建立首頁
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My blog</title>
</head>
<body>
<h1>Hello !it is my blog</h1>
<div class="container">
{% for post in post_list %}
<div class="post">
<h2><a href="#">{{ post.title }}</a></h2>
<p>{{ post.created_date }}</p>
<p>{{ post.text }}</p>
</div>
{% endfor %}
</div>
</body>
</html>
mysite/templates/home.html
在 templates 內建立一個 home.html
更改settings.py
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',
],
},
},
mysite/mysite/settings.py
$ python manage.py runserver
測試看看
複習 - 建立 Post
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{{ post.title }} | My Adventure</title>
</head>
<body>
<div class="post">
<h2><a href="#">{{ post.title }}</a></h2>
{{ post.created_date }}
{{ post.text }}
</div>
</body>
</html>
mysite/templates/post.html
建立文章頁面
from django.shortcuts import render
from django.http import HttpResponse
from trips.models import Post
def home(request):
post_list = Post.objects.all()
return render(request, 'home.html', {
'post_list': post_list,
})
# 新增
def post_detail(request, pk):
post = Post.objects.get(pk=pk)
return render(request, 'post.html', {'post':post})
mysite/trips/views.py
建立文章頁面
from django.contrib import admin
# 修改
from django.urls import path, re_path
from trips.views import home, post_detail
urlpatterns = [
path('admin/', admin.site.urls),
path('home/', home),
# 新增
re_path(r'^post/(?P<pk>\d+)/$', post_detail, name="post_detail"),
]
mysite/mysite/urls.py
建立文章頁面
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My blog</title>
</head>
<body>
<h1>Hello !it is my blog</h1>
<div class="container">
{% for post in post_list %}
<div class="post">
<h2><a href="{% url 'post_detail' pk=post.pk %}">{{ post.title }}</a></h2>
<p>{{ post.created_date }}</p>
<p>{{ post.text }}</p>
</div>
{% endfor %}
</div>
</body>
</html>
mysite/templates/home.html
修改 home.html 內的 post 連結
$ python manage.py runserver
測試看看
複習 - CSS 與 Base
建立 CSS 檔案
在 trips 資料夾內建立一個 static 資料夾, 裡面再建立一個 css 資料夾
venv
mysite/
├── manage.py
├── mysite
├── templates
└── trips
├── static
└── css
h1 a {
color: #FCA205;
}
h1{
text-align: center;
}
body p {
font-style:italic;
}
.post {
color: #FCA205;
font-family: 'Dancing Script', cursive;
}
.page-header {
background-color: #A89797;
margin-top: 0;
padding: 20px 20px 20px 40px;
}
.container{
display: flex;
justify-content: space-around;
}
mysite/trips/static/css/blog.css
建立 blog.css
{% load static %}
<html>
<head>
<meta charset="utf-8">
{% block title %}
{% endblock %}
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="{% static 'css/blog.css' %}">
<link href="https://fonts.googleapis.com/css2?family=Dancing+Script:wght@500&display=swap" rel="stylesheet">
</head>
<body>
<div class="page-header">
<h1><a href="/home">My Blog</a></h1>
</div>
{% block content %}
{% endblock %}
</body>
</html>
mysite/templates/base.html
建立 base.html
{% extends "base.html" %}
{% block title %}
<title>test blog</title>
{% endblock %}
{% block content %}
<h1>Hello! this is my blog</h1>
<div class="container">
{% for post in post_list %}
<div class="post">
<h2><a href="{% url 'post_detail' pk=post.pk %}">{{ post.title }}</a></h2>
<p>{{ post.created_date }}</p>
<p>{{ post.text|linebreaksbr|slice:":30" }}</p>
</div>
{% empty %}
<p>敬請期待</p>
{% endfor %}
</div>
{% endblock %}
mysite/templates/home.html
修改 home.html
{% extends "base.html" %}
{% block title %}
<title>{{ post.title }} | test blog</title>
{% endblock %}
{% block content %}
<div class="post">
<h2><a href="#">{{ post.title }}</a></h2>
<p>{{ post.created_date }}</p>
<p>{{ post.text }}</p>
</div>
{% endblock %}
mysite/templates/post.html
修改 post.html
$ python manage.py runserver
測試看看
功能增加 - Navbar

語意標籤
<body>
# 增加
<nav class="navbar">
<a class="navbar-brand" href="/home">My blog</a>
<a class="navbar-brand" href="/showImg">My Image</a>
<a class="navbar-brand" href="https://github.com/arashi1214">My github</a>
<a class="navbar-brand" href="/admin">Sign in</a>
</nav>
{% block content %}
{% endblock %}
</body>
mysite/templates/base.html
.navbar {
list-style-type: none;
margin: 0;
padding: 0;
background-color: #FCA205;
}
.navbar a{
color: #FFFFFF;
}
mysite/trips/static/css/blog.css
加上 CSS
功能增加 - 照片牆
pip install pillow
安裝 pillow 套件
更改settings.py
STATIC_URL = '/static/'
# 新增
MEDIA_ROOT = os.path.join(BASE_DIR, 'media').replace('\\', '/')
MEDIA_URL = '/media/'
mysite/mysite/settings.py
為了讓 Django 知道該去哪裡抓照片
# 新增
class Img(models.Model):
img_url = models.ImageField(upload_to='img')
定義 Img object
mysite/trips/models.py
$ cd 到 manage.py 在的地方
$ python manage.py makemigrations
$ python manage.py migrate
更新資料庫
from django.shortcuts import render
# 修改
from trips.models import Post, Img
def home(request):
post_list = Post.objects.all()
return render(request, 'home.html', {
'post_list': post_list,
})
def post_detail(request, pk):
post = Post.objects.get(pk=pk)
return render(request, 'post.html', {'post':post})
# 新增顯示圖片
def showImg(request):
imgs = Img.objects.all()
context = {
'imgs' : imgs
}
return render(request, 'showImg.html', context)
新增顯示的頁面
mysite/trips/views.py
from django.contrib import admin
# 修改
from .models import Post, Img
admin.site.register(Post)
# 新增
admin.site.register(Img)
設定 Img 的管理後台
mysite/trips/admin.py
from django.contrib import admin
from django.urls import path, re_path
# 修改
from trips.views import home, post_detail, showImg
# 新增
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('home/', home),
re_path(r'^post/(?P<pk>\d+)/$', post_detail, name="post_detail"),
#新增
path('showImg/', showImg)
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
mysite/mysite/urls.py
新增路由
建立照片牆顯示頁面
{% extends "base.html" %}
{% block title %}
<title>展示圖片</title>
{% endblock %}
{% block content %}
{% for item in imgs %}
<img src="{{ item.img_url.url }}", width="150"><br/>
{% endfor %}
{% endblock %}
mysite/templates/showImg.html
在 templates 內建立一個 showImg.html
$ python manage.py runserver
測試看看
功能增加 - Admin 介面調整
檢視網站網址設定

admin.site.site_url = 'http://127.0.0.1:8000/home'
mysite/trips/admin.py
變數 | 功能 |
---|---|
list_display = ( ) | 列表顯示 |
list_filter = ( ) | 列表過濾 |
search_fields = ( ) | 搜尋指定欄位 |
ordering = ( ) | 依照指定欄位排序 |
常見的自定義管理功能
自訂 Admin 介面
from django.contrib import admin
from .models import Post, Img
# 新增
class PostAdmin(admin.ModelAdmin):
list_display = ('title', 'text', 'created_date', 'published_date', 'author_id')
# 修改
admin.site.register(Post, PostAdmin)
admin.site.register(Img)
mysite/trips/admin.py
自訂 Admin 介面
from django.contrib import admin
from .models import Post, Img
# 修改
class PostAdmin(admin.ModelAdmin):
list_filter = ('created_date',)
admin.site.register(Post, PostAdmin)
admin.site.register(Img)
mysite/trips/admin.py
自訂 Admin 介面
from django.contrib import admin
from .models import Post, Img
# 修改
class PostAdmin(admin.ModelAdmin):
search_fields = ('title',)
admin.site.register(Post, PostAdmin)
admin.site.register(Img)
mysite/trips/admin.py
自訂 Admin 介面
from django.contrib import admin
from .models import Post, Img
# 修改
class PostAdmin(admin.ModelAdmin):
ordering = ('text',)
admin.site.register(Post, PostAdmin)
admin.site.register(Img)
mysite/trips/admin.py
References
- ITread,(2019),django上傳圖片,ImageField, Retrieved from:https://reurl.cc/8G6LyR
- 程式前沿,(2019),Django中Model的使用方法教程,Retrieved from:https://reurl.cc/z8p4eV
- Nar x Life,(2018),使用Django框架建置圖片上傳與展示的平台,Retrieved from:https://reurl.cc/kdM3ZG
- Django's blog,(2014),Django筆記(6) - 後台管理系統Admin,Retrieved from:https://reurl.cc/D9KLdO
- Medium,(2018),快速了解HTML語意化標籤,Retrieved from:https://reurl.cc/X6ZNla
- Bootstrap documentaion,(2010),Navbar,Retrieved from:https://getbootstrap.com/docs/4.3/components/navbar/
Thank for listening
Django - 複習與功能加強
By arashi
Django - 複習與功能加強
- 261