配置文件存放位置

  1. /etc/mysql/mysql.conf.d/mysqld.cnf

创建项目以及配置虚拟环境

安装创建虚拟环境的工具

  1. sudo apt install python3-venv

创建合适的文件夹保存项目文件

  1. cd ~/桌面
  2. mkdir django_venv

创建虚拟环境

  1. python3 -m venv bbs_python38

进入项目文件

  1. cd /django_env

激活环境

  1. source ./bin/activate

安装指定版本的django

  1. pip install django==2.7.0

通过IDE查看是否安装成功不退出环境,当前工作目录

  1. python3
  2. import django
  3. django.get_version()

为项目文件创建数据库及数据库用户

以root用户登录数据库

  1. mysql -u root -p

创建数据库

  1. create database django_bbs;

查看数据库

  1. show databases;

创建用户(前为用户后为密码)

  1. create user work identified by django_bbs’;

添加权限

  1. grant all on django_bbs.* to work’@’%’ with grant option;

退出数据库并且以指定身份登录

  1. mysql -u work -p django_bbs

安装创建项目的文件

  1. sudo apt install python-django-common

创建项目(在指定工作路径)

  1. django-admin startproject my_bbs

启动项目

  1. python manage.py runserver

*_修改_settings.py文件*

  1. LANGUAGE_CODE = 'zh-Hans'TIME_ZONE = 'UTC' USE_I18N = TrueUSE_L10N = TrueUSE_TZ = True

修改默认数据库

原有数据

  1. DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), }}

修改之后的

  1. DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'django_bbs', 'USER': 'work', 'PASSWORD': 'django_bbs', 'HOST': '127.0.0.1', 'PORT': '3306', }}

安装pymysql

解决安装mysqlclient失败的问题

  1. sudo apt install -y mysql-clientsudo apt-get install libmysqlclient-devsudo apt install libssl-devsudo apt install libcrypto++-devpip3 install mysqlclient

安装成功

迁移数据库

  1. cd ~/桌面/django_venv/bbs_python38/my_bbspython manage.py makemigrationspython manage.py migrate

查看迁移文件

登录数据库

  1. show databases;use django_bbs;show tables;

创建超级管理员

  1. python manage.py createsuperuser --username=admin --email=admin@email.com
  1. user : adminpassword:le930067

创建app

  1. python manage.py startapp post

生成项目包版本信息表

  1. pip freeze > requirements.txt

查看版本信息

  1. gedit requirements.txt

常用命令

  1. python manage.py shell

可以快速进入python 命令行

post — app中的项目构建

  1. 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(第一行)

  1. INSTALLED_APPS = [ 'post.apps.PostConfig', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles',]

打印迁移文件

  1. python manage.py sqlmigrate post 0001

迁移文件代码展示

  1. 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;

检查错误命令

  1. python manage.py check

执行迁移命令

  1. python manage.py migrate

迁移效果

Model - 图1

Model

6.2多表继承

  1. # 该字段用来说明多表继承,从SQL生成语句查询可知,django会自动为其添加主键和指向的表格class CategoryTopic(Topic_Many): """ 分类topic """ category = models.CharField(max_length=32, help_text='类别')

Model模块全字段代码

  1. from django.db import models
  2. from django.contrib.auth.models import User
  3. # Create your models here.
  4. class BaseModel(models.Model): # 直接继承自基类
  5. """
  6. post应用中的Model类
  7. """
  8. class Meta:
  9. abstract = True # 声明这个是个抽象类,无法被实例化,也不会创建数据表
  10. ordering = ['-created_time'] # 排序规则, 按照创建时间逆序排列 先后排序则为['-created_time, last+modified']
  11. created_time = models.DateTimeField(auto_now_add=True, help_text=u'创建时间') # 时间域继承自Model,自动将创建时间锚定为当前时间
  12. last_modified = models.DateTimeField(auto_now_add=True, help_text='修改时间') # 时间域继承自Model,自动将修改时间锚定为当前时间
  13. def __str__(self): # 打印Model实例的样式
  14. raise NotImplementedError
  15. class SignField(models.CharField):
  16. """
  17. 签名 Filed
  18. """
  19. def __init__(self, *args, **kwargs):
  20. super().__init__(*args, **kwargs) # 需要从其他字段继承,且签名的长度不一
  21. def get_prep_value(self, value):
  22. return "<my_bbs> %s" % value # 从数据库数据表中读取什么数据?特别注意,返回值会作为数据存储到数据表中,所以签名也会被报错到数据表中
  23. class Topic_Many(BaseModel): # 直接继承自基类
  24. """
  25. BBS论坛发布的话题
  26. """
  27. title = SignField(max_length=255, unique=True, help_text='话题标题') # 类似于超话可以从人衍生
  28. content = models.TextField(help_text=u'话题内容')
  29. is_online = models.BooleanField(default=True, help_text='话题是否在线')
  30. # user为topic_many的外键,被其引用
  31. user = models.ForeignKey(to=User, to_field='id', on_delete=models.CASCADE, help_text='关联用户表')
  32. unique_together = (('title', 'is_online'), ('title', 'content')) # 联合索引,元组双元素,父子级别
  33. # 测试index参数,这个参数是用来制作索引的
  34. indexes = {
  35. models.Index(fields=['title']), # 指定索引的字段
  36. models.Index(fields=['title', 'is_online'], name='title_is_online_idx')
  37. }
  38. permissions = (
  39. ("can_read_topic", "可以阅读话题"),
  40. ("can_discuss_topic", "可以评论话题")
  41. )
  42. def default_title(self):
  43. return 'default title'
  44. def __str__(self):
  45. return '%d: %s' % (self.id, self.title[0:20])
  46. # 该字段用来说明多表继承,从SQL生成语句查询可知,django会自动为其添加主键和指向的表格
  47. class CategoryTopic(Topic_Many):
  48. """
  49. 分类topic
  50. """
  51. category = models.CharField(max_length=32, help_text='类别')
  52. # 基类的代理模型:创建方法,功能:返回逻辑上不同的排序,理论意义在于:不修改基类原始定义,但对代理的增删改差会同步到基类
  53. # 同时代理模型只能继承自一个非抽象的基类,且不能同时继承多个
  54. class ProxyTopic_Many(Topic_Many):
  55. """代理Topic
  56. """
  57. class Meta:
  58. ordering = ['id']
  59. proxy = True
  60. def is_topic_many_valid(self):
  61. return 'django' in self.title
  62. class Comment(BaseModel):
  63. """
  64. BBS话题的评论
  65. """
  66. content = models.CharField(max_length=255, help_text='话题评论')
  67. topic = models.ForeignKey(to='Topic_Many', to_field='id', on_delete=models.CASCADE, help_text=u'关联话题表')
  68. up = models.IntegerField(default=0, help_text=u'支持')
  69. down = models.IntegerField(default=0, help_text=u'反对')
  70. def __str__(self):
  71. return '%d: %s' % (self.id, self.content[0:20])
  72. class People(models.Model): # 通用字段,用于用户选择双元组,定义在Model内部,是基类么?
  73. MALE = 'm'
  74. FEMALE = 'f'
  75. GENDER_CHOICE = (
  76. (MALE, '男性'),
  77. (FEMALE, '女性')
  78. )
  79. gender = models.CharField(max_length=1, choices=GENDER_CHOICE, default=MALE)

项目settings文件

  1. """
  2. Django settings for my_bbs project.
  3. Generated by 'django-admin startproject' using Django 2.0.7.
  4. For more information on this file, see
  5. https://docs.djangoproject.com/en/2.0/topics/settings/
  6. For the full list of settings and their values, see
  7. https://docs.djangoproject.com/en/2.0/ref/settings/
  8. """
  9. import os
  10. # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
  11. BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  12. # Quick-start development settings - unsuitable for production
  13. # See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/
  14. # SECURITY WARNING: keep the secret key used in production secret!
  15. SECRET_KEY = '^=qr$i13wl6beju-_o10ntei9za+3n5q7om+6^_s4@z+8j5@*1'
  16. # SECURITY WARNING: don't run with debug turned on in production!
  17. DEBUG = True
  18. ALLOWED_HOSTS = []
  19. # Application definition
  20. INSTALLED_APPS = [
  21. 'post.apps.PostConfig',
  22. 'django.contrib.admin',
  23. 'django.contrib.auth',
  24. 'django.contrib.contenttypes',
  25. 'django.contrib.sessions',
  26. 'django.contrib.messages',
  27. 'django.contrib.staticfiles',
  28. ]
  29. MIDDLEWARE = [
  30. 'django.middleware.security.SecurityMiddleware',
  31. 'django.contrib.sessions.middleware.SessionMiddleware',
  32. 'django.middleware.common.CommonMiddleware',
  33. 'django.middleware.csrf.CsrfViewMiddleware',
  34. 'django.contrib.auth.middleware.AuthenticationMiddleware',
  35. 'django.contrib.messages.middleware.MessageMiddleware',
  36. 'django.middleware.clickjacking.XFrameOptionsMiddleware',
  37. ]
  38. ROOT_URLCONF = 'my_bbs.urls'
  39. TEMPLATES = [
  40. {
  41. 'BACKEND': 'django.template.backends.django.DjangoTemplates',
  42. 'DIRS': [],
  43. 'APP_DIRS': True,
  44. 'OPTIONS': {
  45. 'context_processors': [
  46. 'django.template.context_processors.debug',
  47. 'django.template.context_processors.request',
  48. 'django.contrib.auth.context_processors.auth',
  49. 'django.contrib.messages.context_processors.messages',
  50. ],
  51. },
  52. },
  53. ]
  54. WSGI_APPLICATION = 'my_bbs.wsgi.application'
  55. # Database
  56. # https://docs.djangoproject.com/en/2.0/ref/settings/#databases
  57. DATABASES = {
  58. 'default': {
  59. 'ENGINE': 'django.db.backends.mysql',
  60. 'NAME': 'django_bbs',
  61. 'USER': 'work',
  62. 'PASSWORD': 'django_bbs',
  63. 'HOST': '127.0.0.1',
  64. 'PORT': '3306',
  65. }
  66. }
  67. # Password validation
  68. # https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators
  69. AUTH_PASSWORD_VALIDATORS = [
  70. {
  71. 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
  72. },
  73. {
  74. 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
  75. },
  76. {
  77. 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
  78. },
  79. {
  80. 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
  81. },
  82. ]
  83. # Internationalization
  84. # https://docs.djangoproject.com/en/2.0/topics/i18n/
  85. LANGUAGE_CODE = 'zh-Hans'
  86. TIME_ZONE = 'UTC'
  87. USE_I18N = True
  88. USE_L10N = True
  89. USE_TZ = False
  90. # Static files (CSS, JavaScript, Images)
  91. # https://docs.djangoproject.com/en/2.0/howto/static-files/
  92. STATIC_URL = '/static/'