zoukankan      html  css  js  c++  java
  • 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
    

    自关联

    自关联表设计

    模型类中设置:null=True,表示数据库创建时该字段可不填,用NULL填充.即在Null字段显示为YES。

    模型类中设置:blank=True,表示代码中创建数据库记录时该字段可传空白(空串,空字符串).表示你的表单填写该字段的时候可以不填,但是对数据库来说,没有任何影响

    class AddressInfo(models.Model):
    	address = models.CharField(max_length=200, null=True, blank=True, verbose="地址")
    	pid = models.ForeignKey('self', null=True, blank=True, verbose_name="自关联")
    

    Models去物理外键为逻辑外键

    断关联的特点

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

    db_constraint

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

    db_constraint=False

    on_delete--级联删除

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

    on_delete=models.CASCADE

    #有6种操作
    CASCADE:将定义有外键的模型对象同时删除(默认)
    PROTECT:阻止上面的删除操作,但是会弹出ProtectedError异常
    SET_NULL:将外键字段设为null,只有当字段设置了null=True时,才可以使用
    SET_DEFAULT:将外键字段设为默认值,只有当字段设置了default参数时,可以使用
    DO_NOTHING:什么也不做
    SET():设置为一个传递给SET()的值,或者一个回调函数的返回值。注意大小写。
    

    注意多对多例外

    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是反向查询字段

    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语句 同属于一个事务
    缩进出来之后自动结束
    
  • 相关阅读:
    JS练习
    推断一组数的规律,并填充缺失的数
    IP地址的正则表达式写法
    相比于HTML4,HTML5废弃的元素有哪些?
    关于HTML5和CSS3的几个“新增”
    hdu 3092 简单数论+分组背包dp
    避障
    人工势场法
    A*
    pop 2049-简单bfs
  • 原文地址:https://www.cnblogs.com/zx125/p/12025031.html
Copyright © 2011-2022 走看看