Django-orm高级

Posted zx125

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django-orm高级相关的知识,希望对你有一定的参考价值。

ORM字段

orm常见字段

https://www.cnblogs.com/liuqingzheng/articles/9627915.html

choice字段注释与数据渲染

性别

sex_choices =(
    (1,'male')
    (2,'female'),
    (3,'null')
)
sex = models.IntegerField("上课纪录", choices=sex_choices, default="3")


user_obj = models.Userinfo.objects.all().first()
# 针对choices字段,如果你想要获取数字所对应的中文,你不能直接点字段
# 固定句式,数据对象.get_字段名_display(),当没有对应关系的时候,该句式获取到的还是数字
print(user_obj.get_sex_display())

自定义字段

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)

modles基表

modles里面的表有公共字段,可以提取到基表上

基表注意

设置内嵌meta类的abstract为True,默认为False(为False会创建这个表)

is_delete字段

用来做逻辑删除,因为数据是有价值的

class BaseModel(models.Model):
    is_delete = models.BooleanField(default=False)
    create_time = models.DateTimeField(auto_now_add=True)
    class Meta:
        # 基表必须设置abstract,基表就是给普通Model类继承使用的,设置了abstract就不会完成数据库迁移完成建表
        abstract = True

Models去物理外键为逻辑外键

断关联的特点

1.表之间没有物理外键关联,但是有逻辑外键关联(但是要注意,由于没有物理的约束,所以要在逻辑上必须保证数据操作的安全)
2、断关联后不会影响数据库查询效率,但是会极大提高数据库增删改效率(因为少做了一步判断外键数据是否存在的操作)

db_constraint

断关联,但是级联关系还在(默认级联删除),所以要自己设置,如下

db_constraint=False

on_delete--级联删除

在django1.x中默认有,2.x中必须自己实现

on_delete=models.CASCADE

注意多对多例外

1.多对多外键实际在关系表中,ORM默认关系表中两个外键都是级联

2.ManyToManyField字段不提供设置on_delete,如果想设置关系表级联,只能手动定义关系表

作者没了,详情也没:on_delete=models.CASCADE
出版社没了,书还是那个出版社出版:on_delete=models.DO_NOTHING

#下面两个比较类似
部门没了,员工没有部门(空不能):null=True, on_delete=models.SET_NULL
部门没了,员工进入默认部门(默认值):default=0, on_delete=models.SET_DEFAULT

related_name

外键字段为正向查询字段,related_name是反向查询字段

obj = models.Author.objects.filter(pk=1).first()
print(obj.detail.mobile)
obj2 = models.AuthorDetail.objects.filter(pk=1).first()
print(obj2.author.name)

only与defer

# 惰性查询
# res = models.Book.objects.all()
# res = models.Book.objects.values('title')
# res = models.Book.objects.only('title')
# for r in res:
#     # print(r.title)
#     print(r.price)#除了title,查询其他数据都要重新查询
"""
only会将括号内的字段对应的值 直接封装到返回给你的对象中  点该字段 不需要再走数据库
一旦你点了不是括号内的字段  就会频繁的去走数据库查询
"""

# res = models.Book.objects.defer('title')  # defer和only互为反关系,除了id
# for r in res:
#     print(r.title)
"""
defer会将括号内的字段排除之外将其他字段对应的值 直接封装到返回给你的对象中  点该其他字段 不需要再走数据库
一旦你点了括号内的字段  就会频繁的去走数据库查询
"""
# prefetch_related
res = models.Book.objects.prefetch_related('publish')
# print(res)
for r in res:
    print(r.publish.name)

"""
prefetch_related  看似连表操作  其实是类似于子查询
prefetch_related括号内只能放外键字段
    并且多对多字段不能放
    
如果括号内外键字段所关联的表中还有外键字段 还可以继续连表
        select_related(外键字段__外键字段__外键字段...)

注意

如果你使用的是django2.X版本 你在建数据库表关系的时候
你需要手动指定两个参数
    (你要手动告诉django  级联更新 级联删除  是否建外键约束)
    
    on_delete
    db_constraint

django中如何开启事务

from django.db import transaction
with transaction.atomic():
# 在该代码块中所写的orm语句 同属于一个事务
缩进出来之后自动结束

以上是关于Django-orm高级的主要内容,如果未能解决你的问题,请参考以下文章

Django-ORM操作数据库无数据问题

Django-ORM系统详述

12.Django-ORM增删改查

JavaScript笔试题(js高级代码片段)

django-orm

Django-ORM操作