ORM Mysql Django Models 模型详解

Django models

ORM是“对象-关系-映射”的简称,主要作用是定义模型类以及属性。每个模型都可以被映射为数据库中的一个数据表,而类属性被映射为为数据字段。
在这里插入图片描述
models 编码风格

from django.db import models
class ModelName(models.Model):
  field1 = models.xxfield(..)
  field2 = models.xxfield(..)
  ...
  class Meta:
    db_table  = ...
    other_metas = ...

ORM 实例映射

creat

# 创建表sql
CREATE TABLE employee(
id INT PRIMARY KEY auto_increment ,
name VARCHAR (20),
gender BIT default 1,
birthday DATA ,
department VARCHAR (20),
salary DECIMAL (8,2) unsigned,
);

# 创建表ORM
class Employee(models.Model):
id=models.AutoField(primary_key=True)
name=models.CharField(max_length=32)
gender=models.BooleanField()
birthday=models.DateField()
department=models.CharField(max_length=32)
salary=models.DecimalField(max_digits=8,decimal_places=2)

增删改查

# 添加表数据sql
INSERT employee (name,gender,birthday,salary,department)
VALUES ("alex",1,"1985-12-12",8000,"保洁部");
# 添加表数据ORM
emp=Employee(name="alex",gender=True,birthday="1985-12-12",epartment="保洁部")
emp.save()

# 查询表数据sql
SELECT * FROM employee WHERE age=24;
# 查询表数据ORM
Employee.objects.filter(age=24)

# 更新表数据sql
UPDATE employee SET birthday="1989-10-24" WHERE id=1;
# 更新表数据ORM
Employee.objects.filter(id=1).update(birthday="1989-10-24")

# 删除表数据sql
DELETE FROM employee WHERE name="alex"
# 删除表数据ORM
Employee.objects.filter(name="alex").delete()

说明
1、表名称是自动生成的,如果需要自定义表名,需要在model的Meta类中指定 db_table 参数,建议使用小写表名,特别是使用MySQL作为后端数据库时。
2、id字段是自动添加的,如果想要指定自定义主键,只需在其中一个字段中指定 primary_key=True 即可。如果Django发现你已经明确地设置了Field.primary_key,它将不会添加自动ID列。
3、Django会根据配置文件中指定的数据库后端类型来生成相应的SQL语句,支持MySQL5.5及更高版本。

ORM 多对一关系

假设一个公司有多个员工,多个员工隶属于一个公司。
可以用foreign key来指定多对一的关系

# models.py
class Department(models.Model): # 主表
    dep_name = models.CharField(max_length=20,verbose_name='部门名称')
    desc = models.CharField(max_length=20,verbose_name='部门描述')

    class Meta: # 从表
        verbose_name = "部门表"
        verbose_name_plural = verbose_name
        db_table = 'department'
    def __str__(self):
        return self.dep_name

class Employee(models.Model):
    emp_name = models.CharField(max_length=20,verbose_name='姓名')
    job = models.CharField(max_length=20,verbose_name='职位')
    salary = models.IntegerField(verbose_name='工资')
    dapartment = models.ForeignKey(to=Department, on_delete=models.CASCADE, verbose_name='部门')

    class Meta:
        verbose_name = "员工表"
        verbose_name_plural = verbose_name
        db_table = 'employee'
    def __str__(self):
        return self.emp_name
# views.py
class DepartmentView(View):
    def get(self,request):
        department = Department.objects.all()
        return render(request,'department.html',{
    
    'department':department})
       <以下代码为增加操作,上面的代码为方便写路由>
    def post(self,request):
        emp_name = request.POST.get('emp_name')
        job = request.POST.get('job')
        salary = request.POST.get('salary')
        dapartment = request.POST.get('dapartment')
        try:
            Employee.objects.create(
                emp_name=emp_name,
                job=job,
                salary=salary,
                dapartment_id=dapartment)
        except Exception as e:
            print(e)
            return HttpResponse("添加失败")
        return redirect('/dep/')
        
# url路由
path('dep/',views.DepartmentView.as_view()),
 

# 删

class DelEmployeeView(View):
    def get(self,request,id):
        employee_data = Employee.objects.get(id=id)
        dep_id = employee_data.dapartment_id
        employee_data.delete()
        return redirect(f'/emp/{
      
      dep_id}')
        
# url路由
path('delemp/<int:id>/',views.DelEmployeeView.as_view()),

# 改

class UpdateEmployeeView(View):
    def get(self,request,id):
        try:
            employee_data = Employee.objects.get(id=id)
        except Exception as e:
            print(e)
            return HttpResponse("页面不存在")
        return render(request,'index.html',{
    
    'employee':employee_data})
    def post(self,request,id):
        emp_name = request.POST.get('emp_name')
        job =  request.POST.get('job')
        salary = request.POST.get('salary')
        dapartment = request.POST.get('dapartment')
        try:
            Employee.objects.filter(id=id).update(
                emp_name = emp_name,
                job = job,
                salary = salary,
                dapartment_id = dapartment
            )
        except Exception as e:
            print(e)
            return HttpResponse('修改数据失败')
        return redirect('/dep/')

# url路由
path('updateemp/<int:id>/',views.UpdateEmployeeView.as_view())

# 点击主表某字段以获取从表对应信息
class EmployeeView(View):
    def get(self,request,id):
        employee = Employee.objects.filter(dapartment_id=id)
        return render(request,'employee.html',{
    
    'employee':employee})

# url路由
    path('emp/<int:id>/',views.EmployeeView.as_view()),

ORM 一对一关系

假设一个人只能有一个对象,一个人不能有多个对象
使用OneToOneField用来定义一对一关系

主表查子表将子表名小写
子表查主表直接用连接的字段来查即可

ORM 多对多关系

假设一个音乐家隶属于多个乐队,而一个乐队有多个音乐家。
使用ManyToManyField字段定义

数据的添加
模型类.objects.create(需要添加的字段=‘’)
乐队 = 表名.objects.create(表名小写_name=“Jack”)
数据的删除
乐队.表名.remove(音乐家)
数据的查询
主表查子表
主表.band_set.all()
子表查主表
子表.主表字段.all()

常用字段

字段名 详解
AutoField int自增列,必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列。
IntegerField 一个整数类型,范围在 -2147483648 to 2147483647。(一般不用它来存手机号(位数也不够),直接用字符串存
CharField 字符类型,必须提供max_length参数, max_length表示字符长度。Django中的CharField对应的MySQL数据库中的varchar类型,没有设置对应char类型的字段
DateField 日期字段,日期格式 YYYY-MM-DD,相当于Python中的datetime.date()实例。
DateTimeField 日期时间字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相当于Python中的datetime.datetime()实例。
字段参数
null 用于表示某个字段可以为空。
unique 如果设置为unique=True 则该字段在此表中必须是唯一的 。
db_index 如果db_index=True 则代表着为此字段设置索引。
default 为该字段设置默认值。
auto_now_add DateField和DateTimeField,配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库。
auto_now 配置上auto_now=True,每次更新数据记录的时候会更新该字段。
关系字段
ForeignKey 外键类型在ORM中用来表示外键关联关系,一般把ForeignKey字段设置在 '一对多’中’多’的一方。ForeignKey可以和其他表做关联关系同时也可以和自身做关联关系。
字段参数
to 设置要关联的表。
to_field 设置要关联的字段
on_delete 当删除关联表中的数据时,当前表与其关联的行的行为。(参考上面的例子)
ManyToManyField 用于表示多对多的关联关系。在数据库中通过第三张表来建立关联关系
related_name 同ForeignKey字段
related_query_name 同ForeignKey字段。
symmetrical 仅用于多对多自关联时,指定内部是否创建反向操作的字段。默认为True。
through 在使用ManyToManyField字段时,Django将自动生成一张表来管理多对多的关联关系。但我们也可以手动创建第三张表来管理多对多关系,此时就需要通过through来指定第三张表的表名。
through_fields 设置关联的字段。
db_table 默认创建第三张表时,数据库中表的名称。

这里的 CreatedTime和uLastUpdatedTime存到数据库中的时间总是UTC时区的时间(比北京时间慢了8个小时)。如果不需要在程序中特别处理时区(timezone-aware),显示为北京时间,就要把时区关闭:

将全局设置settings.py中的USE_TZ = True 改为 USE_TZ = False 即关闭时区

如果还要保持USE_TZ=True,则可设置为CreatedTime = models.DateTimeField(default=datetime.now().replace(tzinfo=utc))。

Meta 类

Meta类封装了一些数据库的信息

字段名 详解
db_table ORM在数据库中的表名默认是 app_类名,可以通过db_table可以重写表名。
index_together 联合索引
unique_together 联合唯一索引,unique_together这个选项用于:当你需要通过两个字段保持唯一性时使用。比如假设你希望,一个Person的FirstName和LastName两者的组合必须是唯一的,那么需要这样设置:unique_together = ((“first_name”, “last_name”),) 一个ManyToManyField不能包含在unique_together中。如果你需要验证关联到ManyToManyField字段的唯一验证,尝试使用signal(信号)或者明确指定through属性。
ordering 指定默认按什么字段排序。ordering=[‘order_date’] # 按订单升序排列ordering=[‘-order_date’] # 按订单降序排列,-表示降序ordering=[‘?order_date’] # 随机排序,?表示随机ordering=[‘-pub_date’,‘author’] # 以pub_date为降序,在以author升序排列
verbose_name verbose_name的意思很简单,就是给你的模型类起一个更可读的名字一般定义为中文,我们:verbose_name = “学校”
verbose_name_plural 这个选项是指定,模型的复数形式是什么,比如:verbose_name_plural = "学校"如果不指定Django会自动在模型名称后加一个’s’
abstract Options.abstract 这个属性是定义当前的模型是不是一个抽象类。所谓抽象类是不会对应数据库表的。一般我们用它来归纳一些公共属性字段,然后继承它的子类可以继承这些字段。如果abstract = True 这个model就是一个抽象类
app_label 这个选型只在一种情况下使用,就是你的模型不在默认的应用程序包下的models.py文件中,这时候需要指定你这个模型是哪个应用程序的。如果一个model定义在默认的models.py,例如如果你的app的models在myapp.models子模块下,你必须定义app_label让Django知道它属于哪一个app,app_label = ‘myapp’
db_teblespace 定义这个model所使用的数据库表空间。如果在项目的settin中定义那么它会使用这个值
get_latest_by 在model中指定一个DateField或者DateTimeField。这个设置让你在使用model的Manager上的lastest方法时,默认使用指定字段来排序
managed 默认值为True,这意味着Django可以使用syncdb和reset命令来创建或移除对应的数据库。默认值为True,如果你不希望这么做,可以把manage的值设置为False
order_with_respect_to 这个选项一般用于多对多的关系中,它指向一个关联对象,就是说关联对象找到这个对象后它是经过排序的。指定这个属性后你会得到一个get_xxx_order()和set_xxx_order()的方法,通过它们你可以设置或者回去排序的对象
permissions permissions主要是为了在Django Admin管理模块下使用的,如果你设置了这个属性可以让指定的方法权限描述更清晰可读。Django自动为每个设置了admin的对象创建添加,删除和修改的权限。
proxy 这是为了实现代理模型使用的,如果proxy = True,表示model是其父的代理 model

猜你喜欢

转载自blog.csdn.net/weixin_43587784/article/details/129086558
今日推荐