我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Django基础——ORM字段和字段参数

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Django基础——ORM字段和字段参数

ORM概念:

对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象(

1. 不同的程序员写的SQL水平参差不齐
2. 执行效率也参差不齐

)的技术。

ORM 能够把 python语句 自动的翻译 为SQL语句

ORM优点: 

  1. 简单,不用自己写SQL语句
  2. 开发效率高

  缺点:

  执行效率有差距 

ORM的对应关系:

  类 ---> 数据表
  对象 ---> 数据行
  属性 ---> 字段

 

ORM能做的事儿:
  1. 操作数据表 --> 创建表/删除表/修改表
      操作models.py里面的类

  2. 操作数据行 --> 数据的增删改查

  不能创建数据库,自己动手创建数据库

使用Django的ORM详细步骤:
1. 自己动手创建数据库
  create database 数据库名;
2. 在Django项目中设置连接数据库的相关配置(告诉Django连接哪一个数据库)
  # 数据库相关的配置
  DATABASES = {
  'default': {
  'ENGINE': 'django.db.backends.mysql', # 连接的数据库类型
  'HOST': '127.0.0.1', # 连接数据库的地址
  'PORT': 3306, # 端口
  'NAME': "day61", # 数据库名称
  'USER': 'root', # 用户
  'PASSWORD': '123456' # 密码
  }
  }

3. 告诉Django用pymysql代替默认的MySQLDB 连接MySQL数据库
  在项目/__init__.py文件中,写下面两句:
  import pymysql
  # 告诉Django用pymysql来代替默认的MySQLdb
  pymysql.install_as_MySQLdb()

4. 在app/models.py里面定义类
# 出版社
class Publisher(models.Model):
id = models.AutoField(primary_key=True) # 自增的ID主键
# 创建一个varchar(64)的唯一的不为空的字段
name = models.CharField(max_length=64, null=False, unique=True)

5. 执行两个命令
1. python3 manage.py makemigrations --> 把models.py里面的更改记录到小本本上
2. python3 manage.py migrate --> 把更改翻译成SQL语句,去数据库执行

Django ORM常用字段:
  1. AutoField --> 自增
  2. CharField --> varchar(xx)
  3. ForeignKey --> 外键

    ForeignKey 字段的参数;

    a.to  --> 设置要关联的表;

    b.to_field -->设置要关联的表的字段

    c.related_name -->  反向操作时,使用的字段名,用于代替原反向查询时的'表名_set'。
  4. ManyToManyField --> 多对多关联

  5. DateField  -->日期字段,日期格式  YYYY-MM-DD 
  6. DateTimeField --> 日期时间字段,格式 YYYY-MM-DD HH:MM

  7. IntegerField -->整数类型

 字段的合集:

AutoField(Field)
        - int自增列,必须填入参数 primary_key=True

    BigAutoField(AutoField)
        - bigint自增列,必须填入参数 primary_key=True

        注:当model中如果没有自增列,则自动会创建一个列名为id的列
        from django.db import models

        class UserInfo(models.Model):
            # 自动创建一个列名为id的且为自增的整数列
            username = models.CharField(max_length=32)

        class Group(models.Model):
            # 自定义自增列
            nid = models.AutoField(primary_key=True)
            name = models.CharField(max_length=32)

    SmallIntegerField(IntegerField):
        - 小整数 -32768 ~ 32767

    PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
        - 正小整数 0 ~ 32767
    IntegerField(Field)
        - 整数列(有符号的) -2147483648 ~ 2147483647

    PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
        - 正整数 0 ~ 2147483647

    BigIntegerField(IntegerField):
        - 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807

    BooleanField(Field)
        - 布尔值类型

    NullBooleanField(Field):
        - 可以为空的布尔值

    CharField(Field)
        - 字符类型
        - 必须提供max_length参数, max_length表示字符长度

    TextField(Field)
        - 文本类型

    EmailField(CharField):
        - 字符串类型,Django Admin以及ModelForm中提供验证机制

    IPAddressField(Field)
        - 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制

    GenericIPAddressField(Field)
        - 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
        - 参数:
            protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
            unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启此功能,需要protocol="both"

    URLField(CharField)
        - 字符串类型,Django Admin以及ModelForm中提供验证 URL

    SlugField(CharField)
        - 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)

    CommaSeparatedIntegerField(CharField)
        - 字符串类型,格式必须为逗号分割的数字

    UUIDField(Field)
        - 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证

    FilePathField(Field)
        - 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
        - 参数:
                path,                      文件夹路径
                match=None,                正则匹配
                recursive=False,           递归下面的文件夹
                allow_files=True,          允许文件
                allow_folders=False,       允许文件夹

    FileField(Field)
        - 字符串,路径保存在数据库,文件上传到指定目录
        - 参数:
            upload_to = ""      上传文件的保存路径
            storage = None      存储组件,默认django.core.files.storage.FileSystemStorage

    ImageField(FileField)
        - 字符串,路径保存在数据库,文件上传到指定目录
        - 参数:
            upload_to = ""      上传文件的保存路径
            storage = None      存储组件,默认django.core.files.storage.FileSystemStorage
            width_field=None,   上传图片的高度保存的数据库字段名(字符串)
            height_field=None   上传图片的宽度保存的数据库字段名(字符串)

    DateTimeField(DateField)
        - 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]

    DateField(DateTimeCheckMixin, Field)
        - 日期格式      YYYY-MM-DD

    TimeField(DateTimeCheckMixin, Field)
        - 时间格式      HH:MM[:ss[.uuuuuu]]

    DurationField(Field)
        - 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型

    FloatField(Field)
        - 浮点型

    DecimalField(Field)
        - 10进制小数
        - 参数:
            max_digits,小数总长度
            decimal_places,小数位长度

    BinaryField(Field)
        - 二进制类型

字段合集

 

在ORM 表单中没有char字段;需要自定义

#自定义char字段
class FixedCharField(models.Field):
	"""
	自定义的char类型的字段类
	"""

	def __init__(self, max_length, *args, **kwargs):
		self.max_length = max_length
		super(FixedCharField, self).__init__(max_length=max_length, *args, **kwargs)

	def db_type(self, connection):
		"""
		限定生成数据库表的字段类型为char,长度为max_length指定的值
		"""
		return 'char(%s)' % self.max_length
class Class(models.Model):
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=25)
    # 使用上面自定义的char类型的字段
    cname = FixedCharField(max_length=25)

  

3. 常用的字段参数
1. null

用于表示某个字段可以为空。
2. default

该字段为默认值
3. unique

如果设置为unique=True 则该字段在此表中必须是唯一的 。
4. db_index
如果db_index=True 则代表着为此字段设置数据库索引。

5. DateField和DateTimeField才有的参数:
auto_now_add=True --> 创建数据的时候自动把当前时间赋值
auto_add=True --> 每次更新数据的时候更新当前时间
上述两个不能同时设置!!!

  

表和表之间的关系
1. 一对多(出版社和书);1对多  ,外键通常设置在多的那一边;
publisher = models.ForeignKey(to="Publisher")
数据库中实际 生成的是一个 publisher_id 字段

2. 多对多(作者和书);多对多,通常设置在正向查询多的那一边;比如我用author 查询 book 比较多,则把外键放在author.
books = models.ManyToManyField(to="Book")

在数据库中:
是通过第三张表建立的关系(默认第三张表名 为字段_另一个多对多的字段)

# 书
class Book(models.Model):
	id = models.AutoField(primary_key=True)
	bookname = models.CharField(null=False,max_length=15,unique=True)
	price = models.DecimalField(max_digits=5,decimal_places=2,default=99.99)
	kucun = models.IntegerField(default=10000)
	sell_num = models.IntegerField(default=0)
	# 书和出版社关联的外键(单表对单表的)
	# on_delete=models.CASCADE ; 级联删除,即删除主表数据会自动删除从表数据;使关联的数据对应;
	# related_name 来代替 表名_set;
	publisher = models.ForeignKey(to="Publisher",default=1,on_delete=models.CASCADE,
     related_name='books')
     #反向操作时,使用的字段名,用于代替原反向查询时的'表名_set'。 #在数据库里面生成的字段为 publisher_id 是出版社的id #Book.object.publisher 为该书对应的出版社的对象; def __str__(self): return "Publisher_object:{}".format(self.bookname) #出版社 class Publisher(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(null=False,max_length=15,unique=True) def __str__(self): return "Publisher_object:{}".format(self.name) # class Meta: # ordering ='id' # 书和出版社是,1对1的(ForeignKey(to=)),是需要添加外键的 # 而书和作者是多对多的,一本书可以有多个作者,还有一个作者也可能有多本书,即多对多的时候用(ManyToManyField(to=)) #然后ROM会自动的帮你生成另外的一张表来表示多对多的关系,这个列子生产的另外一个表为author_book; # 作者 class Author(models.Model): id = models.AutoField(primary_key=True) author_name = models.CharField(null=False, max_length=15) #多对多的 book = models.ManyToManyField(to="Book") def __str__(self): return "Publisher_object:{}".format(self.author_name)

 详细参考(点我) 

3. 一对一  ;比如作者和作者详情,一个作者只能对于自己的作者详情;

1. 什么时候用一对一?
  当 一张表的某一些字段查询的比较频繁,另外一些字段查询的不是特别频繁
  把不怎么常用的字段 单独拿出来做成一张表 然后用过一对一关联起来
2. 优势
  既保证数据都完整的保存下来,又能保证大部分的检索更
3. ORM中的用法
  OneToOneField(to="")

举例:作者和作者详情是一对一的;跟一对多,用法相同,只不过detail里面的不能重复;在数据库中也是多一个detail_id 字段

总结+练习ORM(多表的查询)

	# #####################基于对象查询(子查询)##############################
	#                按字段(publish)
	# 一对多   book  ----------------->  publish
	#               <----------------
	#                 book_set.all()

	# 正向查询按字段:

	# 查询python这本书籍的出版社的邮箱

	# python=models.Book.objects.filter(title="python").first()
	# print(python.publish.email)

	# 反向查询按     表名小写_set.all()

	# 苹果出版社出版的书籍名称

	# publish_obj=models.Publish.objects.filter(name="苹果出版社").first()
	# for obj in publish_obj.book_set.all():
	#     print(obj.title)

	#                按字段(authors.all())
	# 多对多   book  ----------------------->  author
	#               <----------------
	#                  book_set.all()

	# 查询python作者的年龄
	# python = models.Book.objects.filter(title="python").first()
	# for author in python.authors.all():
	#     print(author.name ,author.age)

	# 查询alex出版过的书籍名称

	# alex=models.Author.objects.filter(name="alex").first()
	# for book in alex.book_set.all():
	#     print(book.title)

	#                  按字段 authorDetail
	# 一对一  author  ----------------------->  authordetail
	#                <----------------
	#                  按表名  author

	# 查询alex的手机号
	# alex=models.Author.objects.filter(name='alex').first()
	# print(alex.authorDetail.telephone)

	# 查询家在山东的作者名字

	# ad_list=models.AuthorDetail.objects.filter(addr="shandong")
	#
	# for ad in ad_list:
	#     print(ad.author.name)

	'''
	对应sql:

	   select publish_id from Book where title="python"
	   select email from Publish where nid =   1


	'''

	# #####################基于queryset和__查询(join查询)############################

	# 正向查询:按字段  反向查询:表名小写

	# 查询python这本书籍的出版社的邮箱
	# ret=models.Book.objects.filter(title="python").values("publish__email")
	# print(ret.query)

	'''
	select publish.email from Book 
	left join Publish on book.publish_id=publish.nid 
	where book.title="python"
	'''

	# 苹果出版社出版的书籍名称
	# 方式1:
	# ret1 = models.Publish.objects.filter(name="苹果出版社").values("book__title")
	# print("111111111====>", ret1.query)
	# # 方式2:
	# ret2 = models.Book.objects.filter(publish__name="苹果出版社").values("title")
	# print("2222222222====>", ret2.query)
	#
	# # 查询alex的手机号
	# # 方式1:
	# ret = models.Author.objects.filter(name="alex").values("authorDetail__telephone")
	#
	# # 方式2:
	# models.AuthorDetail.objects.filter(author__name="alex").values("telephone")



	# 查询手机号以151开头的作者出版过的书籍名称以及书籍对应的出版社名称 ; 跨5张表; 都联合起来;
	ret = models.Book.objects.filter(authors__authorDetail__telephone__startswith="151").values('title', "publish__name")
	print(ret)

  

# 作者
class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    phone = models.IntegerField()
    books = models.ManyToManyField(to="Book", related_name="authors")
    detail = models.OneToOneField(to="AuthorDetail")

    def __str__(self):
        return self.name


# 作者详情
class AuthorDetail(models.Model):
    # 爱好
    hobby = models.CharField(max_length=32)
    # 地址
    addr = models.CharField(max_length=128)  

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Django基础——ORM字段和字段参数

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Django基础——ORM字段和字段参数

ORM概念:对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象(1. 不同的程序员写的SQL水平参差不齐2. 执行效率也参差不齐)的技术。ORM 能够把
2023-01-31

mysql 基础(1)字段类型

互联网工程师(id:phpstcn),我们一起学习,一起进步
mysql 基础(1)字段类型
2018-11-27

使用MyBatis时数据库字段和实体字段不同如何解决

这期内容当中小编将会给大家带来有关使用MyBatis时数据库字段和实体字段不同如何解决,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。当数据库字段和实体bean中属性不一致时之前数据库Person名字字段是
2023-05-31

sql怎么判断字段是否包含数字和字母

在SQL中,可以使用正则表达式来判断字段是否包含数字和字母。具体可以使用SQL的`REGEXP`函数,结合正则表达式来实现。例如,判断一个字段是否包含数字和字母,可以使用以下SQL语句:```sqlSELECT *FROM table_na
2023-08-18

数据库字段设计指南:为数据存储打下坚实基础

数据库字段设计指南是数据存储的关键,精心设计字段以确保数据完整性和可扩展性。字段类型、长度、约束、键等因素都至关重要。本文提供全面的指南,帮助您设计强大的数据库字段以支持您的数据存储需求。
数据库字段设计指南:为数据存储打下坚实基础
2024-02-14

mysql删除字段的基本语法和示例

目录语法示例注意事项示例代码脚本运行分配 1 MB 的空间解释注意事项总结在 mysql 中,要删除表中的字段(列),可以使用 ALTER TABLE 语句中的 DROP COLUMN 子句。以下是删除字段的基本语法和示例:语法sql<
mysql删除字段的基本语法和示例
2024-09-11

如何解决mybatis-plus实体类中字段和数据库中字段名不对应

这篇文章主要介绍“如何解决mybatis-plus实体类中字段和数据库中字段名不对应”,在日常操作中,相信很多人在如何解决mybatis-plus实体类中字段和数据库中字段名不对应问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法
2023-06-07

易优eyoucms数据表结构和字段说明(数据字典)

EyouCms是基于TP5.0框架为核心开发的免费开源的企业内容管理系统,易优基本包含了一个常规企业网站需要的一切功能。这篇文章主要介绍了易优eyoucms数据表结构和字段说明(数据字典),需要的朋友可以参考下
2023-05-17

将结构体字段切片转换为可变参数

编程网今天将给大家带来《将结构体字段切片转换为可变参数》,感兴趣的朋友请继续看下去吧!以下内容将会涉及到等等知识点,如果你是正在学习Golang或者已经是大佬级别了,都非常欢迎也希望大家都能给我建议评论哈~希望能帮助到大家!问题内容我的应用
将结构体字段切片转换为可变参数
2024-04-05

如何解决MyBatis中Enum字段参数解析问题

小编给大家分享一下如何解决MyBatis中Enum字段参数解析问题,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!基础Class和TypeHandlerMyBati
2023-06-20

mysql怎么修改字段名和数据类型

要修改字段名和数据类型,可以使用ALTER TABLE语句。以下是示例:修改字段名:ALTER TABLE table_name CHANGE old_column_name new_column_name data_type;例如,要将字
mysql怎么修改字段名和数据类型
2024-04-09

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录