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 renderfrom django.http import HttpResponsedef 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 adminfrom django.urls import pathimport blog.views as bvurlpatterns = [ 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 adminfrom django.urls import path,includeimport blog.views as bvurlpatterns = [ path('admin/' , admin.site.urls), path('index/' , include('blog.urls' )), ]
新blog.urls.py
1 2 3 4 5 6 7 from django.urls import pathfrom . import viewsurlpatterns = [ 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 renderfrom django.http import HttpResponsedef 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
字段创建
字段即类里面的属性(变量)
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 Articleadmin.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%} {%endfor%}
修改views.py
1 2 3 4 5 6 7 from django.shortcuts import renderfrom django.http import HttpResponsefrom . import modelsdef 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 renderfrom django.http import HttpResponsefrom . import modelsdef 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}) `` 参数写在相应函数中request后,可以有默认值 修改blog下的urls.py ```py from django.urls import pathfrom . import viewsurlpatterns = [ 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 adminfrom django.urls import path,includeimport blog.views as bvurlpatterns = [ 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 ArticleArticle.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 adminfrom .models import Articleclass 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 modelsclass 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花了我半个小时…