Django框架 数据库模型(Model)1 配置与ORM介绍

更多ORM的语法参见:https://www.cnblogs.com/wupeiqi/articles/6216618.html

一.ORM(Object Relational Mapping;对象关系映射)

  • Django内置的ORM只能用于Django的语法

1.功能:用于实现面向对象语言里不同类型系统的数据间的转换,也就是用面向对象的方式操作数据库

  • 1个类对应1个表,1个实例对应1条记录

2.优点:

·使得与通用数据库的交互简单易行,而且完全不用考虑SQL语句,从而实现快速开发
·数据库搬迁更简单(无需更改代码,只需更改数据库配置)
·可以一些SQL语句带来的性能问题
  #实例:查询User表中的所有字段(见下图)
  如使用selectfrom  auth_user就会因多了匹配动作而降低效率

在这里插入图片描述
3.缺点:

·性能有所牺牲;不过现在的各种ORM框架都在尝试各种方法,如缓存/延迟加载登,来减轻这个问题,效果很显著
·对个别复杂查询仍力不从心;为解决这个问题,ORM一般也支持写raw sql
·通过QuerySet的query属性查询对应操作的SQL语句
  author_obj=models.Author.objects.filter(id=2)
  print(author_obj.query)

4.表与表之间的关系:
on_delete参数参见:https://www.cnblogs.com/tuifeideyouran/p/4418450.html

1.一对一(One-to-One):员工与工号
  #主要用于不常用字段的独立放置
  #在一对多的关系的基础上加上UNIQUE=TRUE的约束
  #当2个类之间有继承关系时,默认会创建1个一对一字段

#字段创建:
<field>=models.OneToOneField(to=None,on_delete=None[,to_field=foreign_key])
  #参数说明:
    to:要关联的表名;也可以是位置参数
    to_field:要关联的字段名
    on_delete:指定级联删除策略(可选值见下)
    field:在本表中的字段名

#on_delete可选值:
on_delete=models.CASCADE:删除关联数据时,与之关联的记录也删除
on_delete=models.DO_NOTHING:删除关联数据时,引发错误IntegrityError
on_delete=models.PROTECT:删除关联数据时,引发错误ProtectedError
on_delete=models.SET_NULL,:删除关联数据时,与之关联的值设为null(需要可为空)
on_delete=models.SET_DEFAULT:删除关联数据时,与之关联的值设为默认值(需要有默认值)
on_delete=models.SET(<value>):删除关联数据时,与之关联的值设为指定值value
on_delete=:models.SET(<可执行对象>):删除关联数据时,与之关联的值设为可执行对象的返回值

##############################################################################

2.一对多(One-to-Many;最常用):员工与部门
  #利用FOREIGN KEY

#字段创建:
<field>=models.ForeignKey(to=None,on_delete=None[,to_field=primary_key,\
    related_name=None,related_query_name=None,limit_choices_to=None,\
    db_constraint=True,parent_link=False])
  #参数说明:
    to:要关联的表名;也可以是位置参数
      #可省略" ",但此时for_tab必须在本表上方(不加按变量找,加则按映射关系找)
    to_field:要关联的字段;默认为for_tab的主键
    on_delete:指定级联删除策略(可取值见下)
      可为:CASCADE/PROTECT/SET_NULL/SET_DEFAULT/SET( )/DO_NOTHING
      #从1.9开始必需
    related_name:反向操作时使用的字段名,用于代替[<tab_name>_set]
      #详情参见 Model2.三.3.对象形式的反向查找 部分
    related_query_name:反向操作时,使用的连接前缀,用于替换[<tab_name>]
    limit_choices_to=None:在Admin/ModelForm中显示关联数据时,提供的条件
      如:limit_choices_to={'nid__gt':5}或limit_choices_to=lambda:{'nid__gt':5}
    db_constraint:是否在数据库中创建外键约束
      #如为False,数据库中没有约束,但Foreign Key的其他功能都被保留
    parent_link:在Admin中是否显示关联数据
    field:在本表中的字符名,Django自动将字段名变为<field>__<pri_key>
      #实际使用需要使用<field>__<pri_key>

##############################################################################

3.多对多(Many-to-Many):作者与书籍
  #转换成2个一对多的关系(自动创建第3张表进行关联,这张表不能通过ORM添加记录)
  #自动生成的第3张表只能包含3个字段:另外2个表的主键和1个AutoField
  #当然也可以自己创建第3张表(两个foreign key)

#字段创建:
<field>=models.ManyToManyField(to=None[,related_name=None,related_query_name=None,\
    limit_choices_to=None,symmetrical=None,through=None,through_fields=None,\
    db_constraint=True,db_table="<tab>_<to>"])
  #参数说明:其他参数同.ForeignKey()
    symmetrical:用于指定内部是否创建反向操作的字段(仅用于多对多自关联时)(详情见下)
    through:指定某表作为多对多关系中的第3张表;str
    through_fields:指定through中的哪些字段作为关联表;str list(示例见下)
      #如果同时指定上述2个参数,ManyToManyField的.add()/.remove()/.clear()/.set()将无法使用,但.filter()/.all()可以继续使用
    db_table:自动创建的第三张表在数据库中的名称;默认为<本表名>_<关联表名>

##############################################################################

4.自关联:
(1)互粉(多对多):博主和粉丝都是用户
class User(models.Model):
    userid=models.AutoField()
    username=models.CharField(max_length=32,db_index=True)
    d=models.ManyToManyField("User",related_name="u")#"User"也可以换成self
    #涉及到自关联时一定要设置related_name,否则反向操作时会出问题
(2)评论区(一对多):可以回复评论
class Comment(models.Model):
    pid=models.AutoField(primary_key=True)#评论的ID
    content=models.TextField()#评论的内容
    news_id=models.ForeignKey(News,ob_delete=models.CASCADE)
      #新闻的ID,表示:是哪条新闻下的评论
    user_id=models.ManyToManyField(User)#用户的ID,表示:是哪个用户的评论
    reply_id=models.ForeignKey(Comment,ob_delete=models.CASCADE,releted_name="ri")
      #表示:回复的是哪条评论;为0表示不是回复
  • 关于symmetrical参数:
做如下操作时,不同的symmetrical会有不同的可选字段:
models.BB.objects.filter(...)
1.当symmetrical=True,可选字段有code/id/m1
class BB(models.Model):
    code=models.CharField(max_length=12)
    m1=models.ManyToManyField('self',symmetrical=True)#self表示和自身关联
2.当symmetrical=False,可选字段有BB(表名)/code/id/m1
class BB(models.Model):
    code=models.CharField(max_length=12)
    m1=models.ManyToManyField('self',symmetrical=False)
  • through_fields参数示例:
from django.db import models

class Person(models.Model):
    name=models.CharField(max_length=50)

class Group(models.Model):
    name=models.CharField(max_length=128)
    members=models.ManyToManyField(
        Person,
        through='Membership',
        through_fields=('group','person'),
    )

class Membership(models.Model):
    group=models.ForeignKey(Group,on_delete=models.CASCADE)
    person=models.ForeignKey(Person,on_delete=models.CASCADE)
    inviter=models.ForeignKey(
        Person,
        on_delete=models.CASCADE,
        related_name="membership_invites",
    )
    invite_reason=models.CharField(max_length=64)

二.数据库的配置
1.Django默认支持SQLite,MySQL,Oracle,PostgreSQL数据库
(1)SQLite:

·Django默认使用SQLite的数据库(见下图),默认自带SQLite的数据库驱动
·引擎名称:django.db.backends.sqlite3

在这里插入图片描述
(2)MySQL:

·引擎名称:django.db.backends.mysql
·MySQL的驱动程序:
  MySQLdb(Python2中使用,对Python3的支持不好)
  MySQLClient
  MySQL
  PyMySQL(纯Python的MySQL驱动程序)

2.更改数据库:

修改settings.py中的DATABASES设置,将ENGINE改为指定数据库的引擎

在这里插入图片描述
3.其他数据库设置:

#settings.py中的DATABASES设置:
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', 
        'NAME': 'books',
        'USER': 'root',
        'PASSWORD': '',
        'HOST': '',
        'PORT': '3306',
    }
}
#参数说明:
  NAME:数据库的名字
    在连接MySQL前该数据库必须已在MySQL中创建
    而项目文件夹中的db.sqlite3数据库由项目自动创建(见下图)
  USER:数据库的用户名
  PASSWORD:数据库的密码
  HOST:数据库主机IP,留空则为localhost
  PORT:数据库端口

设置完成后,在启动Django项目前,需要在MySQL创建数据库
然后启动项目,这次会报错:no module named MySQLdb
这是因为Django默认的驱动是MySQLdb,这里需要的是PyMySQL
需要在项目文件夹下同名文件夹中的__init__.py里写入(见下图):
import pymysql
pymysql.install_as_MySQLdb()

在这里插入图片描述
4.在Pycharm中查看数据库内容(以SQLite为例):

  • SQLite数据库在当前文件夹中(见上图);MySQL数据库在MySQL中
右侧Database栏-+栏-Data Source栏-选择数据来源

在这里插入图片描述

配置连接那个数据库-选择Apply

在这里插入图片描述

把当前文件夹内的数据库引擎拖到右侧的数据来源栏处

在这里插入图片描述

选中表查看
可通过"+"选项创建记录,通过"-"选项删除选定的记录

在这里插入图片描述
三.Admin管理工具
runoob.com/django/django-admin-manage-tool.html
1.简介:

Admin是Django提供的基于Web的数据库后台管理工具;可从数据库读取数据,并在线进行管理
如果不需要十分复杂的功能,默认配置已经足够使用;但一些特殊功能(如搜索功能)需要定制
是django.contrib的一部分,可以在项目的settings.py中的INSTALLED_APPS里找到:
#django.contrib是一套庞大的功能集,是Django基本代码的组成部分
INSTALLED_APPS=(
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
)

如果想使用中文界面,可以在setting.py中修改LANGUAGE_CODE:
  英文界面:LANGUAGE_CODE = 'en-us'
  中文界面:LANGUAGE_CODE = 'zh-hans'

2.激活:

通常在创建项目时会在urls.py中自动设置好,只需去掉注释即可使用:
#urls.py中
from django.conf.urls import url
from django.contrib import admin
urlpatterns = [
    url(r'^admin/', admin.site.urls),
]

3.使用
(1)登录:

需要先在使用的数据库中创建账号
或在终端里创建超级用户:
>>> python manage.py createsuperuser
Username (leave blank to use 'root'):
Email address:
Password:                            #输入后也不显示
Password (again):                    #输入后也不显示
Superuser created successfully.
默认登录界面:IP:port/admin#见下图

在这里插入图片描述

登录后进入管理界面(如果有相应权限)#见下图

在这里插入图片描述
(2)注册Model到Admin:

为了让Admin管理某个Model,需要先注册其到Admin

1.使用register的方法:
#在应用文件夹下的admin.py中:
from django.contrib import models
admin.site.register(models.Book)
admin.site.register([models.Book,models.Publisher,models.Author])
admin.site.register(models.Book,MyAdmin)
2.使用register的装饰器:
#在应用文件夹的models.py中:
@admin.register(Book)
class MyAdmin(admin.ModelAdmin):#自定义管理界面的类
    pass

4.自定义管理界面:
(1)ModelAdmin:

#ModelAdmin:
admin.ModelAdmin:管理界面的定制类,要自定义管理界面需继承该类

#auth系统:
Django自带的登录认证系统
Django admin默认使用auth系统进行登录认证

(2)一些常用设置:

list_display=("<field1>","<field2>"...):指定要显示的字段
  #默认不能包括多对多字段
search_fields=("<field1>",...):指定可搜索的字段
  #默认不能包括多对多字段
list_editable=("<field1>",...):指定可编辑的字段
  #主键无法编辑
list_filter=("<field1>",...):指定列表过滤器
  #跨表时不需要通过"__",直接写字段名即可
filter_horizontal=("<field1>",...):可以通过搜索添加
#filter_vertical=("<field1>",...):类似filter_horizontal()
list_per_page=<x>:指定每页显示的记录数
ordering:指定排序字段

#实例:
from django.contrib import admin
from app01.models import *
#Register your models here:
#@admin.register(Book)#单给某个表加一个定制
class MyAdmin(admin.ModelAdmin):#自定义管理界面
    list_display=("title","price","publisher")
    search_fields=("title","publisher")
    list_filter=("publisher",)#不加","会被以str的形式传入
    ordering=("price",)
    fieldsets=[
        (
            None,
            #不折叠,直接显示
            {'fields':['title']}
        ),
        (
            'price information',
            #折叠以下字段,显示为"price information"
            {
                'fields':['price',"publisher"],
                'classes':['collapse']
            }
        ),
    ]
#以上定义了1个MyAdmin类,用以说明自定义管理界面的显示格式
#以下注册models:
admin.site.register(Book,MyAdmin)#使用自定义的界面显示
admin.site.register(Publish)#使用默认的界面显示
admin.site.register(Author)

在这里插入图片描述
(3)注册管理界面:

MyAdmin类对应的是Contact数据模型,需要注册#见下图

在这里插入图片描述在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值