Django入門與實踐
Django介紹
- 什么是Django:
Django是一個基于Python的高級web開發框架,它能夠讓開發人員進行高效且快速的開發。高度集成(不同重復造輪子),免費且開源。
- 搭建環境:
安裝Python,Python官網下載安裝包安裝即可,過程略。
安裝Django:
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple Django==2.2.5
或者下載源碼tar包,進入解壓目錄執行python setup.py install
- 創建項目:
在Windows命令行下(在Linux下也適用),
cd Desktop
mkdir myblog
cd myblog
django-admin startproject myblog #未報錯則創建成功
- 啟動項目:
命令行下,
cd myblog
python manage.py runserver 9999
瀏覽器訪問127.0.0.1:9999
即可訪問django默認頁
Django默認Debug=True
,即在調試模式下,后面無須手動重啟服務器,除非代碼報錯服務器宕掉。
Django Shell
Django Shell是一個Python的交互式命令行程序,它自動引入了項目環境,我們可以使用它與項目進行交互。
在命令行下,執行python manage.py shell
進入Django Shell。
在Django Shell下,可以嘗試一下 Django 為你創建的各種 API。通常使用Django Shell進行一些調試工作,測試未知的方法。
創建應用
- PyCharm打開項目:
使用PyCharm打開桌面上的目錄myblog下的myblog目錄,有個與manage.py
同級的myblog目錄,其中有這些文件:
wsgi.py python應用與wen服務器之間的接口
urls.py url配置文件,所有頁面都需要配置url
settings.py 項目的總配置文件,包含數據庫、web應用、時間等配置
__init__.py python中聲明模塊的文件,內容默認為空
- 創建應用:
打開命令行,進入項目中manage.py
所在的目錄,執行:
python manage.py startapp blog
并添加應用名到settings.py
中的INSTALLED_APPS
中。
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog',
]
應用名不能與python中模塊名相同,否則會創建失敗。
新生成的與manage.py
同級的blog目錄中有這些文件:
migrations 數據移植(遷移)模塊,內容自動生成
__init__.py
__init__.py
admin.py 該應用的后臺管理系統配置
apps.py 該應用的一些配置
models.py 數據模塊,使用ORM框架,類似于MVC結構中的Models
tests.py 自動化測試模塊,在這里編寫測試腳本
views.py 執行響應的代碼所在模塊,代碼邏輯處理的位置
- 創建一個頁面響應:
views.py
from django.shortcuts import render
# Create your views here.
from django.http import HttpResponse
def index(request):
return HttpResponse('Hello World')
urls.py
from django.contrib import admin
from django.urls import path
import blog.views as bv
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', bv.index),
]
瀏覽器訪問127.0.0.1:9999/index/
每個響應對應一個函數,函數必須返回一個響應。函數必須存在一個參數,一般約定為request,每個響應(函數)對應一個url。
每個url都以url的形式寫出來,url函數放在urlpatterns列表中。url函數三個參數:url(正則),對應方法,名稱。
- 重新配置url:
urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls')),
]
同時在blog應用目錄下新增 urls.py
from django.urls import path
from . import views
urlpatterns = [
path('index/', views.index),
]
瀏覽器訪問127.0.0.1:9999/blog/index/
項目的根urls.py針對APP配置的url名稱,是該APP所有url的總路徑。
開發Template
Django的Template就是一個個的HTML文件,使用了Django模板語言(DTL),template可以使用第三方模板(如Jinja2)。
- 開發一個template:
在應用blog目錄下創建名為Templates
的目錄,在Templates目錄下創建index.html文件。
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Hello, Blog!</h1>
</body>
</html>
接著在views.py中返回render()
from django.shortcuts import render
# Create your views here.
from django.http import HttpResponse
def index(request):
return render(request, 'index.html')
瀏覽器訪問127.0.0.1:9999/blog/index/
- DTL初步使用:
render()
函數中支持一個dict類型參數,該字典是后臺傳遞到模板的參數,key為參數名,在模板中直接通過{{參數名}}
來使用參數。
views.py
from django.shortcuts import render
# Create your views here.
from django.http import HttpResponse
def index(request):
return render(request, 'index.html', {'hello': 'Hello, Blog!!!'})
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>{{ hello }}</h1>
</body>
</html>
瀏覽器訪問127.0.0.1:9999/blog/index/
- Django查找template:
Django按照INSTALLED_APPS
中的添加順序查找template,不同APP下Templates目錄中的同名html文件會造成沖突。
解決沖突:
在APP的Templates目錄下創建以APP名為名稱的目錄,將html文件放入該目錄下。
views.py
from django.shortcuts import render
# Create your views here.
from django.http import HttpResponse
def index(request):
return render(request, 'blog/index.html', {'hello': 'Hello, Blog123!'})
瀏覽器訪問127.0.0.1:9999/blog/index/
編寫Models
通常,一個Model對應數據庫的一張數據表。Django中Models以類的形式表現,它包含一些基本字段以及數據的一些行為。
ORM即對象關系映射(Object Relation Mapping),實現了對象和數據庫之間的映射,隱藏了數據訪問的細節,不需要編寫SQL語句。
- 編寫models:
在應用blog目錄下的 models.py(默認已引入models模塊)中創建類,繼承models.Model
,該類即為一張數據表,在類中創建屬性(變量)即相當于在數據表中創建字段。
models.py
from django.db import models
# Create your models here.
class Article(models.Model):
title = models.CharField(max_length=32, default='Title')
content = models.TextField(null=True)
- 生成數據表
命令行下進入manage.py
同級目錄,執行
python manage.py makemigrations app名(可選)
python manage.py migrate
這里可以不加應用名,就是為項目下的所有應用生成數據表。
Django會自動在app名/migrations/
目錄下生成移植文件。命令行下查看SQL語句,執行
python manage.py sqlmigrate app名 文件id
- 查看并編輯db.sqlite3:
使用第三方軟件SQLite EXpert Personal,打開與manage.py
同級的db.sqlite3文件。
找到blog_article這個表,使用+
添加一行:title為Hello
,content為Hello, Blog!
,再使用√
保存即可。
- 頁面呈現數據:
views.py
from django.shortcuts import render
from . import models
def index(request):
#獲取主鍵為1的article
article = models.Article.objects.get(pk=1)
return render(request, 'blog/index.html', {'article': article})
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>{{article.title}}</h1>
<h3>{{article.content}}</h3>
</body>
</html>
瀏覽器訪問127.0.0.1:9999/blog/index/
Admin
Admin是Django自帶的一個功能強大的自動化數據管理界面,可授權用戶直接在Admin中管理數據庫。
- 創建超級用戶:
python manage.py createsuperuser
瀏覽器訪問127.0.0.1:9999/admin/
,輸入超級用戶的賬號密碼登錄Admin。
修改Admin界面為中文:修改setting.py中LANGUAGE_CODE = 'zh_Hans'
即可。
- 配置Admin:
在應用blog目錄下的admin.py中引入自身的models模塊(或models模塊中的類)。
admin.py
from django.contrib import admin
# Register your models here.
from . import models
admin.site.register(models.Article)
刷新瀏覽器
修改文章內容
訪問127.0.0.1:9999/blog/index/
- 修改數據默認顯示名稱:
在Admin首頁點擊Articles
之后,會發現數據顯示名稱為Article object (1)
,這不是我們想要的。
models.py
from django.db import models
# Create your models here.
class Article(models.Model):
title = models.CharField(max_length=32, default='Title')
content = models.TextField(null=True)
def __str__(self):
return self.title
刷新瀏覽器
完善博客
- 頁面概要:
需要有博客的主頁面、博客文章內容頁面及博客撰寫頁面。
主頁面內容:文章標題列表(超鏈接)、發布博客按鈕(超鏈接)
- 列表編寫思路:
取出數據庫中所有文章對象
將所有文章對象打包成列表,傳遞到前端
前端頁面把文章以標題超鏈接的形式逐個列出
- 主頁面開發:
views.py
from django.shortcuts import render
from . import models
def index(request):
articles = models.Article.objects.all()
return render(request, 'blog/index.html', {'articles': articles})
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>
<a href="">新的文章</a>
</h1>
{% for article in articles %}
<a href="">{{ article.title }}</a>
<br/>
{% endfor %}
</body>
</html>
訪問127.0.0.1:9999/blog/index/
- 文章頁面開發:
views.py
from django.shortcuts import render
from . import models
def index(request):
articles = models.Article.objects.all()
return render(request, 'blog/index.html', {'articles': articles})
def article_page(request, article_id):
article = models.Article.objects.get(pk=article_id)
return render(request, 'blog/article_page.html', {'article': article})
包含index.html的目錄下創建article_page.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Article Page</title>
</head>
<body>
<h1>{{ article.title }}</h1>
<br/>
<h3>{{ article.content }}</h3>
<br/><br/>
<a href="">修改文章</a>
</body>
</html>
應用blog下的urls.py
from django.urls import path, re_path
from . import views
urlpatterns = [
path('index/', views.index),
re_path(r'^article/(?P<article_id>[0-9]+)$', views.article_page),
]
訪問127.0.0.1:9999/blog/article/1
url正則中的組名必須和views.py中的article_page()
方法的參數名一致。
- 補全主頁面超鏈接的目的地:
項目的urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include(('blog.urls'), namespace='blog')),
]
應用blog的urls.py
from django.urls import path, re_path
from . import views
app_name = 'blog'
urlpatterns = [
path('index/', views.index),
re_path(r'^article/(?P<article_id>[0-9]+)$', views.article_page, name='article_page'),
]
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>
<a href="">新的文章</a>
</h1>
{% for article in articles %}
<a href="{% url 'blog:article_page' article.id %}">{{ article.title }}</a>
<br/>
{% endfor %}
</body>
</html>
訪問127.0.0.1:9999/blog/index/
點擊文章名,自動跳轉到文章頁面。
- 撰寫頁面開發:
views.py
from django.shortcuts import render
from . import models
def index(request):
articles = models.Article.objects.all()
return render(request, 'blog/index.html', {'articles': articles})
def article_page(request, article_id):
article = models.Article.objects.get(pk=article_id)
return render(request, 'blog/article_page.html', {'article': article})
def edit_page(request):
return render(request, 'blog/edit_page.html')
def edit_action(request):
title = request.POST.get('title', 'TITLE')
content = request.POST.get('content', 'CONTENT')
models.Article.objects.create(title=title, content=content)
articles = models.Article.objects.all()
return render(request, 'blog/index.html', {'articles': articles})
應用blog的urls.py
from django.urls import path, re_path
from . import views
app_name = 'blog'
urlpatterns = [
path('index/', views.index),
re_path(r'^article/(?P<article_id>[0-9]+)$', views.article_page, name='article_page'),
re_path(r'^edit/$', views.edit_page, name='edit_page'),
re_path(r'^edit/action$', views.edit_action, name='edit_action'),
]
包含index.html的目錄下創建edit_page.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Edit Page</title>
</head>
<body>
<form action="{% url 'blog:edit_action' %}" method="post">
{% csrf_token %}
<label>文章標題
<input type="text" name="title"/>
</label>
<br/>
<label>文章內容
<input type="text" name="content"/>
</label>
<br/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
訪問127.0.0.1:9999/blog/edit/
輸入文章標題及內容后提交,自動跳轉到博客主頁面
- 補全
新文章
的超鏈接:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>
<a href="{% url 'blog:edit_page' %}">新的文章</a>
</h1>
{% for article in articles %}
<a href="{% url 'blog:article_page' article.id %}">{{ article.title }}</a>
<br/>
{% endfor %}
</body>
</html>
- 補全
修改文章
的超鏈接:
views.py
from django.shortcuts import render
from . import models
def index(request):
articles = models.Article.objects.all()
return render(request, 'blog/index.html', {'articles': articles})
def article_page(request, article_id):
article = models.Article.objects.get(pk=article_id)
return render(request, 'blog/article_page.html', {'article': article})
def edit_page(request, article_id):
if str(article_id) == '0':
return render(request, 'blog/edit_page.html')
article = models.Article.objects.get(pk=article_id)
return render(request, 'blog/edit_page.html', {'article': article})
def edit_action(request):
title = request.POST.get('title', 'TITLE')
content = request.POST.get('content', 'CONTENT')
models.Article.objects.create(title=title, content=content)
articles = models.Article.objects.all()
return render(request, 'blog/index.html', {'articles': articles})
應用blog的usls.py
from django.urls import path, re_path
from . import views
app_name = 'blog'
urlpatterns = [
path('index/', views.index),
re_path(r'^article/(?P<article_id>[0-9]+)$', views.article_page, name='article_page'),
re_path(r'^edit/(?P<article_id>[0-9]+)$', views.edit_page, name='edit_page'),
re_path(r'^edit/action$', views.edit_action, name='edit_action'),
]
article_page.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Article Page</title>
</head>
<body>
<h1>{{ article.title }}</h1>
<br/>
<h3>{{ article.content }}</h3>
<br/><br/>
<a href="{% url 'blog:edit_page' article.id %}">修改文章</a>
</body>
</html>
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>
<a href="{% url 'blog:edit_page' 0 %}">新的文章</a>
</h1>
{% for article in articles %}
<a href="{% url 'blog:article_page' article.id %}">{{ article.title }}</a>
<br/>
{% endfor %}
</body>
</html>
edit_page.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Edit Page</title>
</head>
<body>
<form action="{% url 'blog:edit_action' %}" method="post">
{% csrf_token %}
{% if article %}
<label>文章標題
<input type="text" name="title" value="{{ article.title }}"/>
</label>
<br/>
<label>文章內容
<input type="text" name="content" value="{{ article.content }}"/>
</label>
<br/>
{% else %}
<label>文章標題
<input type="text" name="title"/>
</label>
<br/>
<label>文章內容
<input type="text" name="content"/>
</label>
<br/>
{% endif %}
<input type="submit" value="提交"/>
</form>
</body>
</html>
訪問127.0.0.1:9999/blog/article/1
,點擊修改文章
- 補全
提交
的超鏈接:
views.py
from django.shortcuts import render
from . import models
def index(request):
articles = models.Article.objects.all()
return render(request, 'blog/index.html', {'articles': articles})
def article_page(request, article_id):
article = models.Article.objects.get(pk=article_id)
return render(request, 'blog/article_page.html', {'article': article})
def edit_page(request, article_id):
if str(article_id) == '0':
return render(request, 'blog/edit_page.html')
article = models.Article.objects.get(pk=article_id)
return render(request, 'blog/edit_page.html', {'article': article})
def edit_action(request):
title = request.POST.get('title', 'TITLE')
content = request.POST.get('content', 'CONTENT')
article_id = request.POST.get('article_id', '0')
if article_id == '0':
models.Article.objects.create(title=title, content=content)
articles = models.Article.objects.all()
return render(request, 'blog/index.html', {'articles': articles})
article = models.Article.objects.get(pk=article_id)
article.title, article.content = title, content
article.save()
return render(request, 'blog/article_page.html', {'article': article})
edit_page.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Edit Page</title>
</head>
<body>
<form action="{% url 'blog:edit_action' %}" method="post">
{% csrf_token %}
{% if article %}
<input type="hidden" name="article_id" value="{{ article.id }}"/>
<label>文章標題
<input type="text" name="title" value="{{ article.title }}"/>
</label>
<br/>
<label>文章內容
<input type="text" name="content" value="{{ article.content }}"/>
</label>
<br/>
{% else %}
<input type="hidden" name="article_id" value="0"/>
<label>文章標題
<input type="text" name="title"/>
</label>
<br/>
<label>文章內容
<input type="text" name="content"/>
</label>
<br/>
{% endif %}
<input type="submit" value="提交"/>
</form>
</body>
</html>
訪問127.0.0.1:9999/blog/index
,點擊新文章
,任意填寫標題與內容后提交,然后點開這篇文章修改
使用Templates過濾器
- 使用過濾器:
{{ value | filter }}
{{ value | filter1 | filter2 | filter3 |... }} #過濾器可疊加
edit_page.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Edit Page</title>
</head>
<body>
<form action="{% url 'blog:edit_action' %}" method="post">
{% csrf_token %}
<input type="hidden" name="article_id" value="{{ article.id | default:'0' }}"/>
<label>文章標題
<input type="text" name="title" value="{{ article.title }}"/>
</label>
<br/>
<label>文章內容
<input type="text" name="content" value="{{ article.content }}"/>
</label>
<br/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
使用過濾器可以大大減少代碼量。
智能推薦
Django入門之安裝與創建
Django入門之安裝與創建 Django安裝 命令行安裝 PyCharm安裝 Django基本操作 命令行操作 PyCharm操作 Django主要文件介紹 命令行與PyCharm的區別 setting配置文件介紹 Django安裝 命令行安裝 PyCharm安裝 Django基本操作 命令行操作 PyCharm操作 創建Django項目:New Project選擇Django創建Django項...
django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module.django入門實踐
學django入門的時候碰到個找不到mysqldb這個模塊 ,百度了好久 終于找到答案...
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...
電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!
Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...
猜你喜歡
requests實現全自動PPT模板
http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...
Linux C系統編程-線程互斥鎖(四)
互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...
統計學習方法 - 樸素貝葉斯
引入問題:一機器在良好狀態生產合格產品幾率是 90%,在故障狀態生產合格產品幾率是 30%,機器良好的概率是 75%。若一日第一件產品是合格品,那么此日機器良好的概率是多少。 貝葉斯模型 生成模型與判別模型 判別模型,即要判斷這個東西到底是哪一類,也就是要求y,那就用給定的x去預測。 生成模型,是要生成一個模型,那就是誰根據什么生成了模型,誰就是類別y,根據的內容就是x 以上述例子,判斷一個生產出...
styled-components —— React 中的 CSS 最佳實踐
https://zhuanlan.zhihu.com/p/29344146 Styled-components 是目前 React 樣式方案中最受關注的一種,它既具備了 css-in-js 的模塊化與參數化優點,又完全使用CSS的書寫習慣,不會引起額外的學習成本。本文是 styled-components 作者之一 Max Stoiber 所寫,首先總結了前端組件化樣式中的最佳實踐原則,然后在此基...