环境:Windows 10 (64 位),Python 版本为 3.7.6(64 位),django 版本为 2.2.3
(1)安装python3(我自己是python3.7.6)
(2)虚拟环境搭建(两种方法)
1)virtualenv创建和管理虚拟环境
①安装 virtualenv:pip install virtualenv -i https://pypi.douban.com/simple/
②创建虚拟环境:virtualenv 指定一个非中文目录作为虚拟环境目录
③激活虚拟环境:
2)Pipenv 创建和管理虚拟环境(本次搭建个人博客使用的方式):
①安装 Pipenv:pip install pipenv -i https://pypi.douban.com/simple/
②创建一个文件夹,作为将要开发的博客项目的根目录:D:\Djangobang\DjangoBokeCode
③激活虚拟环境:
cd D:\Djangobang\DjangoBokeCode
pipenv install
pipenv shell
Pipenv 会将虚拟环境创建在 ~/.virtualenvs 目录下,在项目根目录下使用 pipenv --venv
可以查看到项目对应的虚拟环境的具体位置:
(3)安装Django:pipenv install django==2.2.3
测试一下安装是否成功,先在命令行输入 pipenv run python 启动虚拟环境中的 Python 解释器交互界面; 然后输入
import django,如果没有报错就说明 django 安装成功。 通过运行 print(django.get_version())
打印出 django 的版本号
(4)建立Django工程:pipenv run django-admin startproject blogproject 博客工程的代码目录
django-admin startproject 命令用来初始化一个 django 项目,它接收两个参数,第一个是项目名字 blogproject,第二个指定项目生成的位置
(5)在命令行工具里进入到 manage.py 所在目录,即 D:\Djangobang\DjangoBokeCode目录下。
运行 pipenv run python manage.py runserver
命令
出现端口被占用的情况:
解决方法:进入管理员Cmd(Win+R;输入cmd;不直接回车而是ctrl+Shift+enter进入Cmd)netstat -ano|findstr 8000
tasklist |findstr 8124
taskkill /pid 8124 /F
解决端口被占用后重新执行命令
成功开启并在浏览器(http://127.0.0.1:8000/)可以查看到
设置成中文界面,在setting文件下:
LANGUAGE_CODE = ‘zh-hans’
TIME_ZONE =‘Asia/Shanghai’
(6)创建博客应用:pipenv run python manage.py startapp 博客应用名字(打开Pycharm查看)
(7)注册应用:
(1)设计表:分成分类和标签的数据库表:
(2)编写博客模型代码modles.py
from django.db import models
from django.contrib.auth.models import User
class Category(models.Model):
name = models.CharField(max_length=100)
class Tag(models.Model):
name = models.CharField(max_length=100)
class Post(models.Model):
"""
文章的数据库表稍微复杂一点,主要是涉及的字段更多。
"""
# 文章标题
title = models.CharField(max_length=70)
# 文章正文,我们使用了 TextField;对于文章的正文来说可能会是一大段文本,因此使用 TextField 来存储大段文本。
body = models.TextField()
# 这两个列分别表示文章的创建时间和最后一次修改时间,存储时间的字段用 DateTimeField 类型。
created_time = models.DateTimeField()
modified_time = models.DateTimeField()
# 文章摘要,可以没有文章摘要,但默认情况下 CharField 要求我们必须存入数据,否则就会报错。
excerpt = models.CharField(max_length=200, blank=True)
# 这是分类与标签,分类与标签的模型我们已经定义在上面。
category = models.ForeignKey(Category, on_delete=models.CASCADE)
tags = models.ManyToManyField(Tag, blank=True)
# 文章作者,这里 User 是从 django.contrib.auth.models 导入的。
author = models.ForeignKey(User, on_delete=models.CASCADE)
(3)数据库迁移
①生成迁移文件:根据模型类生成创建表的语句 pipenv run python manage.py makemigrations
②执行迁移:根据第一步生成的语句在数据库中创建表 pipenv run python manage.py migrate
注:默认采用sqlite3数据库来存储数据,对于小型博客的存储已经足够
(4)存数据
1)进入shell进行脚本编程:pipenv run python manage.py shell
2)创建一个分类和一个标签:
>>> from blog.models import Category, Tag, Post
>>> c = Category(name='category test')
>>> c.save()
>>> t = Tag(name='tag test')
>>> t.save()
3)创建一篇文章试试,但创建文章之前,我们需要先创建一个 User,用于指定文章的作者。创建 User 的命令 django 已经帮我们写好了,依然是通过 manage.py 来运行。新建一个终端。
①创建超级用户管理员:pipenv run python manage.py createsuperuser
②回到shell编程终端
为文章指定了 title、body 、created_time、modified_time值,并把它和前面创建的 Category 以及 User 关联了起来。允许为空 excerpt、tags 我们就没有为它们指定值了
>>> from blog.models import Category, Tag, Post
>>> from django.utils import timezone
>>> from django.contrib.auth.models import User
# 这里的username记得修改为自己创建的超级管理员登录名
>>> user = User.objects.get(username='Amen')
>>> c = Category.objects.get(name='category test')
>>> p = Post(title='title test', body='body test', created_time=timezone.now(), modified_time=timezone.now(), category=c, author=user)
>>> p.save()
(5)取数据
数据已经存入数据库了,现在要把它们取出来看看:
>>> Category.objects.all()
<QuerySet [<Category: Category object (1)>]>
>>> Tag.objects.all()
<QuerySet [<Tag: Tag object (1)>]>
>>> Post.objects.all()
<QuerySet [<Post: Post object (1)>]>
(6)将数据转化成非对象形式输出(回到models.py)
为每一个model添加一个__str__方法
class Category(models.Model):
...
def __str__(self):
return self.name
class Tag(models.Model):
...
def __str__(self):
return self.name
class Post(models.Model):
...
def __str__(self):
return self.title
(7)该数据和删数据不做演示
(1)在子应用创建blog/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
(2)编写视图函数view.py
from django.http import HttpResponse
def index(request):
return HttpResponse("欢迎访问我的博客首页!")
(3)配置项目URL(blogproject/urls.py)
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('blog.urls')),
]
(1)为模板指定目录
①在根目录新建一个文件夹(和子应用同级)templates用于存放模板;
②在 templates 目录下建立一个名为 blog 的文件夹,用来存放和 blog 应用相关的模板;
③在 templates\blog 目录下建立一个名为 index.html 的文件;
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{ title }}title>
head>
<body>
<h1>{{ welcome }}h1>
body>
html>
④配置指定目录(在setting.py)
(2)使用模板页面
1)修改views函数
from django.shortcuts import render
def index(request):
context = {
'title': '我的博客首页',
'welcome': '欢迎访问我的博客首页',
}
return render(request, 'blog/index.html', context=context)
(1)修改首页视图函数,使用数据库的内容
from django.shortcuts import render
from .models import Post
def index(request):
post_list = Post.objects.all().order_by('-created_time')
context = {
'post_list': post_list
}
return render(request, 'blog/index.html',context=context)
(2)处理静态文件
①下载一套博客模板
②在blog子应用新建文件夹static,再在static文件夹新建一个blog文件夹:把下载的CSS和JavaScript文件夹放进来
(3)替换模板:将自己写的index.html文件替换成下载的index.html
(4)应用静态文件Css和JavaScript对index.html进行修饰
<html>
{% load static %}
<html>
<head>
<title>Black & Whitetitle>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
<link rel="stylesheet" href="{% static 'blog/css/bootstrap.min.css' %}">
<link rel="stylesheet" href="{% static 'blog/css/pace.css' %}">
<link rel="stylesheet" href="{% static 'blog/css/custom.css' %}">
<script src="{% static 'blog/js/jquery-2.1.3.min.js' %}">script>
<script src="{% static 'blog/js/bootstrap.min.js' %}">script>
<script src="{% static 'blog/js/pace.min.js' %}">script>
<script src="{% static 'blog/js/modernizr.custom.js' %}">script>
head>
(5)修改模板替换为数据库内容
①在模板 index.html 中你会找到一系列 article 标签;
②将 index.html 中多余的 article 标签删掉,只留下一个 article 标签,然后写上下列代码:
{% for post in post_list %}
<article class="post post-{{ post.pk }}">
...
article>
{% empty %}
<div class="no-post">暂时还没有发布的文章!div>
{% endfor %}
③定义article标签的值 ,使显示数据库数据
<article class="post post-{{ post.pk }}">
{#替换标题成 post 的 title 属性值#}
<h1 class="entry-title">
<a href="single.html">{{ post.title }}a>
h1>
{#替换分类、文章发布时间、文章作者#}
<div class="entry-meta">
<span class="post-category"><a href="#">{{ post.category.name }}a>span>
<span class="post-date"><a href="#"><time class="entry-date"
datetime="{{ post.created_time }}">{{ post.created_time }}time>a>span>
<span class="post-author"><a href="#">{{ post.author }}a>span>
<span class="comments-link"><a href="#">4 评论a>span>
<span class="views-count"><a href="#">588 阅读a>span>
div>
{#替换成 post 的摘要#}
<div class="entry-content clearfix">
<p>{{ post.excerpt }}p>
<div class="read-more cl-effect-14">
<a href="#" class="more-link">继续阅读 <span class="meta-nav">→span>a>
div>
div>
article>
(1)前面已经创建过了就用前面创建的就可以
(2)运行程序,通过浏览器访问http://127.0.0.1:8000/admin/
(3)注册应用,在blog/admin.py
from django.contrib import admin
from .models import Post, Category, Tag
admin.site.register(Post)
admin.site.register(Category)
admin.site.register(Tag)
(4)点击 Posts 后面的增加按钮,将进入添加 Post 的页面,也就是新增博客文章
(5)刷新http://127.0.0.1:8000可以看到已经将数据读取出来
(1)修改应用名blog/apps.py
from django.apps import AppConfig
class BlogConfig(AppConfig):
name = 'blog'
verbose_name = '博客'
(2)修改表名blog/models.py
class Category(models.Model):
name = models.CharField(max_length=100)
class Meta:
verbose_name = '分类'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
class Tag(models.Model):
name = models.CharField(max_length=100)
class Meta:
verbose_name = '标签'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
class Post(models.Model):
...
author = models.ForeignKey(User, on_delete=models.CASCADE)
class Meta:
verbose_name = '文章'
verbose_name_plural = verbose_name
def __str__(self):
return self.title
(3)修改 post 的表单的 label:label 由定义在 model 中的 Field 名转换,blog/models.py
class Post(models.Model):
title = models.CharField('标题', max_length=70)
body = models.TextField('正文')
created_time = models.DateTimeField('创建时间')
modified_time = models.DateTimeField('修改时间')
excerpt = models.CharField('摘要', max_length=200, blank=True)
category = models.ForeignKey(Category, verbose_name='分类', on_delete=models.CASCADE)
tags = models.ManyToManyField(Tag, verbose_name='标签', blank=True)
author = models.ForeignKey(User, verbose_name='作者', on_delete=models.CASCADE)
from django.contrib import admin
from .models import Post, Category, Tag
class PostAdmin(admin.ModelAdmin):
list_display = ['title', 'created_time', 'modified_time', 'category', 'author']
# 把新增的 Postadmin 也注册进来
admin.site.register(Post, PostAdmin)
admin.site.register(Category)
admin.site.register(Tag)
(5)简化表单信息,系统自动识别作者blog/admin.py
class PostAdmin(admin.ModelAdmin):
list_display = ['title', 'created_time', 'modified_time', 'category', 'author']
fields = ['title', 'body', 'excerpt', 'category', 'tags']
def save_model(self, request, obj, form, change):
obj.author = request.user
super().save_model(request, obj, form, change)
(6)创建时间和修改时间自动填充blog/models.py
from django.utils import timezone
class Post(models.Model):
...
created_time = models.DateTimeField('创建时间', default=timezone.now)
...
def save(self, *args, **kwargs):
self.modified_time = timezone.now()
super().save(*args, **kwargs)