配置文件存放位置
/etc/mysql/mysql.conf.d/mysqld.cnf
创建项目以及配置虚拟环境
安装创建虚拟环境的工具
sudo apt install python3-venv
创建合适的文件夹保存项目文件
cd ~/桌面
mkdir django_venv
创建虚拟环境
python3 -m venv bbs_python38
进入项目文件
cd /django_env
激活环境
source ./bin/activate
安装指定版本的django
pip install django==2.7.0
通过IDE查看是否安装成功不退出环境,当前工作目录
python3
import django
django.get_version()
为项目文件创建数据库及数据库用户
以root用户登录数据库
mysql -u root -p
创建数据库
create database django_bbs;
查看数据库
show databases;
创建用户(前为用户后为密码)
create user work identified by ‘django_bbs’;
添加权限
grant all on django_bbs.* to ‘work’@’%’ with grant option;
退出数据库并且以指定身份登录
mysql -u work -p django_bbs
安装创建项目的文件
sudo apt install python-django-common
创建项目(在指定工作路径)
django-admin startproject my_bbs
启动项目
python manage.py runserver
*_修改_settings.py文件*
LANGUAGE_CODE = 'zh-Hans'TIME_ZONE = 'UTC' USE_I18N = TrueUSE_L10N = TrueUSE_TZ = True
修改默认数据库
原有数据
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), }}
修改之后的
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'django_bbs', 'USER': 'work', 'PASSWORD': 'django_bbs', 'HOST': '127.0.0.1', 'PORT': '3306', }}
安装pymysql
解决安装mysqlclient失败的问题
sudo apt install -y mysql-clientsudo apt-get install libmysqlclient-devsudo apt install libssl-devsudo apt install libcrypto++-devpip3 install mysqlclient
安装成功
迁移数据库
cd ~/桌面/django_venv/bbs_python38/my_bbspython manage.py makemigrationspython manage.py migrate
查看迁移文件
登录数据库
show databases;use django_bbs;show tables;
创建超级管理员
python manage.py createsuperuser --username=admin --email=admin@email.com
user : adminpassword:le930067
创建app
python manage.py startapp post
生成项目包版本信息表
pip freeze > requirements.txt
查看版本信息
gedit requirements.txt
常用命令
python manage.py shell
可以快速进入python 命令行
post — app中的项目构建
from django.db import modelsfrom django.contrib.auth.models import User# Create your models here.class BaseModel(models.Model): """ base_model of project post """ class Metal: abstract = True ordering = ['created_time'] created_time = models.DateTimeField(auto_now_add=True, help_text=u'time of creation') # last_modified = models.DateTimeField(auto_now_add=True, help_text='time of creation') def __str__(self): raise NotImplementedErrorclass Topic(BaseModel): """ topics of BBS """ title = models.CharField(max_length=255, unique=True, help_text='label of topics') content = models.TextField(help_text=u'content of topics') is_online = models.BooleanField(default=True, help_text='whether topics is online') user = models.ForeignKey(to=User, to_field='id', on_delete=models.CASCADE, help_text='tables of association') def __str__(self): return '%d : %s' % (self.id, self.title[0:20])class Comment(BaseModel): """ comment of topics """ content = models.CharField(max_length=255, help_text='comment of topics') topic = models.ForeignKey(to=Topic, to_field='id', on_delete=models.CASCADE, help_text=u'table of association topic') up = models.IntegerField(default=0, help_text=u'agree') down = models.IntegerField(default=0, help_text=u'disagree') def __str__(self): return '%d : %s' % (self.id, self.content[0:20])
给项目文件注册app(第一行)
INSTALLED_APPS = [ 'post.apps.PostConfig', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles',]
打印迁移文件
python manage.py sqlmigrate post 0001
迁移文件代码展示
BEGIN;---- Create model BaseModel--CREATE TABLE `post_basemodel` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `created_time` datetime(6) NOT NULL, `last_modified` datetime(6) NOT NULL);---- Create model Comment--CREATE TABLE `post_comment` (`basemodel_ptr_id` integer NOT NULL PRIMARY KEY, `content` varchar(255) NOT NULL, `up` integer NOT NULL, `down` integer NOT NULL);---- Create model Topic_Many--CREATE TABLE `post_topic_many` (`basemodel_ptr_id` integer NOT NULL PRIMARY KEY, `title` varchar(255) NOT NULL UNIQUE, `content` longtext NOT NULL, `is_online` bool NOT NULL, `user_id` integer NOT NULL);---- Add field topic to comment--ALTER TABLE `post_comment` ADD COLUMN `topic_id` integer NOT NULL;ALTER TABLE `post_comment` ADD CONSTRAINT `post_comment_basemodel_ptr_id_27053bac_fk_post_basemodel_id` FOREIGN KEY (`basemodel_ptr_id`) REFERENCES `post_basemodel` (`id`);ALTER TABLE `post_topic_many` ADD CONSTRAINT `post_topic_many_basemodel_ptr_id_0e9c4bdc_fk_post_basemodel_id` FOREIGN KEY (`basemodel_ptr_id`) REFERENCES `post_basemodel` (`id`);ALTER TABLE `post_topic_many` ADD CONSTRAINT `post_topic_many_user_id_ae7619c5_fk_auth_user_id` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`);ALTER TABLE `post_comment` ADD CONSTRAINT `post_comment_topic_id_de2ae665_fk_post_basemodel_id` FOREIGN KEY (`topic_id`) REFERENCES `post_basemodel` (`id`);COMMIT;
检查错误命令
python manage.py check
执行迁移命令
python manage.py migrate
迁移效果
Model
6.2多表继承
# 该字段用来说明多表继承,从SQL生成语句查询可知,django会自动为其添加主键和指向的表格class CategoryTopic(Topic_Many): """ 分类topic """ category = models.CharField(max_length=32, help_text='类别')
Model模块全字段代码
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class BaseModel(models.Model): # 直接继承自基类
"""
post应用中的Model类
"""
class Meta:
abstract = True # 声明这个是个抽象类,无法被实例化,也不会创建数据表
ordering = ['-created_time'] # 排序规则, 按照创建时间逆序排列 先后排序则为['-created_time, last+modified']
created_time = models.DateTimeField(auto_now_add=True, help_text=u'创建时间') # 时间域继承自Model,自动将创建时间锚定为当前时间
last_modified = models.DateTimeField(auto_now_add=True, help_text='修改时间') # 时间域继承自Model,自动将修改时间锚定为当前时间
def __str__(self): # 打印Model实例的样式
raise NotImplementedError
class SignField(models.CharField):
"""
签名 Filed
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) # 需要从其他字段继承,且签名的长度不一
def get_prep_value(self, value):
return "<my_bbs> %s" % value # 从数据库数据表中读取什么数据?特别注意,返回值会作为数据存储到数据表中,所以签名也会被报错到数据表中
class Topic_Many(BaseModel): # 直接继承自基类
"""
BBS论坛发布的话题
"""
title = SignField(max_length=255, unique=True, help_text='话题标题') # 类似于超话可以从人衍生
content = models.TextField(help_text=u'话题内容')
is_online = models.BooleanField(default=True, help_text='话题是否在线')
# user为topic_many的外键,被其引用
user = models.ForeignKey(to=User, to_field='id', on_delete=models.CASCADE, help_text='关联用户表')
unique_together = (('title', 'is_online'), ('title', 'content')) # 联合索引,元组双元素,父子级别
# 测试index参数,这个参数是用来制作索引的
indexes = {
models.Index(fields=['title']), # 指定索引的字段
models.Index(fields=['title', 'is_online'], name='title_is_online_idx')
}
permissions = (
("can_read_topic", "可以阅读话题"),
("can_discuss_topic", "可以评论话题")
)
def default_title(self):
return 'default title'
def __str__(self):
return '%d: %s' % (self.id, self.title[0:20])
# 该字段用来说明多表继承,从SQL生成语句查询可知,django会自动为其添加主键和指向的表格
class CategoryTopic(Topic_Many):
"""
分类topic
"""
category = models.CharField(max_length=32, help_text='类别')
# 基类的代理模型:创建方法,功能:返回逻辑上不同的排序,理论意义在于:不修改基类原始定义,但对代理的增删改差会同步到基类
# 同时代理模型只能继承自一个非抽象的基类,且不能同时继承多个
class ProxyTopic_Many(Topic_Many):
"""代理Topic
"""
class Meta:
ordering = ['id']
proxy = True
def is_topic_many_valid(self):
return 'django' in self.title
class Comment(BaseModel):
"""
BBS话题的评论
"""
content = models.CharField(max_length=255, help_text='话题评论')
topic = models.ForeignKey(to='Topic_Many', to_field='id', on_delete=models.CASCADE, help_text=u'关联话题表')
up = models.IntegerField(default=0, help_text=u'支持')
down = models.IntegerField(default=0, help_text=u'反对')
def __str__(self):
return '%d: %s' % (self.id, self.content[0:20])
class People(models.Model): # 通用字段,用于用户选择双元组,定义在Model内部,是基类么?
MALE = 'm'
FEMALE = 'f'
GENDER_CHOICE = (
(MALE, '男性'),
(FEMALE, '女性')
)
gender = models.CharField(max_length=1, choices=GENDER_CHOICE, default=MALE)
项目settings文件
"""
Django settings for my_bbs project.
Generated by 'django-admin startproject' using Django 2.0.7.
For more information on this file, see
https://docs.djangoproject.com/en/2.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.0/ref/settings/
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '^=qr$i13wl6beju-_o10ntei9za+3n5q7om+6^_s4@z+8j5@*1'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'post.apps.PostConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'my_bbs.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'my_bbs.wsgi.application'
# Database
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'django_bbs',
'USER': 'work',
'PASSWORD': 'django_bbs',
'HOST': '127.0.0.1',
'PORT': '3306',
}
}
# Password validation
# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/2.0/topics/i18n/
LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = False
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/
STATIC_URL = '/static/'