1. 分析
博客系统核心模块有:
- 用户管理:注册、登录、删改查用户;
- 博文管理:增删改查博文;
需要数据库,本次使用Mysql 5.5, InnoDB引擎。需要支持多用户登录,各自可以管理自己的博文(增删改查),管理是不公开的,但是博文是不需要登录就可以公开浏览的。
2.数据库设计
创建数据库:create database if not exists blog;
用户表user:
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(48) NOT NULL,
`email` varchar(64) NOT NULL,
`password` varchar(128) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
文章表post:
一对多关系:一篇博文属于一个作者,一个作者有多篇博文。如何设计?
content字段的设计:
- 博客选取什么字段类型?
- 多大合适?
- 博文中图片如何处理?
- 适合和其它字段放在同一张表吗?
- 字段类型 : 博文一般很长,不可能只有几百个字符,需要大文本字段。MySQL中,选择TEXT类型,而不是char或者varchar类型。
- 大小 : text类型是65535个字符,如果不够用,选择longtext,有2^32-1个字符长度,足够使用了。
- 图片存储 : 博文就像HTML一样,图片是通过路径信息将图片是嵌入在内容中的,所以保存的内容还是字符串。
- 字段考虑 :content字段存储文本类型大字段,一般不和数据频繁查询的字段放在一张表中,需要拆到另一张表中。
图片来源有2种:
- 外链,通过URL链接访问,本站不用存储该图片,但容易引起盗链问题。
- 本站存储,需要提供博文的在线文本编辑器,提供图片上传到网站存储,并生成图片URL,这个URL嵌入博客正文中。不会有盗链的问题,但要解决众多图片存储问题、水印问题、在线压缩问题、临时或垃圾图片清理 等等难题。
本次博客项目不实现图片功能。
CREATE TABLE `post` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`title` varchar(256) NOT NULL,
`author_id` int(11) NOT NULL,
`postdate` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `author_id` (`author_id`),
CONSTRAINT `fk_post_user` FOREIGN KEY (`author_id`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `content` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`content` text NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `fk_content_post` FOREIGN KEY (`id`) REFERENCES `post` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
3.Django框架
本次使用Django 1.11版本,它也是长期支持版本LTS,请在虚拟环境中安装。在虚拟环境路径中,Lib/site-packages/django/bin下有一个django-admin.py,一起从它开始。$ pip install django==1.11.20
创建django项目:$ django-admin startproject blog .
在pycharm中的terminal中窗口中创建blog项目;上句命令就在当前项目根目录中构建了Django项目的初始文件。 点 代表项目根目录。
重要文件说明:
- manage.py:本项目管理的命令行工具。应用创建、数据库迁移等都使用它完成
- blog/settings.py:本项目的核心配置文件。数据库、中间件、模板等
- blog/urls.py:URL路径映射配置。项目初始,只配置了/admin的路由。
- blog/wsgi:定义WSGI接口信息。部署用,一般无需改动。
数据库配置:
使用数据库,需要修改默认的数据库配置。在主项目的settings.py下的DATABASES。默认使用的sqlite,修改为mysql。
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'blog',
'USER': '用户名',
'PASSWORD': '密码',
'HOST': '192.168.171.128',
'PORT': '3306',
}
}
3.1 MYSQL数据库驱动
Django支持MySQL 5.5+;Django官方推荐使用本地驱动mysqlclient 1.3.7 +
$ pip install mysqlclient
3.2 创建应用
创建用户应用 $ python manage.py startapp user
创建应用后,项目根目录下产生一个user目录,有如下文件:
- admin.py:应用后台管理声明文件
- models.py:模型层Model类定义
- views.py:定义URL响应函数或类
- migrations包:数据迁移文件生成目录
- apps.py:应用的信息定义文件
该应用完成以下功能 :用户注册、登录;
注册应用:
在settings.py中,增加user应用。目的是为了后台管理admin使用,或迁移migrate使用。
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'user',
'post',
]
模型Model:
字段类型:
缺省主键:
缺省情况下,Django的每一个Model都有一个名为id的AutoField字段,如果显式定义了主键,这种缺省主键就不会被创建了。Python之禅中说“显式优于隐式”,所以,尽量使用自己定义 的主键,哪怕该字段名就是id,也是一种不错的选择。
字段选项:
关系类型字段类:
一对多时,自动创建会增加_id后缀。
- 从一访问多,使用对象.小写模型类_set
- 从一访问一,使用对象.小写模型类
访问id,对象.属性_id
3.2.1 创建user的Model类
- 基类 models.Model
- 表名不指定默认使用 <appname>_<model_name> 。使用Meta类修改表名
from django.db import models
# Create your models here.
class User(models.Model):
class Meta:
db_table = 'user'
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=48, null=False)
email = models.CharField(max_length=64, unique=True, null=False)
password = models.CharField(max_length=128, null=False)
def __repr__(self):
return "<User {} {} {} {}>".format(self.id, self.name, self.email, self.password)
__str__ = __repr__
- 迁移Migration:$ python manage.py makemigrations
- 执行迁移生成数据库的表: $ python manage.py migrate
注意修改过Model类就需要重新迁移,然后migrarte,迁移文件的序列号会增加。
另外:迁移的应用必须在settings.py的INSTALLED_APPS中注册。 不要随便删除这些迁移文件,因为后面的改动都是要依据这些迁移文件的。
4.django后台管理
4.1 创建管理员
$ manage.py createsuperuser
填写基本信息:管理员用户名:admin;密码:*************
4.2 本地化
settings.py中设置语言、时区;语言名称可以查看 django\contrib\admin\locale 目录
# LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'zh-Hans' # 中文
# TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = True
4.3 启动WEB Server
$ python manage.py runserver, 默认端口是8000
4.4 登录后台管理
后台登录地址 http://127.0.0.1:8000/admin
4.5 注册应用模块
在user应用的admin.py添加
from django.contrib import admin
from .models import User
# Register your models here.
admin.site.register(User) # 注册
5. 路由
路由功能就是实现URL模式匹配和处理函数之间的映射。路由配置要在项目的urls.py中配置,也可以多级配置,在每一个应用中,建立一个urls.py文件配置路由映射。
url函数 :
- url(regex, view, kwargs=None, name=None),进行模式匹配
- regex: 正则表达式,与之匹配的 URL 会执行对应的第二个参数 view
- view: 用于执行与正则表达式匹配的 URL 请求
- kwargs: 视图使用的字典类型的参数
- name: 用来反向获取 URL
from django.conf.urls import url, include
from django.contrib import admin
from django.http import HttpRequest # , HttpResponse # , JsonResponse
# from django.template import loader
from django.shortcuts import render
import datetime
def index(request: HttpRequest):
"""视图函数:请求进来返回响应"""
new_dict = {
'a': 100,
'b': 0,
'c': list(range(10, 20)),
'd': 'abc',
'date': datetime.datetime.now(),
'f': list(range(1, 10))
}
context = {'content': 'www.magedu.com', 'new_dict': new_dict}
return render(request, 'index.html', context)
urlpatterns = [
url(r'^admin/', admin.site.urls), # url在 2.x版本 re_path
url(r'^$', index),
]
url(r'^index/$', index) : http://127.0.0.1:8000/index/ 可以访问 ;http://127.0.0.1:8000/index 可以访问,但会补一个/
url(r'^index$', index) :http://127.0.0.1:8000/index 可以访问 ;http://127.0.0.1:8000/index/ 不可以访问