django 记录二 orm

orm——Object Relational Mapping


settings.py配置

# 配置mysql数据库
# 其他数据库配置看上面注释地址
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': '127.0.0.1',
        'PORT': 3306,
        'NAME': 'orm01',
        'USER': 'root',
        'PASSWORD': 'root'
    }
    'app01': { # 可以为每个app都配置自己的数据,并且数据库还可以指定别的,也就是不一定就是mysql,也可以指定sqlite等其他的数据库
        'ENGINE': 'django.db.backends.mysql',
        'NAME':'bms',           
        'USER':'root',       
        'PASSWORD':'',        
        'HOST':'127.0.0.1',       
        'PORT':3306           
    }
}

项目下的init文件配置

import pymysql

pymysql.install_as_MySQLdb()

 

models.py

from django.db import models


class UserInfo(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=16, null=True, blank=True, db_index=True)
    sex = models.IntegerField("性别", unique=True, choices=((1, '男'), (2, '女'), (3, '二椅子')))
    current_date = models.DateField(auto_now=True, auto_now_add=True)
# 创建一对一,一对多和多对多关系表

from django.db import models


# 作者表
class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    sex = models.IntegerField()
    authorDetail = models.OneToOneField(to="AuthorDetail")      # 作者和作者详细信息 一对一关系
    # authorDetail = models.OneToOneField(to="AuthorDetail", on_delete=models.CASCADE)    # 在django2.x版本后需要创建级联模式,如果不需要级联 on_delete=models.SET_NULL
    # 如果不创建nid,mysql会自动创建id,建立联系时候需要添加to_field
    # authorDetail = models.OneToOneField(to="AuthorDetail", to_field="id")

    def __str__(self):
        return self.name


# 作者详细信息表
class AuthorDetail(models.Model):
    nid = models.AutoField(primary_key=True)
    birthday = models.DateField()
    address = models.CharField(max_length=64)

    def __str__(self):
        return self.address


# 出版社
class Publish(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)
    email = models.EmailField()

    def __str__(self):
        return self.name


# 书籍表
class Books(models.Model):
    nid = models.AutoField(primary_key=True)
    title = models.CharField(max_length=32)
    publishDate = models.DateField()
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish = models.ForeignKey(to="Publish")               # 一个出版社可出版多本书籍  多对一关系
    authors = models.ManyToManyField(to="Author")           # 一个作者有多本书籍,一本书籍可由多个作者完成  多对多关系
    # authors = models.ManyToManyField(to="Author", through="BookToAuthor",through_fields=("author_id", "book_id"))    # 通过ManyToMany创建第三张表,并通过through指定表,through_fields指定外键名


    def __str__(self):
        return self.title


# 通过创建第三张表的方式,建立多对多关系,里面可以添加额外字段
# class BookToAuthor(models.Model):
#     book_id = models.ForeignKey(to="Books")
#     author_id = models.ForeignKey(to="Author")
#     other = models.CharField(max_length=32)


 

创建表

python manage.py makemigrations
python manage.py migrate

 

migrations文件夹

  • 当我们创建,修改或删除某些数据库字段时,migrations夹会记录每次操作
  • 同时数据库里面也有一个django_migrations的表记录了每次操作
  • 当执行创建命令时,系统会检测migrations文件夹,和之前做对比,如果没有改变就不执行
  • 当我们修改后,执行命令没有成功或没有检测时,可以清理对应的文件和数据库对应操作数据再执行

 

常用字段和参数


字段 

CharField        # 字符串字段,需要一个参数:maxlength最大长度
IntegerField     # 用于保存一个整数
DecimalField     # 浮点数,需要两个参数:max_digits最大长度,decimal_places小数位数
AutoField        # 自增,一般设置主键就可以
TextField        # 文本字段
EmailField       # 能够检验邮箱合法性的CharField,不接收maxlength
DateField        # 日期,参数:auto_now对象保存、修改或添加时设置当前时间,auto_now_add对象创建时设置为当前时间
DateTimeField    # 日期时间字段,支持同DateField同样的字段
BooleanField     # 布尔值类型
FileField        # 文件上传字段,需要一个参数:upload_to一个用于保存上载文件的本地文件系统路径. 这个路径必须包含 strftime #formatting,
ImageField       # 类似于FileField,校验上传对象是否为图片,参数:height_field和width_field,如果提供图片按照设置宽和高规则保存
URLField         # 用于保存url,参数verify_exists如果为True会检测是否存在(404)
NullBooleanField # 类似BooleanField,不过允许NULL作为一个选项
XMLField         # 检测是否为合法的xml的TextField,需要一个参数schema_path
IPAddressField   # 一个字符串形式的地址
CommaSeparatedIntegerField    # 用于存放逗号分隔的整数,必须有maxlength

参数

null            # 如果为True,django将用Null来在数据库存放空值。默认为false
blank           # 如果为True,该字段允许不填。默认为False。blank 是数据验证范畴的
default         # 字段默认值
primary_key     # 主键,如果没有指定Django 就会自动添加一个IntegerField字段做为主键
unique          # 唯一
choices         # 由二元组组成的一个可迭代对象(例如,列表或元组),用来给字段提供选择项。 如果设置了choices ,默认的表单将是一个选择框而不是标准的文本框
db_index        # 数据库索引
auto_now_add    # 配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库
auto_now        # 配置上auto_now=True,每次更新数据记录的时候会更新该字段,标识这条记录最后一次的修改时间。

 

表单操作


# 创建方式一
student_obj = models.Student(
        name='路飞',
        age=24,
        ...            # 相应字段
    )
    student_obj.save()

# 创建方式二
new_obj = models.Student.objects.create(name='娜美',age=18)

# 创建方式三,批量创建
obj_list = []
for i in range(100,3000000):
        obj = models.Student(
            name='香克斯',
            age = 10,
        )
        objs_list.append(obj)

    models.Student.objects.bulk_create(objs_list)

# 创建方式四,有就更新没有就创建
models.Student.objects.update_or_create(
        name='布鲁克',
        defaults={
            'age':38,
        }
    )

# 日期数据
import datetime
current_date = datetime.datetime.now()
# 两种方式
models.Brithday.objects.create(name='罗宾',date=current_date)
models.Brithday.objects.create(name='乔巴',date='2000-12-08')

通过外部文件方式操作django的models

import os

if __name__ == '__main__':
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "singletablehw.settings")
    import django
    django.setup()

    from app01 import models
    import datetime
    obj_list = []
    for i in range(1,10):
        obj = models.Book(
            title='冒险第%s册'%i,
            price=20 + i,
            pub_date='198%s-11-11 00:00:00'%i,
            # pub_date=datetime.datetime.now(),

            publish= '东海贼出版社' if i < 5 else '西海贼出版社',

        )
        obj_list.append(obj)

    models.Book.objects.bulk_create(obj_list)

models.Student.objects.get(id=3).delete()      # model对象来调用的delete方法
models.Student.objects.filter(name='路飞').delete()     # queryset对象调用delete方法
models.Student.objects.all().delete()     # 删除所有

注意:时间auto_now类型,使用方式一update是不会进行更新的,使用方式二没有问题。或者直接使用time模块将时间直接传

# model对象不能调用update方法
# 方式一:
models.Student.objects.filter(name='娜美').update(age=38)

# 方式二:
ret = models.Student.objects.filter(name='娜美')
ret.age = 18
ret.save()

# 错误方式:
models.Student.objects.get(name='娜美').update(age=38)  # 报错:'Student' object has no attribute 'update'

基本查询

# all 查询所有数据,返回queryset类型
all_object = models.Student.objects.all()

# filter 条件查询,返回queryset类型,没有数据返回空的queryset <QuerySet []>
objs = models.Student.objects.filter(id=2,name='娜美')

# get 条件查询,返回model对象,而且get方法必须只有一个结果
obj = models.Student.objects.get(id=2)

# exclude 排除查询,返回queryset类型
query = models.Student.objects.exclude(id=1)

# order_by 排序,queryset类型的数据来调用,对查询结果排序,默认是按照id来升序排列的,如果想降序添加-,返回值还是queryset类型
query = models.Book.objects.all().order_by('price','-id')

# reverse 反转,queryset类型的数据来调用,对查询结果反向排序,返回值还是queryset类型
query = models.Student.objects.all().order_by('id').reverse()

# count 统计数量,queryset类型的数据来调用,返回数据库中匹配查询(QuerySet)的对象数量
all_object = models.Student.objects.all().count()

# first 得到第一条数据,queryset类型的数据来调用,得到的是model对象
# Book.objects.all()[0] = Book.objects.all().first()

# last 得到最后一条数据,queryset类型的数据来调用,得到的是model对象

# exists queryset类型的数据来调用,如果QuerySet包含数据,就返回True,否则返回False

# values queryset类型的数据来调用,返回一个ValueQuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列,只要是返回的queryset类型,就可以继续链式调用queryset类型的其他的查找方法,其他方法也是一样的。

# values_list 和values一样,不过返回的是一个元组序列

# distinct 去重
query = models.Student.objects.all().values('age').distinct()

双下划线模糊查询

# sql:in
Book.objects.filter(price__in=[100,200,300])

# sql:>
Book.objects.filter(price__gt=100)

# sql:<
Book.objects.filter(price__lt=100)

# sql:between and
Book.objects.filter(price__range=[100,200])        # 100<= price >= 200

# 包含
Book.objects.filter(title__contains="python")

# 不区分大小写
Book.objects.filter(title__icontains="python") 

# 以什么开头,不区分大小写
Book.objects.filter(title__startswith="py") 

# 时间,根据年、月等查询
Book.objects.filter(pub_date__year=2020, pub_date__month__gt=2)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值