• django-orm


    1. Django-orm定义

    实现数据库的sql操作转换为接口的形式,定义的类对应mysql的表,属性对应的是数据库的字段,实例对应数据库的一条记录

    1. Django-orm 基础字段

    2.1 所有字段都有的参数

    db_column= "AA" 设置字段名称

    primary_key=True 设置主键

    verbose_name = "B" 设置字段别名

    unique = True #设置唯一值属性

    null = True blank=True # 默认情况下所有字段都不能为空,null字段设置允许为空(数据库层面),blank=True指的是前端表单提交允许为空

    db_index = True 给字段建立索引

    help_text = "AA" 在表单中显示说明信息

    editable = False 字段不能编辑,默认字段都是可以编辑的

    default = "AA" 设置默认值

    2.2 个别字段的参数

    max_length = 100 CharField必须要设置最大长度

    auto_now = True DateField使用,默认填充当前时间,指的是数据更新的时间

    auto_now_add = True DateField使用,指的是数据插入的时间

    max_digits =4 DecimalField,设置所有的数字个数

    decimal_places = 2 DecimalField,设置小数位的数字个数

    2.3 关系型字段的参数

    OneToOneField

    ForeignKey

    ManyToManyField

    related_name = "one" 反向查询,可以通过父表查询到子表的信息

    on_delete =models.CASCADE 当表关联的外键被删除时候对应的操作,一共由6种

    models.CASCADE # 删除级联,删除A表的数据,B表关联的数据一起被删除

    2.4 基础字段参数

    class Test(models.Model):

    # 自增长字段,默认是int型

    Auto = models.AutoField()

    BigAuto = models.BigAutoField()

    # 二进制数据

    Binary = models.BinaryField()

    # 布尔型

    Boolean = models.BooleanField() # 不允许为空的布尔

    NullBoolean = models.NullBooleanField()

    # 整型

    PositiveSmallInteger = models.PositiveSmallIntegerField() # 5个字节

    SmallInteger = models.SmallIntegerField()

    PositiveInteger = models.PositiveIntegerField()

    Integer = models.IntegerField() # 11个字节

    BigInteger = models.BigIntegerField()

    # 字符串类型

    Char = models.CharField() # 需要指定默认长度

    Text = models.TextField() # 不需要指定长度,可以存大量文字

    # 时间日期类型

    Date = models.DateField() # 年月日

    DateTime = models.DateTimeField() # 年月日 时分秒

    Duration = models.DurationField() # int型的时间

    # 浮点型

    float = models.FloatField()

    Decimal = models.DecimalField()

    # 其它字段

    Email = models.EmailField() # 邮箱

    Image = models.ImageField()

    File = models.FileField() # 文件

    FilePath = models.FilePathField() # 文件路径

    URL = models.URLField()

    UUID = models.UUIDField()

    GenericIPAddress = models.GenericIPAddressField() # ipv4 ipv6

    class Test_A(models.Model):

    # 关系型字段

    onetoone = models.OneToOneField(Test,on_delete=models.CASCADE)

    class Test_B(models.Model):

    foreign = models.ForeignKey(Test_A)

    class Test_C(models.Model):

    manytomany = models.ManyToManyField(Test_B)

    2.5 自关联

    class AdddressInfo(models.Model):

    "省市县地址信息"

    address= models.CharField(max_length=200,verbose_name="地址")

    pid = models.ForeignKey("AdddressInfo",null=True,blank=True,verbose_name="自关联",on_delete=models.CASCADE)

    # 可以取到这个表自己的字段

    2.6 元数据

    class Meta: # 每个模型类都由一个子类Meta,定义元数据的地方,封装了一些数据表的信息

    db_table="address" # 定义表的名称

    ordering = "pid" # 按照pid字段来排序

    verbose_name = "地址" # 设置别名

    verbose_name_plural = verbose_name # 设置别名复数

    abstract = True # 设置这个类为基类,仅供其它类继承,自身不生成表

    2.7 取choice里面的显示值

    type = models.CharField(choices=((0,'test00'),(1,'test11'),(2,'test22')))

    def __str__(self):

    return self.address+self.get_type_display()

    # 在数据库实际存储的是 0,1,2,但是页面展示的是test00 test11 test22,但是在数据库取值的时候可以通过 get+字段名+display() 的方式取值(django orm方法)

    2.8 表结构

    所以可以科学的删除数据表(了解了makemigrations migrate 的用处)

    makemigrations: 通过models生成一个表执行文件到migrations文件夹下面

    migrate:执行这个表执行文件(生成或者修改表记录)

    2.9 数据的创建

    bulk_create : 批量导入

    update_or_create: 创建或者更新

    get_or_create: 取值或者创建

    当导入的表结构含有外键属性的时候: 可以直接使用

    teacher = Teacher.object.get(A="A") teacher 是course表的字段,Teacher是course的关联表。

    1. QuerySet api

    3.1返回新的QuerySet api

    1. all() get() order_by() exclude() reverse() distinct()

    exclude() 排除指定条件的结果集

    2. values() values_list() 获取字典或者元组形式的QuerySet

    例如:

    Teacher.Objects.values("nickname","111")

    >>> [{"nickname":"别名","111":"123"},{},{}] 字典格式的QuerySet

    >>> [("nickname":"别名","111":"123"),(),()] 元组格式的QuerySet

    3. 反向查询通过父表查询子表

    子表查询父表的数据:

    当导入的表结构含有外键属性的时候: 可以直接使用

    teacher = Teacher.object.get(A="A") teacher 是course表的字段,Teacher是course的关联表。

    父表查询子表的数据:

    Teacher.objects.get(A="A").course_set.all() Teacher是父表,course是子表,格式是(子表名_set)

    3.2 不返回QuerySet Api

    get() 查询单个对象

    get_or_create() 查询或者创建

    Author.objects.get_or_create(nickname="hello",default={"name":"123"})

    备注:主键或者唯一键写在外面,如果有,获取返回的值;没有,使用default里面的值创建

    create() 创建

    bulk_create() 批量创建 传的值是列表

    update_or_create() 创建或更新,用法同get_or_create()

    update() 更新

    delete() 删除

    exist() 判断是否存在

    count() 计数

    3.3 F对象和Q对象

    F对象的使用:操作字段的数据

    Q对象: 结合AND OR NOT | ~ & 实现复杂的查询

    & 与

    | 或

    NOT 取反

    1. 其它

    4.1新建一个对象的方法有以下几种:

    # 方法 1

    Author.objects.create(name="WeizhongTu", email="tuweizhong@163.com")

     

    # 方法 2

    twz = Author(name="WeizhongTu", email="tuweizhong@163.com")

    twz.save()

     

    # 方法 3--------------------常用

    twz = Author()

    twz.name="WeizhongTu"

    twz.email="tuweizhong@163.com"

    twz.save()

     

    # 方法 4,首先尝试获取,不存在就创建,可以防止重复

    Author.objects.get_or_create(nickname="hello",default={"name":"123"})

    备注:主键或者唯一键写在外面,如果有,获取返回的值;没有,使用default里面的值创建

    # 返回值(object, True/False)

    备注:前三种方法返回的都是对应的 queryset object,最后一种方法返回的是一个元组,(object, True/False),创建时返回 True, 已经存在时返回 False

    4.2 获取对象有以下方法

    Person.objects.all() # 返回QuerySet结果集

    Person.objects.all()[:10] 切片操作,获取10个人,不支持负索引,切片可以节约内存

    Person.objects.get(name=name) ## 名称为 WeizhongTu 的一条,多条会报错

    A:get是用来获取一个对象的,get返回的是结果,如果获取到多个会报错,通常传主键或者唯一键作为查询条件

    B:filter获取满足条件的一些结果,filter返回的是结果集(QuerySet,类似于list,可以使用for循环来取值,支持切片))

    Person.objects.filter(name="abc",address = "北京")  Person.objects.filter(name__exact="abc") 名称严格等于 "abc" 的人

    A:逗号代表与的关系,

    B:mes= Person.objects.filter(name="abc",address = "北京") #返回queryset对象,获取不到返回None

    print(mes.name) #返回的是多条记录的对象[object1,object2,objevt3],对象有字段的方法 mes.name

    C: 字段__+关键字(对字段进行特殊orm操作:)

    例如: name__exact="abc" 刚好等于

    name__gte = 大于

    name__in= 在列表范围内

    D:Person.objects.all().order_by("字段名") 以。。进行排序(默认升序排列)

    Person.objects.all().order_by("-字段名") 降序排列

    E:查看原生的SQL

    str(Person.objects.all().order_by.query)

    Person.objects.filter(name__iexact="abc")  # 名称为 abc 但是不区分大小写,可以找到 ABC, Abc, aBC,这些都符合条件

    Person.objects.filter(name__contains="abc")  # 名称中包含 "abc"的人

    Person.objects.filter(name__icontains="abc")  #名称中包含 "abc",且abc不区分大小写,模拟sql中like语句

    Person.objects.filter(name__regex="^abc")  # 正则表达式查询

    Person.objects.filter(name__iregex="^abc")  # 正则表达式不区分大小写

    filter是找出满足条件的,当然也有排除符合某条件的

    Person.objects.exclude(name__contains="WZ")  # 排除包含 WZ 的Person对象

    Person.objects.filter(name__contains="abc").exclude(age=23)  # 找出名称含有abc, 但是排除年龄是23岁的

    4.3删除符合条件的结果

    和上面类似,得到满足条件的结果,然后 delete 就可以(危险操作,正式场合操作务必谨慎),比如

    Person.objects.filter(name__contains="abc").delete() # 删除 名称中包含 "abc"的人

     

    如果写成 

    people = Person.objects.filter(name__contains="abc")

    people.delete()

    效果也是一样的,Django实际只执行一条 SQL 语句。

    4.4更新某个内容

    (1) 批量更新,适用于 .all()  .filter()  .exclude() 等后面 (危险操作,正式场合操作务必谨慎)

    1

    2

    Person.objects.filter(name__contains="abc").update(name='xxx') # 名称中包含 "abc"的人 都改成 xxx

    Person.objects.all().delete() # 删除所有 Person 记录

    (2) 单个 object 更新,适合于 .get(), get_or_create(), update_or_create() 等得到的 obj,和新建很类似。

    1

    2

    3

    4

    twz = Author.objects.get(name="WeizhongTu")

    twz.name="WeizhongTu"

    twz.email="tuweizhong@163.com"

    twz.save()  # 最后不要忘了保存!!!

    QuerySet 是可迭代的,比如:

    es = Entry.objects.all()

    for e in es:

        print(e.headline)

    Entry.objects.all() 或者 es 就是 QuerySet 是查询所有的 Entry 条目。

    注意事项:

    (1). 如果只是检查 Entry 中是否有对象,应该用 Entry.objects.all().exists()

    (2). QuerySet 支持切片 Entry.objects.all()[:10] 取出10条,可以节省内存

    (3). 用 len(es) 可以得到Entry的数量,但是推荐用 Entry.objects.count() (等价于 es.count())来查询数量,后者用的是SQL:SELECT COUNT(*)

    (4). list(es) 可以强行将 QuerySet 变成 列表

  • 相关阅读:
    【CF932E】Team Work
    【ZJOI2011】看电影
    【CQOI2011】放棋子
    【HAOI2010】计数
    【HNOI2009】有趣的数列
    【ZJOI2010】排列计数
    【FJOI2016】建筑师
    【USACO10 OPEN】三角形计数
    【HNOI2012】排队
    【HNOI2008】越狱
  • 原文地址:https://www.cnblogs.com/wenshu/p/12267134.html
Copyright © 2020-2023  润新知