Day 08 ORM表单创建及查询

Day 08 表单创建及查询

一、多表操作之模型创建

首先整理相关关系(逻辑上存在错误o(╥﹏╥)o)

Models

from django.db import models


# Create your models here.
class Company(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    address = models.CharField(max_length=254)
    leader = models.CharField(max_length=32)


class Department(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32, unique=True)
    task = models.CharField(max_length=32)
    established = models.DateTimeField()
    # to='Employee'Employee(ForeignKey,一对多)
    # to_field='id'跟哪个字段做关联
    # ForeignKey对到数据中的字段是int类型
    # employee=models.ForeignKey(to='Publish',to_field='id')
    # employee = models.ForeignKey(to='Publish')  # 不写,默认跟主键做关联
    
    employee = models.ForeignKey(to='Employee')  # 一个部分拥有多个员工
    company = models.ManyToManyField(to='Company')  # 不同公司拥有相同部门


class Employee(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    gender = models.SmallIntegerField()
    employee_detail = models.OneToOneField(to='EmployeeDetail', to_field='id', on_delete=models.CASCADE)


class EmployeeDetail(models.Model):  # 无足轻重
    id = models.AutoField(primary_key=True)
    salary = models.IntegerField()
    address = models.CharField(max_length=254)
    phone = models.CharField(max_length=32)
 
6 同步到mysql数据库
	-配置文件
    -pymysql.install_as_mysqldb()
		-公司可以用过的mysqlclient
    -两条命令
    
7 2.x版本的django
	-外键字段必须加  参数:on_delete
    -1.x版本不需要,默认就是级联删除
    -假设,
    	删除出版社,该出版社出版的所有图书也都删除,on_delete=models.CASCADE
        删除出版社,该出版社出版的图书不删除,设置为空on_delete=models.SET_NULL,null=True
        删除出版社,该出版社出版的图书不删除,设置为默认on_delete=models.SET_DEFAULT,default=0

批量写入文件(相关配置)

faker相关用法参考

import django, os, random, time
from faker import Faker

f = Faker(locale='zh-CN')  # 设置成中国信息

a1 = (2000, 1, 1, 0, 0, 0, 0, 0, 0)  # 设置开始日期时间元组(2020-01-01 00:00:00)
a2 = (2015, 12, 31, 23, 59, 59, 0, 0, 0)  # 设置结束日期时间元组(2015-12-31 23:59:59)

start = time.mktime(a1)  # 生成开始时间戳
end = time.mktime(a2)  # 生成结束时间戳

t = random.randint(start, end)  # 在开始和结束时间戳中随机取出一个
date_touple = time.localtime(t)  # 将时间戳生成时间元组
date = time.strftime("%Y-%m-%d", date_touple)  # 将时间元组转成格式化字符串(1976-05-21)

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

二、基本写入文件

    # 普通添加记录
    job_list = []
    for i in range(10):
        Company.objects.create(
            name=f.company(),
            address=f.province() + f.street_address(),
            leader=f.name(),
        )
    # 一对一添加记录,注意先后顺序
    for i in range(40):
        job_name = f.name()
        job_list.append(job_name)
        res = EmployeeDetail.objects.create(
            salary=random.randint(8000, 15000),
            address=f.address(),
            phone=f.phone_number(),
        )
        Employee.objects.create(
            name=f.name(),
            gender=random.randint(0, 1),
            employee_detail=res
        )

三、一对多添加记录

    for i in range(15):
        t = random.randint(start, end)  # 在开始和结束时间戳中随机取出一个
        date_tuple = time.localtime(t)  # 将时间戳生成时间元组
        date = time.strftime("%Y-%m-%d", date_tuple)  # 将时间元组转成格式化字符串
        Department.objects.create(
            name=f.job(),
            task=f.job()[0:4],
            established=date,
            # 一对多文件写入 写入对象
            employee=Employee.objects.get(id=random.randint(1, 40)),
            # company=Company.objects.get(id=random.randint(115, 144))
            # 这种方法暂时不要使用
            #如果Model中包含多对多关系,那么就会报错:ValueError: “needs to have a value for field ”id“ before this many-to-many relationship can be used”解决办法是,先把data中的多对多数据取出,然后创建model,最后建立多对多关系。
        )

由于多对多字段还没有创建,所以创建的关联表中是没有数据image-20201014203942350

四、多对多文件写入(相关api add ,remove,set clear)

1、通过id新增

company从115开始是因为我有这么多数据img

# 1.首先我们要找到 含有多对多表的一个对象
    # for i in range(10):
    #     department = Department.objects.get(id=i+1)
    #     # 可以添加 多个值
    #     department.company.add(random.randint(115, 144))
    department = Department.objects.get(id=11)
    # 可以添加 多个值
    department.company.add(115, 120)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fx48UNKh-1602727694098)(C:\Users\S\AppData\Roaming\Typora\typora-user-images\image-20201014211026059.png)]

这样多对多的数据就写入进去了

2、通过对象添加字段

    company1 = Company.objects.get(id=122)
    company2 = Company.objects.get(id=126)
    department = Department.objects.get(id=14)
    # 可以添加 多个值
    department.company.add(company1, company2)
    # 同样可以混合添加
    department.company.add(133, company2)

3、修改删除

3.1 删除(remove clear)
    # 选择删除
    department = Department.objects.get(id=14)
    # 删除部门id为14 的company1 同样也可以为id
    department.company.remove(company1)
    
    # 全部删除
    department = Department.objects.get(id=14)
    # 删除部门id为14 所有的公司
    department.company.clear()

注意:没有相关联的id也是不会报错的

3.2修改(set)
    # set是先清空再添加作者
    
    department = Department.objects.get(id=14)
    department.company.add(133)
    department.company.set({144: 122})
image-20201014212705934
跨表查询有两种方式

-基于对象的跨表查询:子查询

-基于双下划线的跨表查询:关联查询,连表查询

五、基于对象的跨表查询(正向反向)

一对一查询(不适用set)

# 正向查询
# id为1的 职员 的电话号码
    employee = Employee.objects.get(id=1)
    employee_detail = employee.employee_detail
    print(employee.name, employee_detail.phone)
    
    
# 反向查询
# 电话号码为 13653093989 的职员名字
    employee_detail = EmployeeDetail.objects.get(phone='13653093989')
    name = employee_detail.employee.name
    print(name)

一对多查询

#1.查询主键为1的 部门 的 职员 所在的地址
    # 1.查询主键为1的 部门 的 职员 所在的地址
    department = Department.objects.get(id=1)
    employee = department.employee  # 找到id为i 对应的职员
    employee_address = employee.employee_detail.address  # 一对一查找他的信息找到地址
    print(employee_address)

    # 反向查找
    # id为9的 职员 所在部门的名字
    employee = Employee.objects.get(id=9)
    department = employee.department_set.all().first().name
    print(department)

多对多查询

    # 正向
    # 1. id为14的 部门 所对应的 公司 名字
    department = Department.objects.get(id=14)
    companys = department.company.all()
    for i in companys:
        print(i.name)
    
    # 反向
    # 2. 查询主键为124的 公司 的 所有部门 名称 这其实是反向查找,company上是没有关联键的,
    #表名小写_set.方法()
    company = Company.objects.get(id=124)
    departments = company.department_set.all()
    for i in departments:
        print(i.name)
正向查找:

有关联表内的 关联字段 直接对象.字段名

反向查找(不适用一对一):

被关联表没有关联字段 被关联表对象.关联表名小写_set.all()

六.基于双下划线的跨表查询

连表查询

基于对象的跨表查询,先查对象,通过对象再去查另一个对象(正向:字段名,反向:表名小写/表名小写_set.all())

一对多

正向:字段名
反向:表名小写
filter,values,values_list(写 __ 跨表)
# id为124公司名字 所有的部门名字,任务
# 反向
    res1 = Company.objects.filter(id=124).values('department__name', 'department__task')
    for i in res1:
        print(i)
#正向  
    res2 = Department.objects.filter(company__id=124).values('name', 'task')
    for i in res2:
        print(i)
----------------------------------------------
{'department__name': '市场助理', 'department__task': '手机应用'}
{'department__name': '广告创意/设计主管/专员', 'department__task': '地勤人员'}
{'department__name': '救生员', 'department__task': '调研员'}
{'department__name': '磨工', 'department__task': '促销主管'}

多对多

    #反向
    # res=models.Author.objects.filter(name='egon').values('book__name','book__price')
    # print(res)

    # 正向
    # res=models.Book.objects.filter(authors__name='egon').values('name','price')
    # print(res)

    #查询egon的手机号
    # res=models.Author.objects.filter(name='egon').values('author_detail__phone')
    # print(res)
    # res=models.AuthorDetail.objects.filter(author__name='egon').values('phone')
    # print(res)

七、进阶连续跨表查询

# 员工信息id为 7 的 员工所在的公司名字
    res = EmployeeDetail.objects.get(id=7).employee.department_set.values('company__name', 'company__address')
    print(res)
# 先找到 detail对象,一对一找到employee对象, 反向查找到 department对象 最后基于双下划线查询到具体

扩展

1 看一看这篇博客

https://www.cnblogs.com/nokiaguy/p/13803370.html

2 安装模块相关

pip3 install django    
# 本质是去https://pypi.python.org/simple,搜这个模块,会根据你的平台下载在一个安装包(windows平台是whl),下载完,再安装

# pip安装失败的情况
# 我们可以绕过它,有了whl文件以后,自己装
# https://www.lfd.uci.edu/~gohlke/pythonlibs/#opencv
pip3 install django.whl   

# 官方库没有上传到pypi,官方也不给制作whl文件
#如何安装  包 (setup.py)
到达安装目录,setup.py所在的目录
python setup.py build
python setup.py install

# 配置清华源,豆瓣源,本质是
豆瓣源会把pypi,包拉到自己的服务器上,以后你再下,去它的服务器上下,所以速度快

# 你自己写的包,如何上传到pypi上给别人使用?

2 外键关系要不要建立

1 关联字段与外键约束没有必然的联系(建管理字段是为了进行查询,建约束是为了不出现脏数据)
2 默认情况,关联关系建好以后,外键约束就自然建立了
3 实际工作中,外键约束一般不建(影响效率),都是人为约束(代码约束)
	-db_constraint=False
4 表模型和数据库表的对应,不要直接修改表(这是可以的,但是不建议),要修改表模型,同步到表中
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值