Django中model层详解

#!/usr/bin/env python
# _*_ coding:utf-8 _*_

from django.db import models


class UserType(models.Model):
nid = models.AutoField(primary_key=True) # 自增 主键
caption = models.CharField(max_length=16)


class UserInfo(models.Model):
username = models.CharField(max_length=32)
email = models.EmailField(max_length=32)
pwd = models.CharField(max_length=32)
user_type = models.ForeignKey("UserType")
# UserType也可以不加引号,加了引号之后,UserInfo表可以放在UserType的上面


# 单表基本操作

# 增
# 第一种方法:
models.UserInfo.objects.create(username='aaron',
email='aaron@163.com',
pwd='123',
)
# 第二种方法:

user_dict = {
'username':'aaron',
'email':'aaron@qq.com',
'pwd':123,
'user_type':UserType.objects.get(nid=1), #nid为1的数据类型对象
}

user_dict = {
'username':'aaron',
'email':'aaron@qq.com',
'pwd':123,
'user_type_id':1
}



models.UserInfo.objects.create(**user_dict)
# 增加一条数据,可以接受字典类型数据 **kwargs

obj = models.UserType(caption='超级管理员')
obj.save()

# 查

models.UserInfo.objects.get(id=1) # 获取单条数据,不存在则报错
models.UserInfo.objects.all() # 获取全部数据
models.UserInfo.objects.filter(username='aaron') # 获取指定条件的数据
# 删
models.UserInfo.objects.filter(username='aaron').delete() # 删除指定条件的数据

# 改
models.UserInfo.objects.filter(username='aaron').update(pwd='456')
# 将指定条件的数据更新,均支持 **kwargs
obj = models.UserInfo.objects.get(id=1)
obj.pwd = '123'
obj.save()


models.UserInfo.objects.filter(id__gt=1).count() # 获取个数
models.UserInfo.objects.filter(id__gt=1) # 获取id大于1的值
models.UserInfo.objects.filter(id__gte=1) # 获取id大于等于1的值
models.UserInfo.objects.filter(id__lt=10) # 获取id小于10的值
models.UserInfo.objects.filter(id__lte=10) # 获取id小于10的值
models.UserInfo.objects.filter(id__lt=10, id__gt=1)
# 获取id大于1 且 小于10的值,逗号默认取并集
models.UserInfo.objects.filter(id__in=[11, 22, 33]) # 获取id等于11、22、33的数据
models.UserInfo.objects.exclude(id__in=[11, 22, 33]) # not in

models.UserInfo.objects.filter(username__contains="ron")
# 相当于百分号
models.UserInfo.objects.filter(username__icontains="ron") # icontains大小写不敏感
models.UserInfo.objects.exclude(username__icontains="ron")
models.UserInfo.objects.filter(id__range=[1, 2]) # 范围bettwen and
models.UserInfo.objects.filter(id__gt=1).order_by('id') # asc
models.UserInfo.objects.filter(id__gt=1).order_by('-id') # desc

# groupby
models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))
# 这里的values和annotate组合一起,意思是以ID进行分组,计算每组的个数
# group_by id
# SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"

# offset
models.UserInfo.objects.all()[2:3]


# 连表操作
class UserProfile(models.Model):
user_info = models.OneToOneField('UserInfo')
username = models.CharField(max_length=64)
password = models.CharField(max_length=64)

def __unicode__(self):
return self.username


class UserInfo(models.Model):
user_type_choice = (
(0, u'普通用户'),
(1, u'高级用户'),
)
user_type = models.IntegerField(choices=user_type_choice)
name = models.CharField(max_length=32)
email = models.CharField(max_length=32)
address = models.CharField(max_length=128)

def __str__(self):
return self.name


class UserGroup(models.Model):

caption = models.CharField(max_length=64)

user_info = models.ManyToManyField('UserInfo')

def __str__(self):
return self.caption


class Host(models.Model):
hostname = models.CharField(max_length=64)
ip = models.GenericIPAddressField()
user_group = models.ForeignKey('UserGroup')

def __str__(self):
return self.hostname


user_info_obj = models.UserInfo.objects.filter(id=1).first()
# 筛选出userinfo ID为1的数据(对象)
print user_info_obj.user_type
# 拿到id为1这行数据的对象的用户类型
print user_info_obj.get_user_type_display()
print user_info_obj.userprofile.password
# print user_info_obj.userprofile_set.password???
# 拿到id为1这行数据的对象的密码,这个密码信息存放在userprofile表,

user_info_obj = models.UserInfo.objects.filter(id=1).values('email', 'userprofile__username').first()
# 筛选出userinfo ID为1的数据(对象)并且取email, userprofile__username这两列
print user_info_obj.keys()
print user_info_obj.values()
<QuerySet [{'pwd': '123', 'username': 'alex'},
{'pwd': '123', 'username': 'erice'}]>

# 小总结:
# 1、搜索条件使用 __ 连接
# 2、获取值时使用 . 连接


# 多对多操作
user_info_obj = models.UserInfo.objects.get(name=u'aaron')
# 拿到UserInfo表name列为aaron的那一行数据(对象)
user_info_objs = models.UserInfo.objects.all()
# 拿到UserInfo表的所有数据(对象)
group_obj = models.UserGroup.objects.get(caption='CEO')
# 拿到UserGroup表caption列为CEO的那一行数据(对象)
group_objs = models.UserGroup.objects.all()
# 拿到UserGroup表的所有数据(对象)

# 添加数据
group_obj.user_info.add(user_info_obj)
# 正向
# 把UserInfo表name列为aaron的那一行数据(对象)添加到ceo这个用户组
# group_obj.user_info表示CEO这个组的用户信息(也就是这个组有什么用户),应该是一个对象集合
group_obj.user_info.add(*user_info_objs)

# 删除数据
group_obj.user_info.remove(user_info_obj)
group_obj.user_info.remove(*user_info_objs)

# 添加数据
user_info_obj.usergroup_set.add(group_obj)
# 反向
# UserInfo表name列为aaron的那一行数据(对象)所在的用户组信息(就是有哪些组),再添加CEO组
user_info_obj.usergroup_set.add(*group_objs)

# 删除数据
user_info_obj.usergroup_set.remove(group_obj)
user_info_obj.usergroup_set.remove(*group_objs)

# 获取数据
print group_obj.user_info.all()
print group_obj.user_info.all().filter(id=1)

# 获取数据
print user_info_obj.usergroup_set.all()
print user_info_obj.usergroup_set.all().filter(caption='CEO')
print user_info_obj.usergroup_set.all().filter(caption='DBA')


# 注意问题:
# 1.单表操作,跨表操作
# 2.跨表操作肯定涉及到一对一(其实是外键+unique),一对多,多对多
# 3.跨表操作:
# 正向,反向,看外键在哪,
# 正向:group_obj.user_info.all()
# 获取值:
# 搜索(fileter,value):
# 反向:user_info_obj.usergroup_set.all()
#


# 唯一组合索引与 普通组合索引
class Meta:
unique_together =[
("username","email"),
]
# class Meta:
# index_together =[
# ("username","email"),
# ]

# 创建多对多有两种方式
# 第一种:
class HostToGroup(models.Model):
hgid =models.AutoField(primary_key=True)
hid = models.ForeignKey('Host')
gid = models.ForeignKey("Group")

class Host(models.Model):
hid = models.AutoField(primary_key=True)
hostname = models.CharField(max_length=32)
ip = models.CharField(max_length=17)

class Group(models.Model):
gid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)


# 第二种:
class Host(models.Model):
hid = models.AutoField(primary_key=True)
hostname = models.CharField(max_length=32)
ip = models.CharField(max_length=17)

# h2g = models.ManyToManyField('Group')
# group_set 反向查的对象

class Group(models.Model):
gid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)

h2g = models.ManyToManyField('Host')
# h2g = models.ManyToManyField('Host',through="HostToGroup")

# 增:插入数据
models.HostToGroup.objects.create(hid=1,gid=1)
models.HostToGroup.objects.create(hid=1,gid=2)
models.HostToGroup.objects.create(hid=1,gid=3)

# 正向:
obj = models.Group.objects.get(gid=1)
obj.h2g.add(*models.Host.objects.all())
# 把所有的主机都添加到i d为1的组

h2 = models.Host.objects.get(hid=2)
h1 = models.Host.objects.get(hid=1)
q = models.Host.objects.filter(hid__gt=3)
obj.h2g.add(*q)


# 将一台机器,分给多个组
h = models.Host.objects.get(hid=1) # id为1的机器
obj = models.Group.objects.get(gid=1) # id为1的组
obj.h2g.add(h) #组id为1的组添加主机id为1的机器
obj = models.Group.objects.get(gid=2)
obj.h2g.add(h) #组id为2的组添加主机id为1的机器

# 反向:
h = models.Host.objects.get(hid=1)
h.group_set.add(*models.Group.objects.filter(gid__gt = 2))
# 主机id为1的主机所对应的组,如果原先的组有了就不添加,没有就继续添加

h.group_set.add(1)
h.group_set.add(models.Group.objects.get(gid=1))
h.group_set.add(*[1,2,3])
h.group_set.add(*models.Group.objects.filter(gid__gt=1))

# 正向,反向,增删改查,filter,values,一对多,多对多

# 正向:
# 增删改:
# obj = models.Group.objects.get(gid=1)
# obj.h2g.add(*models.Host.objects.all())
#
# 查:
# print group_obj.user_info.all()
# print group_obj.user_info.all().filter(id=1)
#
# 反向:
# 增删改:
# h = models.Host.objects.get(hid=1)
# h.group_set.add(*models.Group.objects.filter(gid__gt = 2))
#
# 查:
# 有filter,values:
# models.UserInfo.objects.filter(id=1).values('email', 'userprofile__username').first()
# print user_info_obj.usergroup_set.all().filter(caption='CEO')
# models.UserType.objects.all().values('caption','userinfo')
# models.UserType.objects.all().values('caption','userinfo__user')
#
# 无filter,values:
# print user_info_obj.usergroup_set.all()


原文地址:https://www.cnblogs.com/liangweixiong/p/6418158.html