django的ORM常用字段和参数

Python之django(ORM常用字段和参数)

文章目录

    • Python之django(ORM常用字段和参数)
      • 一、测试环境的搭建
      • 二、单表操作之必知必会十三条
        • 1、all():查询所有结果
        • 2、filter(\**kwargs): 它包含了与所给筛选条件相匹配的对象
        • 3、get(\**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误
        • 4、exclude(\**kwargs): 它包含了与所给筛选条件不匹配的对象
        • 5、values(\*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列
        • 6、values_list(\*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
        • 7、order_by(\*field): 对查询结果排序
        • 8、reverse(): 对查询结果反向排序,请注意reverse()通常只能在具有已定义顺序的QuerySet上调用(在model类的Meta中指定ordering或调用order_by()方法)。
        • 9、distinct(): 从返回结果中剔除重复纪录(如果你查询跨越多个表,可能在计算QuerySet时得到重复的结果。此时可以使用distinct(),(注意只有在PostgreSQL中支持按字段去重。)
        • 10、count(): 返回数据库中匹配查询(QuerySet)的对象数量。
        • 11、first(): 返回第一条记录
        • 12、**last(): 返回最后一条记录**
        • 13、exists(): 如果QuerySet包含数据,就返回True,否则返回False
      • 三、单表查询之神奇的下划线
      • 四、外键的增删改查
      • 五、神奇的双下划线查询
      • 六、外键的正反向概念
      • 七、多表查询
        • 1、子查询(基于对象的跨表查询)
        • 2、连表查询(基于双下划线的跨表查询)
      • 八、聚合查询
      • 九、分组查询
      • 十、F与Q查询
        • 1、F查询
        • 2、Q查询
      • 十一、django中开启事务
      • 十二、ORM中常用字段及参数
      • 十三、choices参数
      • 十四、多对多的三种创建方式

一、测试环境的搭建

当我们新建一个应用时,这个应用通常会自带一个test.py的文件这个文件就是测试文件。我们学要把测试所需的环境搭建起来,然后在文件书写要测试的代码右键直接run test.py就可以了,不需要再把django项目启动起来

此时控制台会输出代码运行的结果(熟悉的感觉又回来了)

测试环境的搭建如下代码

from django.test import TestCase

# Create your tests here.
import os
import sys

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Mysite03.settings")
    import django
    django.setup()
    print('就一个字,帅!')  # 就一个字,帅!

例如:想测试往数据库里添加数据是否成功

from django.test import TestCase

# Create your tests here.
import os
import sys

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Mysite03.settings")
    import django
    django.setup()
    from app01 import models

    reg_obj = models.student.objects.create(
        student_name='小张',
        student_account='xiaozhang',
        student_pwd='123456',
        student_age='22',
        student_hobby='1'
    )


    see_obj = models.student.objects.filter(student_account='xiaozhang').first()
    print(see_obj)
# 就一个字,帅!
# 小张

二、单表操作之必知必会十三条

queryset是查询集,就是传到服务器上的url里面的内容。Django会对查询返回的结果集QuerySet进行缓存,这里是为了提高查询效率。也就是说,在你创建一个QuerySet对象的时候,Django并不会立即向数据库发出查询命令,只有在你需要用到这个QuerySet的时候才回去数据库查询。

1、all():查询所有结果
print(models.student.objects.all())
返回的是所有queryset对象
# , , , ]>
2、filter(**kwargs): 它包含了与所给筛选条件相匹配的对象
print(models.student.objects.filter(student_name='小张'))
# ]>
3、get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误
get_something = models.student.objects.get(id=3)
print(get_something,get_something.student_age)
# egon 19


get_something = models.student.objects.get(id=100)
print(get_something,get_something.student_age)
# app01.models.DoesNotExist: student matching query does not exist.
4、exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象
print(models.student.objects.exclude(student_is_delete=True))
# , , ]>
5、values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列
print(models.student.objects.values('student_is_delete'))
# 
6、values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
print(models.student.objects.values_list('student_is_delete'))
# 
7、order_by(*field): 对查询结果排序
print(models.student.objects.order_by('student_age')) # 默认按升序排列
# , , , ]>
8、reverse(): 对查询结果反向排序,请注意reverse()通常只能在具有已定义顺序的QuerySet上调用(在model类的Meta中指定ordering或调用order_by()方法)。
print(models.student.objects.order_by('student_age').reverse())
# , , , ]>
9、distinct(): 从返回结果中剔除重复纪录(如果你查询跨越多个表,可能在计算QuerySet时得到重复的结果。此时可以使用distinct(),(注意只有在PostgreSQL中支持按字段去重。)
10、count(): 返回数据库中匹配查询(QuerySet)的对象数量。
print(models.student.objects.all().count())
# 4
11、first(): 返回第一条记录
print(models.student.objects.order_by('student_age').reverse().first())
# ly
12、last(): 返回最后一条记录
print(models.student.objects.order_by('student_age').reverse().last())
# jason
13、exists(): 如果QuerySet包含数据,就返回True,否则返回False
print(models.student.objects.filter(student_name='小张').exists())
# True

三、单表查询之神奇的下划线

models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 获取id大于1 且 小于10的值
 
models.Tb1.objects.filter(id__in=[11, 22, 33])   # 获取id等于11、22、33的数据
models.Tb1.objects.exclude(id__in=[11, 22, 33])  # not in
 
models.Tb1.objects.filter(name__contains="ven")  # 获取name字段包含"ven"的
models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
 
models.Tb1.objects.filter(id__range=[1, 3])      # id范围是1到3的,等价于SQL的bettwen and
 
类似的还有:startswith,istartswith, endswith, iendswith 

date字段还可以:
models.Class.objects.filter(first_day__year=2017)
date字段可以通过在其后加__year,__month,__day等来获取date的特点部分数据
# date
        #
        # Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
        # Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1))

        # year
        #
        # Entry.objects.filter(pub_date__year=2005)
        # Entry.objects.filter(pub_date__year__gte=2005)

        # month
        #
        # Entry.objects.filter(pub_date__month=12)
        # Entry.objects.filter(pub_date__month__gte=6)

        # day
        #
        # Entry.objects.filter(pub_date__day=3)
        # Entry.objects.filter(pub_date__day__gte=3)

        # week_day
        #
        # Entry.objects.filter(pub_date__week_day=2)
        # Entry.objects.filter(pub_date__week_day__gte=2)
需要注意的是在表示一年的时间的时候,我们通常用52周来表示,因为天数是不确定的,老外就是按周来计算薪资的哦~

四、外键的增删改查

models.py

"""
需要明确的关系:
    出版者对书的关系为一对多(一个出版社可以出版多本书)
    书和作者的关系为多对多的关系(多个作者可以出版一本书,一本书也可以有多个作者)
    作者和作者详情是一对一关系(一个作者只能由一个作者详情)
"""

# 创建书这张表
class Book(models.Model):
    title = models.CharField(max_length=32,verbose_name='书名')
    price = models.DecimalField(max_digits=8,decimal_places=2,verbose_name='书价格')

    # 出版社对书
    publish = models.ForeignKey(to='Publish')

    # 书对作者
    author = models.ManyToManyField(to='Authors')



# 创建出版社表
class Publish(models.Model):
    name = models.CharField(max_length=32,verbose_name='出版社名')
    addr = models.CharField(max_length=64,verbose_name='出版社地址')
    Email= models.EmailField() # 电子邮件格式



# 创建作者表
class Authors(models.Model):
    name = models.CharField(max_length=32,verbose_name='作者名')
    phone = models.BigIntegerField(verbose_name='作者联系方式')

    # 作者对作者详情
    detail =  models.OneToOneField(to='Authors_detail')


# 创建作者详情表
class Authors_detail(models.Model):
    addr = models.CharField(max_length=64,verbose_name='作者地址')
    hobby = models.CharField(max_length=32,verbose_name='作者爱好')

test.py

from django.test import TestCase

# Create your tests here.
import os
import sys

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Mysite03.settings")
    import django
    django.setup()
    from app01 import models
    # 外键的增加
    # 一对多
    # 第一种publish_id
    models.Book.objects.create(title='三国演义',price=123.56,publish_id=1)
    models.Book.objects.create(title='金瓶梅',price=786.01,publish_id=2)
    models.Book.objects.create(title='西游记',price=333.56,publish_id=3)
    models.Book.objects.create(title='红楼梦',price=456.56,publish_id=2)

    # 第二种虚拟字段 直接放对象用publish接收
    obj = models.Publish.objects.filter(pk=1).first()
    models.Book.objects.create(title='水浒传',price=111.26,publish=obj)
    obj = models.Publish.objects.filter(pk=2).first()
    models.Book.objects.create(title='西游记', price=111.26, publish=obj)



    models.Publish.objects.create(name='清华出版社',addr='北京',Email='[email protected]')
    models.Publish.objects.create(name='北大出版社',addr='北京',Email='[email protected]')


    # 外键的删除
    models.Book.objects.filter(publish_id=3).delete() # 级联删除

    # 外键的修改
    # 第一种方式直接使用publish_id
    models.Book.objects.filter(pk=2).update(publish_id=4)

    # 第二种方式使用虚拟字段 publish接收
    obj = models.Publish.objects.filter(pk=2).first()
    models.Book.objects.filter(pk=2).update(publish=obj)


    # 多对多 就是在操作第三张关系表,就是对第三张虚拟表的增删改查(book_author)
    # 如何给书籍添加作者
    # 第一种方式
    book = models.Book.objects.filter(pk=2).first()
    book.author  # 先拿到book对象,对象可以点属性,(book.author)这就是第三张表
    book.author.add(1) # 给书籍id为2 添加作者id为1的作者
    # 书和作者是多对多的关系 add()也可以添加多条
    book.author.add(2,3)
    # 第二种方式
    author_obj = models.Authors.objects.filter(pk=1).first()
    author_obj1 = models.Authors.objects.filter(pk=2).first()
    book = models.Book.objects.filter(pk=2).first()
    book.author.add(author_obj,author_obj1)
    """
    add给第三张表添加数据,括号内可以传数字也可以传对象并且可以传多个
    """

五、神奇的双下划线查询

# 神奇的双下划线查询
    # 1 年龄大于35岁的数据
    res = models.User.objects.filter(age__gt=35)
    print(res)
    # 2 年龄小于35岁的数据
    res = models.User.objects.filter(age__lt=35)
    print(res)
    # 大于等于 小于等于
    res = models.User.objects.filter(age__gte=32)
    print(res)
    res = models.User.objects.filter(age__lte=32)
    print(res)

    # 年龄是18 或者 32 或者40
    res = models.User.objects.filter(age__in=[18,32,40])
    print(res)

    # 年龄在18到40岁之间的  首尾都要
    res = models.User.objects.filter(age__range=[18,40])
    print(res)

    # 查询出名字里面含有s的数据  模糊查询
    res = models.User.objects.filter(name__contains='s')
    print(res)
  
    # 是否区分大小写  查询出名字里面含有p的数据  区分大小写
    res = models.User.objects.filter(name__contains='p')
    print(res)
    # 忽略大小写
    res = models.User.objects.filter(name__icontains='p')
    print(res)

    res =models.User.objects.filter(name__startswith='j')
    res1 = models.User.objects.filter(name__endswith='j')
    print(res,res1)


    # 查询出注册时间是 2020 1月
   res = models.User.objects.filter(register_time__month='1')
   res = models.User.objects.filter(register_time__year='2020')

六、外键的正反向概念

# 正向
# 反向
根据外键来判断
eg:外键在A那,A查B就是正向查找。B查A就是反向查找
    正向查询按字段
	反向查询按表名小写

七、多表查询

1、子查询(基于对象的跨表查询)
# 1.查询书籍主键为1的出版社
    # 正向查找
    print(models.Book.objects.filter(pk=1).values('id','publish__name')) # 

    # 2.查询书籍主键为2的作者
    # 正向查找
    # 
    print(models.Book.objects.filter(pk=2).values('id','author__name'))

    # 3.查询作者lanlan的爱好
    # 正向查找
    # 
    print(models.Authors.objects.filter(name='lanlan').values('name','detail__hobby'))

    # 4.查询出版社是清华出版社出版的书
    # 反向查找
    # 
    print(models.Publish.objects.filter(name='清华出版社').values('name','book__title'))

    # 5.查询作者是lanlan写过的书
    # 反向查找
    # 
    print(models.Authors.objects.filter(name='lanlan').values('name','book__title'))

    # 6.查询爱好的打球的作者姓名
    # 反向查找
    # < QuerySet[{'authors__name': 'zhangzhang', 'hobby': '打球'}] >
    print(models.Authors_detail.objects.filter(hobby='打球').values('authors__name','hobby'))

"""
    基于对象 
        反向查询的时候
            当你的查询结果可以有多个的时候 就必须加_set.all()
            当你的结果只有一个的时候 不需要加_set.all()
        自己总结出 自己方便记忆的即可 每个人都可以不一样
"""
2、连表查询(基于双下划线的跨表查询)
    # 1.查询zhenzhen的住址,爱好和作者姓名
    # 正向查找
    # 
    print(models.Authors.objects.filter(name='zhenzhen').values('name','detail__addr','detail__hobby'))
    # 反向查找
    # 
    print(models.Authors_detail.objects.filter(authors__name='zhenzhen').values('authors__name','addr','hobby'))

    # 2.查询书籍主键为1的出版社名称和书的名称
    # 正向查找
    # 
    print(models.Book.objects.filter(pk=1).values('title','publish__name'))
    # 反向查找
    # 
    print(models.Publish.objects.filter(book__pk=1).values('book__title','name'))

    # 3.查询书籍主键为1的作者姓名
    # 正向查找
    # 
    print(models.Book.objects.filter(pk=1).values('author__name'))
    # 
    print(models.Authors.objects.filter(book__id=1).values('name'))

    # 4.查询书籍主键是1的作者爱好
    # 正向查找
    # 
    print(models.Book.objects.filter(pk=1).values('author__detail__hobby'))
    # 反向查找
    # < QuerySet[{'hobby': '跳水'}] >
    print(models.Authors_detail.objects.filter(authors__book__id=1).values('hobby'))

八、聚合查询

 """
 聚合查询:使用聚合函数进行查询
 分组查询需要使用 aggregate关键字
"""
# 使用聚合函数必须导入聚合函数的模块
 from django.db.models import Avg,Max,Min,Sum,Count

 print(models.Book.objects.aggregate(
        price_avg=Avg('price'),
        price_sum=Sum('price'),
        price_count=Count('price'),
        price_max=Max('price'),
        price_min=Min('price'))
   )
# {      'price_avg': 320.33, 
#	    'price_sum': Decimal('1601.65'), 
#        'price_count': 5, 
#        'price_max': Decimal('786.01'),
#        'price_min': Decimal('111.26')
#                }


九、分组查询

"""
分组查询:group by
     分组查询需要使用 annotate关键字
"""
# 统计每一本书的作者个数
    # print(models.Book.objects.annotate()) # models后面点什么就按什么分组
    # 
    print(models.Book.objects.annotate(author_num=Count('author')).values('author_num','title'))

    # 统计每个出版社卖出的最便宜的价格
    # 
    print(models.Publish.objects.annotate(min_price=Min('book__price')).values('name','min_price'))

    # 统计不止一个作者的图书
    # 
    print(models.Book.objects.annotate(count_author=Count('author')).filter(count_author__gt=1).values('title','count_author'))
    """
    只要你的ORM语句得到的结果还是一个Queryset对象
    那么你就可以一直点Queryset对象封装方法(无限制,只要你的逻通)
    """

    # 查询每个作者出的书的总价格
    # 
    print(models.Authors.objects.annotate(sum_price = Sum('book__price')).values('name','sum_price'))


    """
    按照指定指定字段分组如何做?
        models.Book.objects.values('price').annotate()
        这种就是按照在指定字段分组
    """

十、F与Q查询

1、F查询
# 为了更加的直观模拟出F与Q的操作,先在book表中增加两条字段
class Book(models.Model):
    title = models.CharField(max_length=32,verbose_name='书名')
    price = models.DecimalField(max_digits=8,decimal_places=2,verbose_name='书价格')
    stock = models.IntegerField(default=1000,verbose_name='库存数量')
    sale = models.IntegerField(default=100,verbose_name='卖出数量')

    # 出版社对书
    publish = models.ForeignKey(to='Publish')

    # 书对作者
    author = models.ManyToManyField(to='Authors')

    def __str__(self):
        return '书名:%s'%self.title
# test.py
from django.db.models import F,Q

# 查出卖出数大于库存数的书籍
# F: An object capable of resolving references to existing query objects.(能够解析对现有查询对象的引用的对象。)
print(models.Book.objects.filter(sale__gt=F('stock')))
# , , ]>

# 将所有书籍的价格提升五十块
print(models.Book.objects.update(price=F('price') + 500))

# 将所有书的名字加上“爆款”两个字
 """
在操作字符的时候,F不能够实现字符串的拼接
如果非要实现,需要导Concat模块和Value模块
from django.db.models.functions import Concat
from django.db.models import Value
"""
from django.db.models.functions import Concat
from django.db.models import Value
   print(models.Book.objects.update(title=Concat(F('title'),Value('爆款'))))
print(models.Book.objects.update(title=F('title')+'爆款')) # 所有title名称会变空白

2、Q查询
# Q:Encapsulates filters as objects that can then be combined logically (using
#     `&` and `|`)   (将过滤器封装为对象,然后可以逻辑地组合这些对象(使用' & ' and ' | '))
# 查询卖出数大于100小于300
print(models.Book.objects.filter(Q(sale__gt=100, sale__lt=300)).values('title'))
# 
print(models.Book.objects.filter(Q(sale__gt=100), Q(sale__lt=300)).values('title'))
# 
#print(models.Book.objects.filter(Q(sale__gt=100)|Q(sale__lt=300)).values('title'))  # | or 或者关系
print(models.Book.objects.filter(~Q(sale__gt=100) | Q(sale__lt=300)).values('title'))  # ~是取反的
# 



# Q的高级用法  能够将查询条件左边的也变成字符串样式
q =Q()
q.children.append(('sale__gt',100))
q.children.append(('sale__lt',300))
print(models.Book.objects.filter(q)) # 默认是and关系 , ]>
    # 可以修改成or 关系
q.connector = 'or'
print(models.Book.objects.filter(q)) # or关系 , , , , ]>

十一、django中开启事务

"""
事务
	ACID
	原子性:不可分割最小单位
	一致性:跟原子性是相辅相成的
	隔离性:事物之间互相不干扰
	持久性:事务一旦确认永久生效
	
事务的回滚
	rollback
事物的确认
	commit
"""
# 事务
    # 需要导入transaction模块
    from django.db import transaction

    # 开启事务
    try: # 异常捕获(视情况而定)
        with transaction.atomic():
            pass
            # 代码块
            # 在with代码内书写的所有ORM操作都属于同一个事务
    except Exception as e:
        print(e)

十二、ORM中常用字段及参数

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):
        - 小整数 -3276832767

    PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
        - 正小整数 032767
    IntegerField(Field)
        - 整数列(有符号的) -21474836482147483647

    PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
        - 正整数 02147483647

    BigIntegerField(IntegerField):
        - 长整型(有符号的) -92233720368547758089223372036854775807

    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)
        - 二进制类型

ORM字段与MySQL字段对应列表

对应关系:
    'AutoField': 'integer AUTO_INCREMENT',
    'BigAutoField': 'bigint AUTO_INCREMENT',
    'BinaryField': 'longblob',
    'BooleanField': 'bool',
    'CharField': 'varchar(%(max_length)s)',
    'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
    'DateField': 'date',
    'DateTimeField': 'datetime',
    'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
    'DurationField': 'bigint',
    'FileField': 'varchar(%(max_length)s)',
    'FilePathField': 'varchar(%(max_length)s)',
    'FloatField': 'double precision',
    'IntegerField': 'integer',
    'BigIntegerField': 'bigint',
    'IPAddressField': 'char(15)',
    'GenericIPAddressField': 'char(39)',
    'NullBooleanField': 'bool',
    'OneToOneField': 'integer',
    'PositiveIntegerField': 'integer UNSIGNED',
    'PositiveSmallIntegerField': 'smallint UNSIGNED',
    'SlugField': 'varchar(%(max_length)s)',
    'SmallIntegerField': 'smallint',
    'TextField': 'longtext',
    'TimeField': 'time',
    'UUIDField': 'char(32)',

十三、choices参数

  • models.py
# 创建一张普通表
class user(models.Model):
    choices_gender =(
        (1,'男'),
        (2,'女'),
        (3,'保密')
    )
    name = models.CharField(max_length=32,verbose_name='姓名')
    gender = models.IntegerField(choices=choices_gender,verbose_name='性别')

  • test.py
# 向表中添加数据
    # models.user.objects.create(name='lanlan',gender=2)
    # models.user.objects.create(name='honghong',gender=1)
    # models.user.objects.create(name='lvlv',gender=3)

    # 从表中取数据
    res = models.user.objects.filter(name='lanlan').first()
    print(res.gender)  # 2 只能取出数字,取不出具体的内容
    """
        在获取值的时候,固定句式:get_字段名_display() => 
    """
    print(res.get_gender_display())  # 女

    res1 = models.user.objects.filter(name='lvlv').first()
    print(res1.get_gender_display())  # 保密

十四、多对多的三种创建方式

# 第一种
"""
全自动创建
优点:可以利用正反向查询的概念,还可以利用add(),set(),remove(),clear()
缺点:扩展性差(第三张表只能有三个字段,写死了。不能添加其他字段)
"""
class Book(models.Model):
    title = models.CharField(max_length=32,verbose_name='书名')
    authors = models.ManyToManyField(to='Authors')
class Authors(models.Model):
    name = models.CharField(max_length=32,verbose_name='作者名')
# 第二种
"""
纯手动创建
特点:add(),set(),remove(),clear()不能用
	不可以使用正反向查询概念
	扩展性强
"""
class Book(models.Model):
    title = models.CharField(max_length=32,verbose_name='书名')
    
class Authors(models.Model):
    name = model.CharField(max_length=32,verbose_name='作者名')
    
class BooktoAuthor(model.Model):
    book_id= models.ForeignKey(to='Book')
    author_id= models.ForeignKey(to='Author')
    # 手动创建的第三张表,可以自己定义其他字段
# 半自动
"""
半自动创建
特点:可以利用正反向的概念,但是不能用add(),set(),remove(),clear()
	扩展性强
"""
class Book(models.Model):
    title = models.CharField(max_length=32,verbose_name='书名')
    authors = models.ManyToManyField(to='Author',
                                    through='BooktoAuthor', # 指定哪个表为第三张表
                                     through_fields=('book','authors') # 外键放在谁那,谁在第一个位置
                                    )
    
class Author(models.Model):
    name = model.CharField(max_length=32,verbose_name='作者名')
    '''
    book = models.ManyToManyField(to='Book',
                                    through='BooktoAuthor', # 指定哪个表为第三张表
                                     through_fields=('authors','book') # 外键放在谁那,谁在第一个位置
                                    )
    '''
    
    
class BooktoAuthor(model.Model):
    book= models.ForeignKey(to='Book')
    author= models.ForeignKey(to='Author')
    # 手动创建的第三张表,可以自己定义其他字段

你可能感兴趣的:(python,django,python,后端)