写在前面
上课第17天,打卡:
我想去趟欧洲,看看莱茵河,听听贝多芬的悲伤;
################ # 2017-08-20 - 课上笔记 ################ ‘‘‘ Django流程 1.创建项目: django-admin startproject projectname 2.创建应用: python manage.py startapp appname 3.在控制器(urls.py)创建 url 与视图函数的映射关系(一一对应) 4.创建视图函数,完成逻辑处理 5.从数据库取出集合对象 6.把从数据库里取出的数据变量嵌入到模板里进行渲染 最后Reponse: render/httpresponse - render 进行渲染(Django提供模板语言,方便把变量嵌入到模板里)并返回 - httpresponse 直接返回一个字符串 7.将渲染后的html页面返回给客户端 ‘‘‘ ‘‘‘ python manage.py shell python manage.py dbshell ‘‘‘ ‘‘‘ URL由什么组成:协议 + 域名/ip + 端口 + 路径 eg: http://www.cnblogs.com/yuanchenqi/articles/6811632.html eg: http://www.cnblogs.com/yuanchenqi/articles/6811632.html?a=1 ‘‘‘ ‘‘‘ 别名的使用 urlpatterns = [ url(r‘^register‘,views.index,name=‘reg‘), ] 减少前端和后端的耦合性 因为网站有很多路径,并且存在更改路径的问题 前端页面一直写 reg 即可 <form action="{% url ‘reg‘ %}" method="post"> <p>姓名 <input type="text"></p> <p>密码 <input type="password"></p> <input type="submit"> </form> ‘‘‘ ‘‘‘ 模板/TEMPLATE HTML + 逻辑控制代码 逻辑控制语法 {{ }} 渲染变量 过滤器:{{ var|方法:参数 }} {% %} 渲染标签 {% if %} {% for %} {% url %} {% with %} 起一个短一点的别名 {% verbatim %} 不做渲染 {% load %} ‘‘‘ ‘‘‘ Template和Context对象 >>> python manange.py shell (进入该django项目的环境) >>> from django.template import Context, Template >>> t = Template(‘My name is {{ name }}.‘) >>> c = Context({‘name‘: ‘Stephane‘}) >>> t.render(c) ‘My name is Stephane.‘ ‘‘‘ ‘‘‘ 句点号 深度查询 ‘‘‘ def register(request): if ‘POST‘ == request.method: return HttpResponse(‘注册成功!‘) name = ‘liu‘ l = [1,2,3,4,5] dic = {‘user‘:‘liulixin‘,‘age‘:18} # return render(request,‘register.html‘,{‘name‘:name,‘l‘:l,‘dic‘:dic}) return render(request,‘register.html‘,locals()) ‘‘‘ 变量的过滤器 过滤器:{{ var|方法:参数 }} # 1 add : 给变量加上相应的值 # # 2 addslashes : 给变量中的引号前加上斜线 # # 3 capfirst : 首字母大写 # # 4 cut : 从字符串中移除指定的字符 # # 5 date : 格式化日期字符串 # # 6 default : 如果值是False,就替换成设置的默认值,否则就是用本来的值 # # 7 default_if_none: 如果值是None,就替换成设置的默认值,否则就使用本来的值 import datetime t = datetime.datetime.now() <p>时间:{{ t }}</p> <p>格式化后的时间:{{ t|date:‘Y-m-d‘ }}</p> num = 100 <p>数字+20:{{ num|add:20 }}</p> ‘‘‘ # xxx\django01\app01\templatetags\myTags.py from django import template register = template.Library() @register.filter def filter_multi(num1,num2): return num1*num2 @register.simple_tag def simple_tag_multi(v1,v2): return v1*v2 ‘‘‘ 自定义过滤器 - filter - simple_atg 例如:自定义乘法过滤器 - 在app中创建templatetags包(必须的) - 创建任意 .py 文件,如:myTags.py - 在使用自定义simple_tag和filter的html文件中导入之前创建的 myTags.py :{% load my_tags %} - 使用simple_tag和filter(如何调用) - 在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag. filter 冒号后面只能跟一个参数 但是可以做if条件处理 simple_tag 能够接收多个参数 但是不支持if语句 ‘‘‘ ‘‘‘ 后台管理布局 .header { width: 100%; height: 48px; position: fixed; top: 0; } .left { width: 200px; position: absolute; top: 48px; left: 0; bottom: 0; } .test { overflow: auto; overflow: scroll; } ‘‘‘ ‘‘‘ base.html 是一个模板 xxx {% block content %} {% endblock %} xxx extend模板继承,避免代码冗余 - 在开头写上:{% extends "base.html" %} - 重写content {% block content %} xxx {% endblock %} 如何取父模板的内容? {{ block.super }} ‘‘‘ ‘‘‘ # 数据库和ORM 表与表之间的关系: - 一对一 - 一对多 - 多对多 一对多:通过建外键实现 主表:不依赖任何表的表 子表:含有外键,依赖其他表的表 例如:员工表和部门表(多对一关系) 员工表是子表,部门表是主表 多对多:通过第三张表来实现的,借助两个 Foreign key 实现 一对一:通过建外键 + 唯一约束 实现 在外键字段的基础上增加唯一约束 # ORM DATABASES = { ‘default‘: { ‘ENGINE‘: ‘django.db.backends.mysql‘, ‘NAME‘: ‘books‘, #你的数据库名称 ‘USER‘: ‘root‘, #你的数据库用户名 ‘PASSWORD‘: ‘‘, #你的数据库密码 ‘HOST‘: ‘‘, #你的数据库主机,留空默认为localhost ‘PORT‘: ‘3306‘, #你的数据库端口 } } 项目下的 __init__.py 改驱动 ‘‘‘ ‘‘‘ Publisher.objects.filter(id=xxx) 得到的是一个集合对象:[obj1,obj2,...] Publisher.objects.get(id=xxx) 得到的就是一个对象 ‘‘‘ ‘‘‘ 一对多关系下添加数据的两种方法: - 直接添加 - 先通过条件过滤得到一个主表对象 然后添加 ‘‘‘ ‘‘‘ 配置Django的log 对于每次创建一个对象,想显示对应的raw sql, 需要在settings加上日志记录部分: LOGGING = { ‘version‘: 1, ‘disable_existing_loggers‘: False, ‘handlers‘: { ‘console‘:{ ‘level‘:‘DEBUG‘, ‘class‘:‘logging.StreamHandler‘, }, }, ‘loggers‘: { ‘django.db.backends‘: { ‘handlers‘: [‘console‘], ‘propagate‘: True, ‘level‘:‘DEBUG‘, }, } } ‘‘‘ def __str__(): return self.title # 注意这两种写法的区别: authors = models.ManyToMany(Author) authors = models.ManyToMany("Author") ‘‘‘ 多对多的添加方法: book表和author表 是多对多关系 authors = models.ManyToManyField(Author) # authors = models.ManyToManyField("Author") publisher = models.ForeignKey(Publisher) 因为第三张表示django给创建的,并不在名称空间中 所以只能通过第二种方法进行添加数据 book_obj = Book.objetcs.filter(title=‘python3‘).first() 或者 book_obj = Book.objetcs.filter(title=‘python3‘)[0] author_obj1 = Author.objetcs.get(id=1) author_obj2 = Author.objetcs.get(id=2) book_obj.authors.add(author_obj1,author_obj2) 或者用下面的写法: book_obj.authors.add(*[author_obj1,author_obj2]) # add 是多对多的添加方法 删除所有 authors_all = Author.objetcs.all() book_obj.authors.remove(*authors_all) 添加一些关系 authors_all = Author.objetcs.all() book_obj.authors.add(*authors_all) 注意理解 book_obj.publisher 和 book_obj.authors ‘‘‘ ‘‘‘ # 也可以自己创建第三张表 class Book2Author(models.Model): author=models.ForeignKey("Author") Book= models.ForeignKey("Book") #那么就还有一种方式: author_obj=models.Author.objects.filter(id=2)[0] book_obj =models.Book.objects.filter(id=3)[0] models.Book2Author.objects.create(author_id=1,Book_id=2) s=models.Book2Author(author=author_obj,Book_id=1) s.save() ‘‘‘ ‘‘‘ 删除操作 # MySQL级联删除 Book.objects.filter(id=1).delete() ‘‘‘ ‘‘‘ 修改操作 Book.objects.filter(id=1).update(title="红楼梦") # 值重新赋值title字段信息,效率高 或者 book_obj = Book.objects.filter(id=1).first() book_obj.title = "西游记" book_obj.save() # 所有字段都重新赋值一遍,效率低 ‘‘‘ ‘‘‘ 查询操作 表.objetcs.all() 取到的是QuerySet集合对象 表.objetcs.get() 取到的是Model对象(是QuerySet里的一个元素) 表.objetcs.filter() 取到的是QuerySet集合对象 表.objetcs.values("title") 取到的不是对象,而是把想要的字段封装成键值对的形式返回 [{},{},{}...] ret = Book.objetcs.values("title") ret2 = Book.objetcs.values("title","price") QuerySet存放字典 [{},{},{}...] ret3 = Book.objetcs.values_list("title","price") QuerySet存放列表 [(),(),()...] all() get() filter() first() last() values() values_list() exclude() 排除 order_by() 排序 reverse() 反序 distinct() 去重 count() 计数 exist() 判断是否有记录!!!! ---------------补充------------------- # 查询相关API: # <1>filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 # <2>all(): 查询所有结果 # <3>get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。 #-----------下面的方法都是对查询的结果再进行处理:比如 objects.filter.values()-------- # <4>values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列 model的实例化对象,而是一个可迭代的字典序列 # <5>exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象 # <6>order_by(*field): 对查询结果排序 # <7>reverse(): 对查询结果反向排序 # <8>distinct(): 从返回结果中剔除重复纪录 # <9>values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列 # <10>count(): 返回数据库中匹配查询(QuerySet)的对象数量。 # <11>first(): 返回第一条记录 # <12>last(): 返回最后一条记录 # <13>exists(): 如果QuerySet包含数据,就返回True,否则返回False ---------------补充------------------- 双下划綫条件查询 ---------------了不起的双下划线(__)之单表条件查询---------------- # models.Tb1.objects.filter(id__lt=10, id__gt=1) # 获取id大于1 且 小于10的值 # # models.Tb1.objects.filter(id__in=[11, 22, 33]) # 获取id等于11、22、33的数据 # models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in # # models.Tb1.objects.filter(name__contains="ven") # like模糊查询 # models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感 # # models.Tb1.objects.filter(id__range=[1, 2]) # 范围bettwen and # # startswith,istartswith, endswith, iendswith, ‘‘‘ ‘‘‘ 作业要求: 作者、出版社从数据库遍历拿出来用select展示 如果没有则跳转到添加作者/出版社的页面,添加完再添加书 ajax 实现添加完自动刷新 用bootstrap的模态对话框,给 编辑button添加一个click事件 在update之前需要判断出哪些数据有变更,然后只更新变更过的数据 ‘‘‘
表之表之间的关系: 一对多 外键字段一定是在字表(一对多的多的表)中 Foreign KEY 多对多 在第三张表实现,通过两个Foreign KEY 一对一 在外键字段的基础上增加唯一约束。
# 自定义filter和simple_tag ‘‘‘ 1. 在app中创建templatetags模块 2.创建任意 .py 文件,如:myTags.py 3.在使用自定义simple_tag和filter的html文件中导入之前创建的 myTag.py: {% load myTag %} 4.使用simple_tag和filter(注意如何调用,见后面代码) 5.在settings中的INSTALLED_APPS配置里查看是否有当前app, 没有的话需要自己加上,否则django无法找到自定义的simple_tag. filter 冒号后面只能跟一个参数 但是可以做if条件处理 simple_tag 能够接收多个参数 但是不支持if语句 ‘‘‘ # urls.py from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r‘^admin/‘, admin.site.urls), url(r‘^$‘,views.index), url(r‘^index‘,views.index), url(r‘^register‘,views.register,name=‘reg‘), url(r‘^infomation‘,views.info,name=‘info‘), url(r‘^home‘,views.home,name=‘home‘), ] # xxx/templatetags/myTag.py from django import template register = template.Library() @register.filter def filter_multi(num1,num2): return num1*num2 @register.simple_tag def simple_tag_multi(v1,v2): return v1*v2 # views.py from django.shortcuts import render,HttpResponse,redirect # Create your views here. def index(request): # return HttpResponse("Hello Django!") return render(request,‘index.html‘) def register(request): if ‘POST‘ == request.method: return HttpResponse(‘注册成功!‘) name = ‘liu‘ l = [1,2,3,4,5] dic = {‘user‘:‘liulixin‘,‘age‘:18} # return render(request,‘register.html‘,{‘name‘:name,‘l‘:l,‘dic‘:dic}) import datetime t = datetime.datetime.now() num = 100 s = "<a href=‘#‘>点击</a>" something = "asas asqw d qw123 sdseweq qwqw ret ytsdds asq yty 12ex" info = ‘1024‘ the_url = ‘http://www.baidu.com/?a=1&b=3‘ about = ‘i am liu‘ space = ‘he llo wo r ld‘ return render(request,‘register.html‘,locals()) def info(request): class Person(object): def __init__(self,name,age): self.name = name self.age = age p1 = Person(‘alex‘,34) p2 = Person(‘egon‘,36) p3 = Person(‘eric‘,29) p_list = [p1,p2,p3] li = [666,4,9] return render(request, ‘infomation.html‘, locals()) def home(request): return render(request,‘home.html‘) # infomation.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {% load myTag %} {# 在这里引入myTag模块 #} {% for p in p_list %} <p>{{ p.name }} : {{ p.age }}</p> {% endfor %} <p>{{ li.2 }}</p> <p>{{ li.2|filter_multi:100 }}</p> {# 调用myTag里的filter_multi #} <p>{{ li.2|filter_multi:li.1 }}</p> <p>{{ li.0 }}</p> <p>{% simple_tag_multi 10 li.0 %}</p> {# 调用myTag里的simple_tag_multi #} <p>{% simple_tag_multi 10 8 %}</p> </body> </html> # register.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>{{ name }}</h1> <p>{{ about|upper }}</p> <p>{{ space|cut:‘ ‘ }}</p> <p>{{ space|cut:‘o ‘ }}</p> <p>时间:{{ t }}</p> <p>格式化后的时间:{{ t|date:‘Y-m-d‘ }}</p> <p>数字+20:{{ num|add:20 }}</p> <p>{{ desc|default:‘简介为空‘ }}</p> <p>{{ s }}</p> <p>{{ s|safe }}</p> <p>{{ s|striptags }}</p> {% autoescape off %} {{ s }} {% endautoescape %} <p>{{ something|truncatewords:3 }}</p> <p>{{ something|truncatechars:20 }}</p> {{ info|filesizeformat }}<br> {{ info|first }}<br> {{ info|length }}<br> {{ info|slice:":-1" }}<br> <p>{{ the_url|urlencode }}</p> <form action="{% url ‘reg‘ %}" method="post"> <p>姓名 <input type="text"></p> <p>密码 <input type="password"></p> <input type="submit"> </form> </body> </html>
# 后台管理布局 和 模板继承 # urls.py from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r‘^admin/‘, admin.site.urls), url(r‘^$‘,views.index), url(r‘^index‘,views.index), url(r‘^home‘,views.home,name=‘home‘), ] # 基础模板:base.html # 后台管理布局:注意 header left right三个div的CSS代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .header { width: 100%; height: 60px; background-color: blue; position: fixed; {# 固定好header #} top: 0; left: 0; } .left { width: 200px; position: absolute; {# 固定好左侧菜单 #} top: 60px; left: 0; bottom: 0; background-color: powderblue; } .right { position: absolute; top: 60px; bottom: 0; left: 200px; right: 0; background-color: green; overflow: auto; {# 溢出div的时候显示右侧的滑轮滚动 #} {# overflow: scroll;#} } </style> </head> <body> <div class="header"> </div> <div class="content"> <div class="left"> <a href="/home/">提交</a> {# #} </div> <div class="right"> {% block right-content %} {# 确定好有可能变动的"盒子" #} <h1>qwqqqqqqq</h1> <h1>qwqqqqqqq</h1> <h1>qwqqqqqqq</h1> <h1>qwqqqqqqq</h1> <h1>qwqqqqqqq</h1> <h1>qwqqqqqqq</h1> <h1>qwqqqqqqq</h1> <h1>qwqqqqqqq</h1> <h1>qwqqqqqqq</h1> <h1>qwqqqqqqq</h1> <h1>qwqqqqqqq</h1> <h1>qwqqqqqqq</h1> <h1>qwqqqqqqq</h1> <h1>qwqqqqqqq</h1> <h1>qwqqqqqqq</h1> <h1>qwqqqqqqq</h1> <h1>qwqqqqqqq</h1> <h1>qwqqqqqqq</h1> <h1>qwqqqqqqq</h1> <h1>qwqqqqqqq</h1> <h1>qwqqqqqqq</h1> <h1>qwqqqqqqq</h1> <h1>qwqqqqqqq</h1> <h1>qwqqqqqqq</h1> <h1>qwqqqqqqq</h1> {% endblock %} </div> </div> </body> </html> # views.py def index(request): # return HttpResponse("Hello Django!") return render(request,‘index.html‘) def home(request): return render(request,‘home.html‘) # index.html {% extends "base.html" %} {# 继承base.html模板 #} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {% block right-content %} <h1>index.html</h1> {% endblock %} </body> </html> # home.html {% extends "base.html" %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {% block right-content %} <form action="{% url ‘home‘ %}" method="post"> <p>姓名 <input type="text"></p> <p>密码 <input type="password"></p> <input type="submit"> </form> {% endblock %} </body> </html>
# Django连接MySQL的时候需要注意一点: ‘‘‘ 这是因为django默认你导入的驱动是MySQLdb, 可是MySQLdb对于py3有很大问题, 所以我们需要的驱动是PyMySQL ‘‘‘ 所以,我们只需要找到项目名文件下的__init__,在里面写入: import pymysql pymysql.install_as_MySQLdb()
# 书籍管理系统的 models.py from django.db import models # Create your models here. # 主表 - 出版社信息 class Publisher(models.Model): name = models.CharField(max_length=50) address = models.CharField(max_length=100) email = models.EmailField() website = models.URLField() def __str__(self): return self.name # 主表 - 书籍类别信息 class Category(models.Model): name = models.CharField(max_length=50) def __str__(self): return self.name # 主表 - 作者信息 class Author(models.Model): name = models.CharField(max_length=50) def __str__(self): return self.name # 子表 - 作者详细信息,与 Author 是一对一关系 class AuthorDetail(models.Model): sex = models.BooleanField(max_length=1, choices=((0, ‘男‘),(1, ‘女‘),)) email = models.EmailField() address = models.CharField(max_length=100) birthday = models.DateField() author = models.OneToOneField(Author) # 子表 - 书籍信息;依赖于 Category表 和 Publisher表,是多对一关系 # 依赖于 Author表,是多对多关系 class Book(models.Model): title = models.CharField(max_length=30) authors = models.ManyToManyField(Author) # authors = models.ManyToManyField("Author") category = models.ForeignKey(Category) publisher = models.ForeignKey(Publisher) publish_date = models.DateField() price = models.DecimalField(max_digits=5, decimal_places=2, default=10) description = models.CharField(max_length=5000) def __str__(self): return self.title # python manage.py makemigrations -> 创建数据库 # python manage.py migrate -> 同步数据库 # setting.py """ Django settings for homework project. Generated by ‘django-admin startproject‘ using Django 1.11.4. For more information on this file, see https://docs.djangoproject.com/en/1.11/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/1.11/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/1.11/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = ‘200##-!!hg$&6=d(vy9%1aq&t30xsc133^t3e29r%2yc)-+mor‘ # SECURITY WARNING: don‘t run with debug turned on in production! DEBUG = True ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [ ‘django.contrib.admin‘, ‘django.contrib.auth‘, ‘django.contrib.contenttypes‘, ‘django.contrib.sessions‘, ‘django.contrib.messages‘, ‘django.contrib.staticfiles‘, ‘book.apps.BookConfig‘, ] 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 = ‘homework.urls‘ TEMPLATES = [ { ‘BACKEND‘: ‘django.template.backends.django.DjangoTemplates‘, ‘DIRS‘: [os.path.join(BASE_DIR, ‘templates‘)] , ‘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 = ‘homework.wsgi.application‘ # Database # https://docs.djangoproject.com/en/1.11/ref/settings/#databases # DATABASES = { # ‘default‘: { # ‘ENGINE‘: ‘django.db.backends.sqlite3‘, # ‘NAME‘: os.path.join(BASE_DIR, ‘db.sqlite3‘), # } # } DATABASES = { ‘default‘: { ‘ENGINE‘: ‘django.db.backends.mysql‘, ‘NAME‘: ‘books‘, # 你的数据库名称 ‘USER‘: ‘xxx‘, # 你的数据库用户名 ‘PASSWORD‘: ‘xxx‘, # 你的数据库密码 ‘HOST‘: ‘10.0.0.3‘, # 你的数据库主机,留空默认为localhost ‘PORT‘: ‘3306‘, # 你的数据库端口 } } # Password validation # https://docs.djangoproject.com/en/1.11/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/1.11/topics/i18n/ LANGUAGE_CODE = ‘en-us‘ TIME_ZONE = ‘UTC‘ USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.11/howto/static-files/ STATIC_URL = ‘/static/‘ # 对于每次创建一个对象,想显示对应的raw sql,需要在settings加上日志记录部分: LOGGING = { ‘version‘: 1, ‘disable_existing_loggers‘: False, ‘handlers‘: { ‘console‘:{ ‘level‘:‘DEBUG‘, ‘class‘:‘logging.StreamHandler‘, }, }, ‘loggers‘: { ‘django.db.backends‘: { ‘handlers‘: [‘console‘], ‘propagate‘: True, ‘level‘:‘DEBUG‘, }, } } 最后生成的数据表: ... book_author book_authordetail book_book book_book_authors book_category book_publisher ... mysql> desc book_book; +--------------+---------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+---------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | title | varchar(30) | NO | | NULL | | | publish_date | date | NO | | NULL | | | price | decimal(5,2) | NO | | NULL | | | description | varchar(5000) | NO | | NULL | | | category_id | int(11) | NO | MUL | NULL | | | publisher_id | int(11) | NO | MUL | NULL | | +--------------+---------------+------+-----+---------+----------------+ 7 rows in set (0.00 sec) mysql> desc book_author; +-------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(50) | NO | | NULL | | +-------+-------------+------+-----+---------+----------------+ 2 rows in set (0.00 sec) mysql> desc book_authordetail; +-----------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | sex | tinyint(1) | NO | | NULL | | | email | varchar(254) | NO | | NULL | | | address | varchar(100) | NO | | NULL | | | birthday | date | NO | | NULL | | | author_id | int(11) | NO | UNI | NULL | | +-----------+--------------+------+-----+---------+----------------+ 6 rows in set (0.00 sec) mysql> desc book_book; +--------------+---------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+---------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | title | varchar(30) | NO | | NULL | | | publish_date | date | NO | | NULL | | | price | decimal(5,2) | NO | | NULL | | | description | varchar(5000) | NO | | NULL | | | category_id | int(11) | NO | MUL | NULL | | | publisher_id | int(11) | NO | MUL | NULL | | +--------------+---------------+------+-----+---------+----------------+ 7 rows in set (0.00 sec) mysql> desc book_book_authors; +-----------+---------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------+---------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | book_id | int(11) | NO | MUL | NULL | | | author_id | int(11) | NO | MUL | NULL | | +-----------+---------+------+-----+---------+----------------+ 3 rows in set (0.00 sec) mysql> desc book_category; +-------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(50) | NO | | NULL | | +-------+-------------+------+-----+---------+----------------+ 2 rows in set (0.00 sec) mysql> desc book_publisher; +---------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +---------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(50) | NO | | NULL | | | address | varchar(100) | NO | | NULL | | | email | varchar(254) | NO | | NULL | | | website | varchar(200) | NO | | NULL | | +---------+--------------+------+-----+---------+----------------+ 5 rows in set (0.00 sec) mysql>
时间: 2024-10-14 15:10:10