Django-blog-demo笔记。
搭建
环境
python 3.7
Django 2.1.5
pycharm
安装
cmd里敲:
1
|
pip install Django==2.1.5
|
创建项目和应用
创建项目
在预想安装博客目录下计入cmd,敲:
1
|
django-admin startproject myblog
|
对应目录下生成一个myblog文件夹。
manage.py:与项目进行交互的命令行工具集的入口
查看所有命令。
启动命令:
1
|
python manage.py runserver
|
浏览器127.0.0.1:8000查看效果。
改端口号:
1
|
python manage.py runserver 8888
|
myblog目录
myblog
|–__init__.py
|–settings.py
|–urls.py
|–wsgi.py
manage.py
wsgi.py
WSGI(Python Web Server Gateway Interface) Python服务器网关接口
Python应用与Web服务器之间的接口
urls.py
URL配置文件
settings.py
项目总配置文件,包含数据库、Web应用、时间等各种配置
__init__.py
内容默认为空
创建应用
打开命令行,进入manage.py同级目录
1
|
python manage.py startapp blog
|
会多一个blog文件夹。
添加应用名到settings.py中的INSTALLED_APPS里
1
2
3
4
5
6
7
8
9
|
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog'
]
|
blog目录
blog
|–migrations
|—-__init__.py
|–__init__.py
|–admin.py
|–apps.py
|–models.py
|–tests.py
|–views.py
migrations 数据移植(迁移)模块,内容自动生成
admin.py 该应用的后台管理系统配置
apps.py 应用配置(Django-1.9以后自动生成)
models.py 数据模块,使用ORM框架,类似于MVC结构中的Models(模型)
test.py 自动化测试模块,在此编写测试脚本(语句)
views.py 执行响应的代码所在模块,代码逻辑处理地(项目大部分代码在此)
Hello World
打开view.py,输入
1
2
3
4
5
|
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
return HttpResponse('Hello World!')
|
即编辑blog.views
每个相应对应一个函数,函数必须返回一个响应
函数必须存在一个参数,一般约定为request
每个相应(函数)对应一个URL
在urls.py中,输入
1
2
3
4
5
6
7
8
9
|
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),
]
|
即编辑urls.py
url函数放在urlpatterns列表中
url函数三个参数:URL(正则),对应方法,名称
运行,输入地址http://localhost:8000/index/ 即可。
第二种URL配置
如果页面很多,都写在根urls.py中就很乱。于是,在根urls.py中引入include,在APP目录下创建urls.py文件,格式与根urls.py相同。
更改后:
1
2
3
4
5
6
7
8
9
|
from django.contrib import admin
from django.urls import path,include
import blog.views as bv
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', include('blog.urls')),
]
|
新blog.urls.py
1
2
3
4
5
6
7
|
from django.urls import path
from . import views
urlpatterns = [
path('', views.index),
]
|
Templates
HTML文件使用了Django模板语言(Django Template Language, DTL)
开发第一个Template
- 在APP的根目录下创建名叫Templates的目录
- 在该目录下创建HTML文件
- 在views.py中返回
render()
html中敲入:
1
2
3
4
5
6
7
8
9
10
|
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Hello blog!</h1>
</body>
</html>
|
修改views.py为:
1
2
3
4
5
|
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
return render(request,'index.html')
|
运行查看效果。
DTL初步使用
render()
函数中支持一个dict类型参数
该字典是后台传递到模板的参数,键为参数名
在模板中使用{{参数名}}
来直接使用
修改views.py
1
2
3
|
...
return render(request,'index.html',{'hello':'Hello blog!'})
...
|
修改html
1
2
3
|
...
<h1>{{hello}}</h1>
...
|
运行查看效果。
Models
通常,一个Model对应数据库的一张数据表
Django中Models以类的形式表现
它包含了一些基本字段以及数据的一些行为
ORM
对象关系映射(Object Relation Mapping)
实现了对象和数据库之间的映射
隐藏了数据访问的细节,不需要编写SQL语句
编写Models
- 在应用根目录下创建models.py,并引入models模块
- 创建类,继承models.Model,该类即是一张数据表
- 在类中创建字段
字段创建
字段即类里面的属性(变量)
1
|
attr = models.CharField(max_length = 64)
|
生成数据表
命令行中进入manage.py同级目录
执行命令
1
2
|
python manage.py makemigrations app名(可选)
python manage.py migrate
|
不加app名默认给所有app进行数据迁移。
cmd将显示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
E:\PythonCode\myblog>python manage.py makemigrations
Migrations for 'blog':
blog\migrations\0001_initial.py
- Create model Article
E:\PythonCode\myblog>python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, blog, 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 admin.0003_logentry_add_action_flag_choices... 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 auth.0009_alter_user_last_name_max_length... OK
Applying blog.0001_initial... OK
Applying sessions.0001_initial... OK
|
生成数据表
查看
Django会自动在app/migrations/目录下生成移植文件
执行命令查看SQL语句
1
|
python manage.py sqlmigrate 应用名 文件id
|
cmd将显示:
1
2
3
4
5
6
7
|
E:\PythonCode\myblog>python manage.py sqlmigrate blog 0001
BEGIN;
--
-- Create model Article
--
CREATE TABLE "blog_article" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "title" varchar(32) NOT NULL, "content" text NULL);
COMMIT;
|
默认sqlite3的数据库在项目根目录下db.sqlite3
查看并编辑db.sqlite3,使用第三方软件,如SQLite Expert Personal
页面呈现数据
后台步骤
views.py中import models
1
2
|
article = models.Article.objects.get(pk = 1)
render(request, page, {'article':article})
|
后端步骤
模板可直接使用对象以及对象的“.”操作
{{article}}
修改html
1
2
3
4
5
6
7
8
9
10
11
|
<!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>
|
运行,查看http://localhost:8000/index/
Admin
Django自带的一个功能强大的自动化数据管理界面
被授权的用户可直接在Admin中管理数据库
Django提供了许多针对Admin的定制功能
配置Admin
创建用户
创建超级用户
1
|
python manage.py createsuperuser
|
之后要求输入用户名
邮箱
密码
Admin入口访问地址:localhost:8000/admin/
如需修改成中文版,修改settings.py中LANGUAGE_CODE = ‘zh_Hans’
(英文:LANGUAGE_CODE = ’en-us’)
配置应用
在应用下admin.py中引入自身的models模块(或里面的模型类)
编辑admin.py
1
2
|
from .models import Article
admin.site.register(models.Article)
|
修改数据
点击Article超链接进入Article列表页面,按页面指示修改。
修改数据默认显示名称
每条都显示的Article object,很不方便,显示文章标题比较好。
- 在Article类下添加一个方法
- 根据Python版本选择__str__(self) (python3以上)或__unicode__(self) (python2.7)
- return self.title
博客开发
页面设计
博客主页面
博客文章内容页面
博客撰写页面
主页面内容
文章标题列表,超链接
发表博客按钮(超链接)
列表编写思路
- 取出数据库中所有文章对象
- 将文章对象们打包成列表,传递到前端
- 前端页面把文章以标题超链接的形式逐个列出
模板For循环
1
2
3
|
{%for xx in xxs%}
# HTML语句
{%endfor%}
|
修改views.py
1
2
3
4
5
6
7
|
from django.shortcuts import render
from django.http import HttpResponse
from . import models
def index(request):
articles = models.Article.objects.all()
return render(request,'index.html',{'articles': articles})
|
修改html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<!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>
|
页面内容
标题
文章内容
修改文章按钮(超链接)
在templates中新增article_page.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<!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>
|
修改views.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
from django.shortcuts import render
from django.http import HttpResponse
from . import models
def index(request):
articles = models.Article.objects.all()
return render(request,'index.html',{'articles': articles})
def article_page(request, article_id):
article=models.Article.objects.get(pk = article_id)
return render(request,'article_page.html',{'article':article})
``
### URL传递参数
参数写在相应函数中request后,可以有默认值
修改blog下的urls.py
```py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index),
path('article/<article_id>', views.article_page),
]
|
顺便把myblog\urls.py里的index改成blog(非必要,只是更符合博客url)
1
2
3
4
5
6
7
8
9
|
from django.contrib import admin
from django.urls import path,include
import blog.views as bv
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls')),
]
|
运行,输入http://localhost:8000/blog/article/1 查看。
超链接
href后是目标地址,template中可用
1
|
{%url 'app_name:url_name' param%}
|
其中app_name和url_name都在url中配置
再配URL
uel函数的名称参数
法一:根urls,写在include()
的第二个参数位置,namespace='blog'
法二:应用下则写在url()
的第三个参数位置,name='article'
主要取决于是否使用include
引用了另一个url配置文件
撰写页面
标题编辑栏
文章内容编辑区域
提交按钮
新建edit_page.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Edit Page</title>
</head>
<body>
<form action="" method="post">
<label>文章标题
<input type="text" name="title"/>
</label>
<br/>
<label>文章内容
<input type="text" name="content"/>
</label>
<br/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
|
views.py新增
1
2
|
def edit_page(request):
return render(request,'edit_page.html')
|
blog\urls.py新增
1
|
path('edit', views.edit_page),
|
运行,输入http://localhost:8000/blog/edit 查看。
编辑相应函数
使用request.POST['参数名']
获取表单数据
models.Article.objects.create(title, content)创建对象
两个编辑页面
思路:新文章为空,修改文章有内容
修改文章页面有文章对象
文章的ID
修改数据
article.title = title
article.save()
修改views.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
def edit_page(request, article_id):
if str(article_id) == '0':
return render(request,'edit_page.html')
article = models.Article.objects.get(pk=article_id)
return render(request, '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, 'index.html', {'articles': articles})
article = models.Article.objects.get(pk=article_id)
article.title = title
article.content = content
article.save()
return render(request,'article_page.html', {'article': article})
|
修改blog\urls.py
1
2
3
4
5
6
|
urlpatterns = [
path('', views.index),
path('article/(?P<article_id>[0-9]+)$', views.article_page,name='article_page'),
path('edit/(?P<article_id>[0-9]+)$', views.edit_page,name='edit_page'),
path('edit/Action$', views.edit_action,name='edit_action'),
]
|
修改article_page.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<!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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<!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.gtml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
<!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>
|
Templates过滤器
写在模板中,属于Django模板语言
可以修改模板中的变量,从而显示不同的内容
使用
e.g.
过滤器可叠加:
1
|
{{value | filter1 | filter2 | ...}}
|
修改edit_page.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<!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 Shell
Python交互式命令行程序,自动引入了项目环境,可使用它与项目进行交互
使用
1
2
3
|
python manage.py shell
from blog.models import Article
Article.objects.all()
|
可以使用它进行调试
测试未知的方法
Admin增强
创建admin配置类
class ArticleAdmin(admin.ModelAdmin)
注册:admin.site.register(Article, ArticleAdmin)
显示其他字段
list_display = (’title’, ‘content’)
list_display同时支持tuple和list
修改admin.py
1
2
3
4
5
6
7
8
|
from django.contrib import admin
from .models import Article
class ArticleAdmin(admin.ModelAdmin):
list_display = ('title', 'content','pub_time')
admin.site.register(Article, ArticleAdmin)
|
修改models.py
1
2
3
4
5
6
7
8
9
10
|
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=32, default='Title')
content=models.TextField(null=True)
pub_time = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
|
如果是
1
|
pub_time = models.DateTimeField(null=True)
|
则可自己设定时间。
修改完代码记得进行数据移植
1
2
|
python manage.py makemigrations
python manage.py migrate
|
过滤器
list_filter = (‘pub_time’,)
注意有个逗号
相关资料
Django API Reference
代码下载
django-blog-demo
hexo天坑:
遇到 两个大括号 以及 一个大括号一个% 一定放入代码行(如下),这样是不行的
。
排查这个bug花了我半个小时…