Django之Model

时间:2022-04-22 16:58:50

一、字段

  常用字段:

  1. AutoField:int自增列,必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列。
  2. IntergerField:一个整数类型,范围在 -2147483648 to 2147483647。
  3. CharField:字符类型,必须提供max_length参数, max_length表示字符长度。
  4. DateField:日期字段,日期格式  YYYY-MM-DD,相当于Python中的datetime.date()实例。
  5. DateTimeField:日期时间字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相当于Python中的datetime.datetime()实例。
 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)
         - 二进制类型

 字段合集

全部字段

二、字段参数

  1. null:用于表示某个字段可以为空。
  2. unique:如果设置为unique=True 则该字段在此表中必须是唯一的 。
  3. db_index:如果db_index=True 则代表着为此字段设置数据库索引。
  4. default:为该字段设置默认值。

  时间字段独有:auto_now_add、auto_now

三、关系字段

  1. 一对多外键字段
  2. 一对一关系字段
  3. 多对多关系字段

四、查询

  1、基于对象查询(子查询)

 models.Books.objects.filter(name=xxx).first() #正向查询
 models.Publish.objects.filter(book_set=1).first()  #反向查询 

  2、基于querySet和双下划线查询(join查询)

 models.Books.objects.filter(name=xxx).values("publish__name")   #正向查询
 models.Publish.objects.filter(book__name=xxx).values("name")   #反向查询

  3、聚合分组

  (1)聚合

 from django.db.models. import Sum,Count,Avg
 models.Book.objects.all().aggregate(price_sum=Sum("price"))   #返回一个字典

  (2)分组

 #单表分组models.Book.objects.values("name").annocate(c=Count("id"))    #按什么分组,values里就是什么

 #跨表分组
 #select dep.name,Count(*) from emp inner join dep group by dep.id,dep.name

 models.dep.objeects.values("name").annotate(c=Count("emp__name")).values("name","c")
 models.emp.objects.values("dep__name").annotate(c=Count("name")).values("name","c")
 #.annotate()前面的values()里是什么,就按什么分组

  4、F查询和Q查询

  (1)F查询

 from django.db.models import F
 from app01.models import Book

 Book.objects.update(price=F("price")+20)  # 对于book表中每本书的价格都在原价格的基础上增加20元

  (2)Q查询

  | 表示或者,& 表示和

 from django.db.models import Q

 print(Book.objects.filter(Q(id=3))[0])  # 因为获取的结果是一个QuerySet,所以使用下标的方式获取结果
 print(Book.objects.filter(Q(id=3)|Q(title="Go"))[0])  # 查询id=3或者标题是“Go”的书
 print(Book.objects.filter(Q(price__gte=70)&Q(title__startswith="J")))  # 查询价格大于等于70并且标题是“J”开头的书
 print(Book.objects.filter(Q(title__startswith="J") & ~Q(id=3)))  # 查询标题是“J”开头并且id不是3的书
 print(Book.objects.filter(Q(price=70)|Q(title="Python"), publication_date="2017-09-26"))  # Q对象可以与关键字参数查询一起使用,必须把普通关键字查询放到Q对象查询的后面

  另一种方式

 q = Q()
 q.connector = "or"
 q.children.append(("))  #以元祖的形式
 q.children.append(("))

 models.Books.objects.all().filter(q)

 q = Q()
 q.connectior = "and"
 q.children.append(("))  #以元祖的形式
 q.children.append(("))

 models.Books.objects.all().filter(q)

五、知识点

  Book._meta.app_label拿到模型表所在app的名称

  Book._meta.model_name拿到“book”这个字符串

六、Content-Type表

  https://blog.csdn.net/aaronthon/article/details/81714496

  

        组件的作用:可以通过两个字段让表和N张表创建FK关系

        表结构:
            from django.db import models
            from django.contrib.contenttypes.models import ContentType

            from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation

            class DegreeCourse(models.Model):
                """学位课程"""
                name = models.CharField(max_length=128, unique=True)
                course_img = models.CharField(max_length=255, verbose_name="缩略图")
                brief = models.TextField(verbose_name="学位课程简介", )

            class Course(models.Model):
                """专题课程"""
                name = models.CharField(max_length=128, unique=True)
                course_img = models.CharField(max_length=255)

                # 不会在数据库生成列,只用于帮助你进行查询
                policy_list = GenericRelation("PricePolicy")

            class PricePolicy(models.Model):
                """价格与有课程效期表"""
                content_type = models.ForeignKey(ContentType)  # 关联course or degree_course
                object_id = models.PositiveIntegerField()

                #不会在数据库生成列,只用于帮助你进行添加和查询
                content_object = GenericForeignKey('content_type', 'object_id')

                valid_period_choices = (
                    (1, '1天'),
                    (3, '3天'),
                    (7, '1周'), (14, '2周'),
                    (30, '1个月'),
                    (60, '2个月'),
                    (90, '3个月'),
                    (180, '6个月'), (210, '12个月'),
                    (540, '18个月'), (720, '24个月'),
                )
                valid_period = models.SmallIntegerField(choices=valid_period_choices)
                price = models.FloatField()

        使用:
            # 1.在价格策略表中添加一条数据
            # models.PricePolicy.objects.create(
            #     valid_period=7,
            #     price=6.6,
            #     content_type=ContentType.objects.get(model='course'),
            #     object_id=1
            # )

            # models.PricePolicy.objects.create(
            #     valid_period=14,
            #     price=9.9,
            #     content_object=models.Course.objects.get(id=1)
            # )

            # 2. 根据某个价格策略对象,找到他对应的表和数据,如:管理课程名称
            # price = models.PricePolicy.objects.get(id=2)
            # print(price.content_object.name) # 自动帮你找到

            # 3.找到某个课程关联的所有价格策略
            # obj = models.Course.objects.get(id=1)
            # for item in obj.policy_list.all():
            #     print(item.id,item.valid_period,item.price)

七、values / value_list / only

  values取出来是以列表形式存储在queryset中。

  value_list取出来是以元祖形式存储在queryset中。

  only是以对象的形式存储在queryset中。