orm基础

django orm 简介

ORM(Object Relational Mapping)的意思是对象关系映射,Django ORM描述Django数据模型类和数据库之间的映射关系,通俗地讲就是让一个类和一个数据库表进行对应,这使ORM在数据库层和业务逻辑层之间起到了桥梁的作用。
Django通过类代码描述数据表字段、表间关系等内容,并通过相应命令把类所描述的内容持久化到数据库。

特点:

Django ORM通过统一格式的业务逻辑代码操作数据库,把SQL语句统一转换成较为固定的Django语法结构
Django ORM本质上是对SQL语句的功能进行封装,最终还是转化成SQL语句来操作数据库。
Django ORM与数据库映射的关系表现为Django中的一个数据模型(Model)映射一个数据库表。其基本情况是:类(django.db.models.Model)映射到数据库表,类的属性映射为数据库表字段,类的实例对象则映射为数据行。

Django ORM使用步骤主要有如下5步。

在项目使用的数据库管理系统中建立数据库
在项目的配置文件settings.py中设置数据库的连接字符。
在应用程序的models.py文件中编写继承于models.Model的数据模型。
运行python manage.pymakemigrations、python manage.py migrate两个命令生成数据库表
使用Django ORM操作数据库表。

配置数据库

import pymysql  #需要手动导入
pymysql.install_as_MySQLdb() #建立引擎 (在django,使用mysql需要导入pymysql,因为在django中不直接支持mysql)
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django', #数据库名
        "USER":"root",  #用户名
        "PASSWORD":"root",#密码
        "HOST":'127.0.0.1',#主机
        "PORT":3306 #端口号
    }
}

创建模型

1.创建单个数据表
from django.db import models

class Author(models.Model):
    # verbose_name 中文意思字段备注名,具体作用体现在admin(可以在django后台以字段名体现)和Form(以label标签体先),如果在第一个参数是写入,可以省略verbose_name
    #max_length限制字段长度,同时也要min_length
    name = models.CharField(verbose_name="作者", max_length=320)
    class Meta:
        db_table = 'author'

2.创建一对一数据表
from django.db import models

class Author(models.Model):
    name = models.CharField(verbose_name="作者", max_length=320)
    class Meta:
        db_table = 'author'

class Ids(models.Model):
    ids=models.CharField("身份证",max_length=18)
    # to="关联的数据表" on_delete="级联删除的映射关系" related_name:字段映射的别名(反向查询中使用,没有外键那一方使用),如果设置了,这author使用不了
    author=models.OneToOneField(to="Author",on_delete=models.CASCADE,verbose_name="作者id",related_name='authors')
3.创建一对多数据表
class Author(models.Model):
    name = models.CharField("作者", max_length=320,)

    class Meta:
        db_table = 'author'


class Books(models.Model):
    title = models.CharField("书名", max_length=320)
    text = models.TextField("简介")
    price = models.FloatField("价格")
    date = models.DateField("时间")
    author = models.ForeignKey(to='Author', verbose_name='作者', on_delete=models.CASCADE, related_name='author')
    claa Meta:
        db_table='author'
4.创建多对多数据表

class Author(models.Model):
    name = models.CharField("作者", max_length=320,)
    class Meta:
        db_table = 'author'
        
class Press(models.Model):
    press_name = models.CharField('出版社名称', max_length=320)
    #多对多中,没有级联删除,同时会自动创建第三张表,这张表与author,press都是多对一的关系
    author = models.ManyToManyField(to='Author', verbose_name="作者id")

    class Meta:
        db_table = 'press'
5.字段
字段类型
1. Meta

使用内部Meta类来给模型赋予元数据

模型的元数据即“所有不是字段的东西”,比如排序选项( ordering),数据库表名(db_table),或是阅读友好的单复数名( verbose_name和 verbose_name_plural)。

2.CharField

一个字符串字段,适用于小到大的字符串。对于大量的文本,使用TextField

3.BooleanField

一个true/false字段。该字段的默认表单部件是CheckboxInput

4.DataField

一个日期字段,与DataTimeField用法一致

5.DataTimeField

一个时间日期字段,里面有两个常用的参数

auto_now:默认为False,如果为True,当数据添加/更新时,设置当前时间为默认值

auto_now_add:默认为False,如果为True,当数据添加时设置当前时间为默认值

auto_now与autho_now_add不能共用

6.fileField

一个文件上传字段 class FileField(upload_to=None, max_length=100**,** options)**

这个字符串的值将被附加到你的 MEDIA_ROOT 路径后面,形成本地文件系统中上传文件的存储位置。

class MyModel(models.Model):
    # MEDIA_ROOT/uploads 这是在MEDIA_ROOT这个路径下
    upload = models.FileField(upload_to='uploads/')
    # or...
    # file will be saved to MEDIA_ROOT/uploads/2015/01/30
    upload = models.FileField(upload_to='uploads/%Y/%m/%d/')
在模型中使用 FileField 或 ImageField (见下文)需要几个步骤:
	1. 在你的配置文件中,你需要定义 MEDIA_ROOT 作为你希望 Django 存储上传文件的目录的完整路径。(为了保证性能,这些文件不存储在数据库中。)定义 MEDIA_URL 作为该目录的基本公共 URL。确保这个目录是 Web 服务器的用户账号可以写的。
	2. 将 FileField 或 ImageField 添加到你的模型中,定义 upload_to 选项,指定 MEDIA_ROOT 的子目录,用于上传文件。
	3. 所有这些将被存储在你的数据库中的是一个文件的路径(相对于 MEDIA_ROOT )。你很可能要使用 Django 提供的方便的 url 属性。例如,如果你的 ImageField 叫做 mug_shot,你可以在模板中使用 {{ object.mug_shot.url }} 获取图片的绝对路径。
	例如,你的 MEDIA_ROOT 设置为 '/home/media', upload_to 设置为 'photos/%Y/%m/%d'。upload_to 中的 '%Y/%m/%d' 部分是 strftime() 格式化,'%Y' 是四位数的年,'%m' 是两位数的月,'%d' 是两位数的日。如果你在 2007 年 1 月 15 日上传了一个文件,它将被保存在 /home/media/photos/2007/01/15 目录下。
7.ImageField

class ImageField(upload_to=None, height_field=None, width_field=None, max_length=100, **options)
继承 FileField 的所有属性和方法,但也验证上传的对象是有效的图像。

除了 FileField 的特殊属性外, ImageField 也有 height 和 width 属性。

为了方便查询这些属性,ImageField 有两个额外的可选参数。

ImageField.height_field
模型字段的名称,每次保存模型实例时将自动填充图像的高度。

ImageField.width_field
模型字段的名称,每次保存模型实例时将自动填充图像的宽度。

需要 Pillow 库。

字段参数

每一种字段都需要指定一些特定的参数,

1. null

如果设置True,当字段为空时,django会将数据库中该字段设置为null,默认为False

2.blank

如果设置为True,该字段允许为空。默认为False

注意该选项与null不同,null选项仅仅是数据库层面的设置,而 blank是涉及表单验证方面。如果一个字段设置为 blank=True,在进行表单验证时,接收的数据该字段值允许为空,而设置为 blank=False时,不允许为空。

3.choices

一系列二元组,用作此字段的选项。如果提供了二元组,默认表单小部件是一个选择框,而不是标准文本字段,并将限制给出的选项。

每个二元组的第一个值会储存在数据库中,而第二个值将只会用于在表单中显示。

对于一个模型实例,要获取该字段二元组中相对应的第二个值,使用 get_Foo_display()方法。

class Person(models.Model):
    six_choices=(
    (1,"男"),
    (2,"女"),
    (3,"保密"))
    six=models.CharField(choices=six_choices)
    
#获取数据
person=Person.Objects.all()
print(person.six)  #只会打印(1,2,3)当中的数据
print(person.get_six_display()) #打印了("男","女","保密")当中的数据
4.default

该字段的默认值。可以是一个值或者是个可调用的对象,如果是个可调用对象,每次实例化模型时都会调用该对象。

5.help_text

额外的“帮助”文本,随表单控件一同显示。即便你的字段未用于表单,它对于生成文档也是很有用的。

6.unique

如果设置为 True,这个字段的值必须在整个表中保持唯一。

添加数据

1. 添加单条数据
def get(self,request):
    #方式一,save()
    author=models.Author(name="刘德华")
    author.save()
    #方式二 create()
    models.Author.objects.create(name="刘德华")
2. 一对多,多对多数据添加
def get(self,request):
        data_list=tests.funs()  #数据源
        for items in data_list:
            #判断name这是参数是否存在。返回true,false
            sta = models.Author.objects.filter(name__contains=items["name"]).exists() 
            if sta: #如果存在  
                # 获取Author对象
                authors = models.Author.objects.filter(name__contains=items["name"]).first()
                #判断 Press中的press_name是否存在,返回ture,false
                sta2 =models.Press.objects.filter(press_name=items['press_name']).exists()
                if sta2: #如果存在
                    #获取 Press对象
                    presss = models.Press.objects.filter(press_name=items["press_name"]).first()
                    #并将 author对象id添加到Press
                    presss.author.add(authors.id)
                    #创建Books数据,这里的关系是多对一,在多的里面添加外键属性
                    models.Books.objects.create(title=items['title'],text=items['text'],price=float(items['price']),date=items['date'],author_id=authors.id,press=presss)
				#这里创建Press数据,注意,press_name数据是在Press中没有,需要创建,同时发现author字段没有使用,因为是多对多关系,需要用过add()方法添加
                presss = models.Press.objects.create(press_name=items["press_name"])
                presss.author.add(authors.id)
                models.Books.objects.create(title=items['title'],
                                            text=items['text'],
                                            price=float(items['price']),
                                            date=items['date'],
                                            author_id=authors.id,
                                            press=presss
                                            )

            else:
                models.Author.objects.create(name=items["name"])
                authors = models.Author.objects.filter(name=items["name"]).first()

                sta2 = models.Press.objects.filter(press_name=items['press_name']).exists()
                if sta2:
                    presss = models.Press.objects.filter(press_name=items["press_name"]).first()
                    presss.author.add(authors.id)
                    models.Books.objects.create(title=items['title'],
                                                text=items['text'],
                                                price=float(items['price']),
                                                date=items['date'],
                                                author_id=authors.id,
                                                press=presss
                                                )

                else:
                    presss = models.Press.objects.create(press_name=items["press_name"])
                    presss.author.add(authors.id)
                    models.Books.objects.create(title=items['title'],
                                                text=items['text'],
                                                price=float(items['price']),
                                                date=items['date'],
                                                author_id=authors.id,
                                                press=presss
                                                )
        return HttpResponse("ok")

查询数据

1.基础查询
1.1 all()
#查询所有对象,返回queryset对象,查询集,也称查询结果集,QuerySet,表示从数据库中获取的对象集合
author=models.Author.objects.all()
1.2 filter()
# 筛选条件匹配的对象,返回queryset对象
author =models.Author.objects.filter(name="刘德华")
1.3get()
#返回与所给筛选条件匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误,一般要做异常处理

author=models.Author.objects.get(name="刘德华")
1.4 first(),last()
#分别查询第一条记录和最后一条记录
author=models.Author.objects.first()
author2=models.Author.objects.last()

#在django orm模型中,如果对象还是queryset对象,则一直可以使用orm方法
1.5.exclude()
#筛选条件不匹配的对象,返回queryset对象  与filter()相反
author=models.Author.objects.exclude(name="刘德华")

1.6order_by()
author=models.Author.objects.order_by('-name')
 # order_by("字段")  # 按指定字段正序显示,相当于 asc  从小到大
# order_by("-字段") # 按字段倒序排列,相当于 desc 从大到小
# order_by("第一排序","第二排序",...)
1.7count()

统计出现次数

1.8 values(),values_list()

# values()把结果集中的模型对象转换成字典,并可以设置转换的字段列表,达到减少内存,提供性能
#values_list()把结果转换成列表,可以设置转换的字段列表(元组),减少内存损耗,提供性能
author=models.Author.Objects.values()
author2=models.Author.objects.values("name")
der_by("字段")  # 按指定字段正序显示,相当于 asc  从小到大
# order_by("-字段") # 按字段倒序排列,相当于 desc 从大到小
# order_by("第一排序","第二排序",...)
1.7count()

统计出现次数

1.8 values(),values_list()

# values()把结果集中的模型对象转换成字典,并可以设置转换的字段列表,达到减少内存,提供性能
#values_list()把结果转换成列表,可以设置转换的字段列表(元组),减少内存损耗,提供性能
author=models.Author.Objects.values()
author2=models.Author.objects.values("name")

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值