django ORM应用笔记

django ORM应用笔记

1.常用字段类型和参数

  • 数值型,右边为MySQL对应类型:

    AutoField int(11) Django默认提供,自增主键(也就是id)
    BooleanField tinyint(1) 布尔型
    IntegerField int(11) 整数类型
    PositiveIntegerField int(11) 正整数类型
    
  • 字符型,右边为MySQL对应类型:

    CharField varchar 基础的字符串类型
    TextField longtext 文本类型
    第三方富文本:django-Ueditor(https://github.com/liyaopinner/DjangoUeditor3_imooc)以及django-ckeditor(https://github.com/django-ckeditor/django-ckeditor)
    
    URLField 增加对URL的校验
    EmailField 增加对Email格式的校验
    FileField 多了对文件的处理,后台管理系统可以看到上传文件按钮
    ImageFiled 多了对图片的处理,后台管理系统可以看到上传图片按钮
    
    UUIDField 用来生成唯一的uuid
    
  • 日期类型

    DateField
    DateTimeField
    
  • 关系类型

    ForeignKey 一对多
    OneToOneField 一对一类似是ForeignKey的特殊用法,在外键字段上加了unique约束
    ManyToManyField 多对多类型,会创建一个中间表来进行多对多的关联
    
  • 常用字段和参数举例说明:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    from django.db import models

    class GoodsCategory(models.Model):
    """
    商品类别
    """
    CATEGORY_TYPE = (
    (1, "一级类目"),
    (2, "二级类目"),
    (3, "三级类目"),
    )
    name = models.CharField(max_length=100, null=True, blank=True, verbose_name="类别名", help_text="类别名")
    desc = models.TextField(null=True, blank=True, verbose_name="类别描述", help_text="类别描述")
    category_type = models.IntegerField(choices=CATEGORY_TYPE, verbose_name="类目级别", help_text="类目级别")
    parent_category = models.ForeignKey('self', null=True, blank=True,
    verbose_name='父类目级别', on_delete=models.CASCADE, help_text='父目录',
    related_name='sub_cat') # related_name用于关联查询
    is_tab = models.BooleanField(default=False, verbose_name="是否导航", help_text="是否导航")
    add_time = models.DateTimeField('创建时间', auto_now=True, verbose_name='最后修改时间')

    class Meta:
    verbose_name = "商品类别"
    verbose_name_plural = verbose_name

    def __str__(self):
    return self.name

    class Goods(models.Model):
    """
    商品
    """
    category = models.ForeignKey(GoodsCategory, on_delete=models.CASCADE, verbose_name="商品类目", help_text="商品类目")
    goods_sn = models.CharField(max_length=50, default="", verbose_name="商品唯一货号", help_text="商品唯一货号")
    goods_front_image = models.ImageField(upload_to="goods/images/", null=True, blank=True, verbose_name="封面图",help_text="封面图")
    file = models.FileField(upload_to="message/images/", verbose_name="上传的文件", help_text="上传的文件")
    """

    max_length 最大长度
    default 默认值
    verbose_name 字段在后台显示的名称
    help_text 一般用于生成API文档(djangoRestframework)
    null=True, blank=True 常常搭配使用,允许字段的值为空
    choices 字段在后台管理系统可选的值
    db_index=True 对于需要经常查询的字段需要配置
    unique=True 与db_index相冲突,设置了此项不要在设置db_index

    auto_now=True 用于DateTimeField或DateField,记录更新时间
    auto_now_add=True 用于DateTimeField或DateField,记录初次添加的时间

    on_delete=models.CASCADE 外键级联删除,当删除了外键对象时,外键对象关联的所有记录也会跟着删除,
    (一般设置为on_delete=models.DO_NOTHING)
    models.ForeignKey('self',related_name='sub_cat') 自关联字段,类似于省市区,有三级分类,

    upload_to="message/images/" 用于FileField或ImageField,约束上传文件存储的位置(都存在根目录中的media目录)
    """

元数据

常用到的就四个
class Meta:
    verbose_name = "学生信息表" # 后台管理系统显示的表名
    db_table = "student_info" # 自定义数据库存储的表名,默认是app名+model类名
    verbose_name_plural = verbose_name # 后台管理系统显示的表名
    unique_together('address','info') # address和info联合约束

2.django导入数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# models.py
class Teacher(models.Model):
"""讲师信息表"""
nickname = models.CharField(max_length=30, primary_key=True, db_index=True, verbose_name="昵称")
introduction = models.TextField(default="这位同学很懒,木有签名的说~", verbose_name="简介")
fans = models.PositiveIntegerField(default="0", verbose_name="粉丝数")

class Meta:
verbose_name = "讲师信息表"
verbose_name_plural = verbose_name

def __str__(self): # Python2:__unicode__
return self.nickname

# 在项目根目录新建orm_data.py
import os
import sys

project_path = os.path.dirname(os.path.abspath(__file__))
sys.path.append(project_path) # 将项目路径添加到系统搜寻路径当中
os.environ['DJANGO_SETTINGS_MODULE'] = 'imooc.settings' # 设置项目的配置文件
django.setup()

from courses.models import Teacher

def import_data():
"""使用Django ORM导入数据"""
# 讲师数据 create()
Teacher.objects.create(nickname="Jack", introduction="Python工程师", fans=666)
Teacher.objects.create(nickname="Allen", introduction="Java工程师", fans=123)
Teacher.objects.create(nickname="Henry", introduction="Golang工程师", fans=818)
# bulk_create 批量导入
# update_or_create 存在就更新,否则就新增
return True

3.queryset查询接口

# 直接返回结果,不返回Queryset
函数有:get,create,update,delete,get_or_create,count,first,bulk_create
need_posts = Post..objects.get(id=1)
need_posts = posts.filter(title__contains).count() #查询结果计数
Post.objects.create(title="xx")# 创建并保存一条数据

# 结果检索,过滤,切片,排序,返回Queryset
posts= Post.objects.all()
need_posts = posts.filter(id=1) # 过滤出满足条件的对象
noneed_posts = posts.exclude(id=1) # 排除满足条件的对象
posts = posts.order_by("-add_time") # 根据更新时间倒序排序
posts = posts.reverse() # 查询结果反向排序
posts =posts[:2] # 取到前两条数据

# 链式查询,相当于启用join查询
posts = Post.objects.all().select_related('user')

# Q查询
Q查询,or,and,
posts = Post.objects.filter(Q(id=1)|Q(id=2))
posts = Post.objects.filter(Q(id=1)&Q(id=2))

# 附加说明.查询关键字
contains:包含,用于模糊查询
icontains:忽略大小写,用于模糊查询
exact:精确匹配
in:指定某个集合 posts = Post.objects.filter(id__in=[1,2])
range:指定某个范围,多用于时间范围,posts = Post.objects.filter(add_time__range=('2019-03-01','2019-03-29'))
gt,gte,lt,lte:值满足给定条件:大于、大于或等于,小于,小于或等于
startswith,endswith,istartswith,iendswith,

4.queryset查询优化

实际问题实际考虑

一般是先做filter查询,根据返回的queryset再做进一步的处理

github:https://github.com/zhwl934008411/imooc

坚持原创技术分享,您的支持将鼓励我继续创作!