Django入门-简易博客
慕课网课程:django入门与实践学习笔记
安装Django
pip install Django
新建项目
django-admin startproject HelloWorld
新建app
进入manage.py所在目录:
python manage.py startapp blog
然后在settings.py文件中加入新建的app:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog',
]
注意:新建的App名称不能和Django已有的App名称冲突。
配置Url
首先在blog下的views.py文件中定义处理请求的方法:
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
def index(request):
return HttpResponse("Hello World!")
然后配置URL:
方式一 直接添加
在HelloWorld目录下的urls.py文件中,先导入刚才修改的views.py文件,然后添加相应的url:
from django.contrib import admin
from django.urls import path,include
from blog import views
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index),
]
运行后就可以通过localhost:8000/index/访问,可以看到返回的Hello Word!。
方式二 通过include添加
先在刚刚新建的app blog目录下新建一个urls.py文件,在这里配置这个app相应的urls:
from django.urls import path
from . import views
urlpatterns = [
path('index/', views.index),
]
然后在HelloWorld目录下的urls.py文件中导入django.urls.include,通过include的方式将刚才新建的urls.py文件引入:
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include("blog.urls")),
]
这时运行后通过localhost:8000/blog/index/访问,注意与方式一的差别。
创建Templates
在blog的目录下新建templates目录,然后在blog/templates目录下新建blog目录(这样做是为了防止多个app下模板名冲突)。
然后在blog/templates/blog/下新建模板:index.html:
Title
{{ hello }}
然后在views.py下处理请求时返回这个模板页面的内容,需要用到render,修改之前的views.py文件为:
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
return render(request, 'blog/index.html', {'hello': 'Hello, Blog!'})
这里使用render返回模板内容,render中前两个参数是必填参数,还有其他几个非必填的参数,其中这里用到一个Dict字典,即{'hello': 'Hello, Blog!'},在模板index.html中,会自动填入hello对应的值。
创建Models
在Django中,一个Model对应数据库的一张数据表,Models以类的形式表现,包含一些基本字段及数据的一些行为。
新建
首先在应用根目录blog下创建models.py,引入django.db.models模块:
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=32, default='Title')
content = models.TextField(null=True)
这里创建了一个Article类,包含两个字段title和content,CharField和TextField表示对应的数据类型,default可以传入一个默认值,null=True表示可以为空。官方文档
生成数据表
生成数据迁移:
python manage.py makemigrations appName(可选)
迁移:
python manage.py migrate
在blog/migrations文件夹下可以看到生成了一个迁移文件0001_initial.py
然后可以使用命令python manage.py sqlmigrate appName fileId查看SQL语句:
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;
数据库文件保存在db.sqlite3中,可以使用第三方软件查看(SQLite Expert Personal轻量级且完全免费)。
Ubuntu系统下可以安装sqlite3,在命令行中直接操作数据库文件。
Ubuntu下sqlite3的安装和使用
安装:
sudo apt-get install sqlite3
简单使用:
创建和打开数据库:
sqlite3 test.db
如果当前目录存在test.db则会打开,否则会在当前目录创建test.db文件
查看数据表:
```sql lite
.tables
创建数据表``create table 表名(字段名)``:
```sql lite
create table class(ID int primary key , name text);
查看表中字段信息.schema 表名:
```sql lite
.schema class
删除表``drop table 表名``:
```sql lite
drop table class;
添加记录insert into (列名1,列名2..) 表名 values( ):
```sql lite
insert into class values (1, ‘Mike’);
删除记录``delete from 表名 where 条件``:
```sql lite
delete from class where ID = 1;
修改记录update 表名 set column1=value1,... where 条件:
```sql lite
update class set name=’Jack’ where ID=1
查询记录``select 指定字段 from 表名 where 条件``:
```sql lite
select * from class
调整显示格式:
```sql lite
.header on
.mode column
select * from class;
退出:
```sql lite
.quit
页面呈现数据
通过sqlite工具可以看到db.sqlite3数据库中自动生成了一些表,其中包括blog_article表,就是对应的Article模型。
先在blog_article表中插入一段记录:
```sql lite
insert into blog_article values (‘Hello’, ‘Hello,Blog!’);
然后就是将这条记录展示在页面上,首先在``views.py``中导入``models``包,然后取出主键为1的数据:
```python
from . import models
article = models.Article.objects.get(pk=1)
通过render传递给前端:
from django.shortcuts import render
from . import models
def index(request):
article = models.Article.objects.get(pk=1)
return render(request, 'blog/index.html', {'article': article})
前端的模板可以直接使用对象及对象的"."操作,修改模板index.html如下:
Title
{{ article.title }}
{{ article.content }}
在浏览器中访问就可以看到内容了。
Admin
Admin是Django自带的自动化数据管理界面,被授权的用户可以直接在Admin中管理数据库
配置Admin
创建超级用户
python manage.py createsuperuser
输入用户名、邮箱、密码(至少8位)
打开localhost:8000/admin/就可以访问
(修改settings.py中的LANGUAGE_CODE = 'zh_Hans'可将界面改为中文)
配置应用
在应用下的admin.py中引入自身的models模块(或里面的模型类),然后注册模型类,编辑blog目录下的admin.py:
from django.contrib import admin
from .models import Article
admin.site.register(Article)
浏览器中刷新以下就可以看到Article了,点击进去可以很方便的管理Article的内容了。
修改数据默认显示名称
在点开Article管理它的所有实例时,看到每一个实例显示的是Article Object,这样不方便识别。
在Article类下添加一个方法,Python3.6添加__str__(self),Python2.7添加__unicode__(self)方法,修改models.py文件:
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=32, default='Title')
content = models.TextField(null=True)
def __str__(self):
return self.title
这里返回的是文章的标题,那么在Article的管理界面,每一个Article的实例都会显示它的标题。
博客主页面
展示所有文章的列表
模板For循环:
{% for xx in xxs %}
HTML语句
{% endfor %}
取出所有的文章,修改views.py:
from django.shortcuts import render
from django.http import HttpResponse
from . import models
def index(request):
# article = models.Article.objects.get(pk=1)
articles = models.Article.objects.all()
return render(request, 'blog/index.html', {'articles': articles})
展示文章列表,修改index.html:
Title
新文章
{% for article in articles %}
{{ article.title }}
{% endfor %}
(超链接先暂时空着)
文章内容页面
先添加一个文章内容的模板,在blog/templates/blog/目录下新建article_page.html:
Article Page
{{ article.title }}
{{ article.content }}
修改文章
在views.py文件中新增一个article_page方法,接收文章主键:
def article_page(request, article_id):
article = models.Article.objects.get(pk=article_id)
return render(request, 'blog/article_page.html', {'article': article})
这里根据文章主键获取到对应的文章,传递给article_page.html模板。
配置Url,修改urls.py:
urlpatterns = [
path('index/', views.index),
path('article//', views.article_page)
]
article/后面匹配一个数字,比如article/1/,表示文章的ID。在浏览器中访问localhost:8000/blog/article/1/就可以看到第一篇文章的内容。
Django中的超链接
template中的超链接:
{% url 'app_name:url_name' param %}
其中app_name和url_name都在url中配置:
- 在根
urls.py里,为应用添加命名空间,写在include()函数的第二个参数位置,namespace='blog' - 在应用下的
urls.py里,添加url的名称,写在url()/path()函数的第三个参数位置,``name=’article’
修改HelloWorld/urls.py:
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include("blog.urls", namespace='blog')),
]
修改blog/urls.py,注意最下面要加上app_name='blog':
urlpatterns = [
path('index/', views.index),
path('article//', views.article_page, name='article_page'),
]
app_name = 'blog'
然后修改index.html配置超链接:
新文章
{% for article in articles %}
{{ article.title }}
{% endfor %}
然后通过点击文章标题,就可以跳转到文章内容页面了。
博客编写页面
首先新建一个模板文件edit_page.html:
Edit Page
然后在views.py中添加一个响应函数:
def edit_page(request):
return render(request, 'blog/edit_page.html')
在urls.py中配置url:
path('edit/', views.edit_page)
基本配置完成后,就需要编写一个响应函数,处理Post请求:
获取Post表单数据:request.POST.get('name', 'DefaultValue')或request.POST['参数名']
Django新建Article数据:models.Article.objects.create(title=title, content=content)
在views.py中添加新的响应函数:
def edit_action(request):
# 默认值设置为'TITLE','CONTENT'
title = request.POST.get('title', 'TITLE')
content = request.POST.get('content', 'CONTENT')
# 新建一个Article
models.Article.objects.create(title=title, content=content)
# 返回到主页
articles = models.Article.objects.all()
return render(request, 'blog/index.html', {'articles': articles})
修改urls.py添加url并添加url的名称:
from django.urls import path
from . import views
urlpatterns = [
path('index/', views.index, name='index'),
path('article//', views.article_page, name='article_page'),
path('edit/', views.edit_page, name='edit_page'),
path('edit/action/', views.edit_action, name='edit_action')
]
app_name = 'blog'
然后修改edit_page.html文件,为表单添加action:
其中csrf_token用于防止跨站请求伪造,凡是用到POST的表单,都需要添加这样一句话。(在hexo里,行级代码不能出现({+%+内容+%+} )这种语法,可能是模板语法的冲突,在块级代码中没事)
博客编写页面完成,可以为主页index.html的新文章链接添加一个超链接:
新文章
这里还有一个小问题,就是每次刷新的时候都会新建一个article,而且都是默认值,解决办法如下:
修改views.py,导入HttpResponseRedirect和reverse模块:
from django.http import HttpResponseRedirect
from django.urls import reverse
修改edit_action函数如下:
def edit_action(request):
# 默认值设置为'TITLE','CONTENT'
title = request.POST.get('title', 'TITLE')
content = request.POST.get('content', 'CONTENT')
# 新建一个Article
models.Article.objects.create(title=title, content=content)
# 返回到主页
return HttpResponseRedirect(reverse('blog:index'))
修改文章
由于Article的id是由1开始递增,利用这个特点,我们可以复用edit_page.html来同时作为编写文章和修改文章的页面。即编写文章时,传入文章id为0;修改文章则将这篇文章的id传进去。
修改views.py的edit_page()方法:
def edit_page(request, article_id):
if str(article_id) == '0':
# 传入的id
return render(request, 'blog/edit_page.html')
article = models.Article.objects.get(pk=article_id)
return render(request, 'blog/edit_page.html', {'article': article})
修改urls.py,在edit_page的url添加接收article_id:
path('edit//', views.edit_page, name='edit_page'),
然后在index.html和article_page.html中链接到edit_page的超链接传入文章id:
新文章
{% for article in articles %}
{{ article.title }}
{% endfor %}
{{ article.title }}
{{ article.content }}
修改文章
在edit_page.html中根据article_id判断是新建还是修改,修改的话要设置标题和内容:
<input type="hidden" name="article_id" value="">和<input type="hidden" name="article_id" value="0">是为了传递给edit_action()函数,用于判断是修改还是新建。然后修改views.py中的edit_action()函数:
def edit_action(request):
# 默认值设置为'TITLE','CONTENT'
title = request.POST.get('title', 'TITLE')
content = request.POST.get('content', 'CONTENT')
article_id = request.POST.get('article_id', 0)
if article_id == '0':
# 新建一个Article
models.Article.objects.create(title=title, content=content)
# 返回到主页
return HttpResponseRedirect(reverse('blog:index'))
else:
# 修改文章内容
article = models.Article.objects.get(pk=article_id)
article.title = title
article.content = content
article.save()
# 跳转到文章页面
return render(request, 'blog/article_page.html', {'article': article})
补充内容
Templates过滤器
过滤器写在模板中,属于Django模板语言,可以修改模板中的变量,从而显示不同的内容
{{ value | filter }}
过滤器可叠加:
{{ value | filter1 | filter2 | ... }}
edit_page.html页面的代码可以简写为:
利用过滤器默认传递article_id的值为0,省去了冗余的if_else代码。另外value=""这里不用使用过滤器,因为article不存在的话得到的是空值,在这里显示空值不会有问题。
Django Shell
是一个Python的交互式命令行程序,自动引入了我们的项目环境,我们可以使用它与我们的项目进行交互。
使用Django Shell:
python manage.py shell
进入Django Shell交互环境后,可以直接使用命令与项目交互,比如:
>>> from blog.models import Article
>>> Article.objects.all()
, , , , , , , , , ]>
>>>
这里直接打印出了之前创建的所有Articles记录
Django Shell的作用:
- 我们可以使用Django Shell来进行一些调试工作
- 可以用来测试一些未知的方法
Admin增强
在admin.py中创建admin配置类class ArticleAdmin(admin.ModelAdmin),在注册时和Article绑定admin.site.register(Article, ArticleAdmin)
然后在ArticleAdmin类中进行配置,比如显示其他字段list_display或者设置过滤器list_filter。
为了效果明显,先给Article新增一个pub_time字段,修改models.py:
class Article(models.Model):
title = models.CharField(max_length=32, default='Title')
content = models.TextField(null=True)
pub_time = models.DateField(auto_now=True)
def __str__(self):
return self.title
pub_time作为发布时间,自动设置。然后别忘了数据迁移:
python manage.py makemigrations
python manage.py migrate
然后修改admin.py:
class ArticleAdmin(admin.ModelAdmin):
# 显示的字段
list_display = ('title', 'content', 'pub_time')
# 过滤器
list_filter = ('pub_time',)
admin.site.register(Article, ArticleAdmin)
现在在admin中管理Article就可以看到这三个字段,并且由于设置了pub_time过滤器,右侧会出现一个pub_time的过滤器,可以点击Yesterday、Today、Past 7 days等等选项。