美文网首页
一个模糊的问题,梳理清楚

一个模糊的问题,梳理清楚

作者: 词穷又词贫 | 来源:发表于2017-08-20 12:49 被阅读91次

django模型中一对多与多对多关系梳理,三天时间慢慢梳理完。

一对多关系即是数据库中外键约束。
多对多关系既是数据库中两个表关联形成多对多关系(通过中间表,将在此表中设置两个外键字段分别为另外两张表的主键)。

问题:
1、如何在django模型中建立此类关联关系?又是如何反应到实际数据库中?
2、在视图中如何利用模型类操作数据库?
3、在关联关系中,如何更新数据库?(多对多关系)
4、在关联关系中,如何查询数据库?(多对多关系)
5、在关联关系中,如何进行多级关系深度查询?(一对多,多对多分开讲)

练习数据库

1,2问题比较简单,直接上代码:

1、问题解答:
# 主机表
class Host(models.Model):
    id = models.AutoField(primary_key=True)
    hostname = models.CharField(max_length=50)
    lanip = models.GenericIPAddressField()

    class Meta:
        managed = True
        db_table = 'host'

# 主机组表
class HostGroup(models.Model):
    hgid = models.AutoField(primary_key=True)
    hgname = models.CharField(max_length=50)
    hginfo = models.CharField(max_length=200,default='null')
    hosts = models.ManyToManyField(Host)

    class Meta:
        managed = True
        db_table = 'hostgroup'

# 用户组表
class UserGroup(models.Model):
    gid = models.AutoField(primary_key=True)
    groupname = models.CharField(max_length=50)
    ginfo = models.CharField(max_length=200,default='null')
    userpri = models.BooleanField(default=False,null=False)
    grouppri = models.BooleanField(default=False,null=False)
    hgrouppri = models.BooleanField(default=False,null=False)
    hostgroups = models.ManyToManyField(HostGroup)

    class Meta:
        managed = True
        db_table = 'usergroup'

# 角色表
class Role(models.Model):
    name = models.CharField(max_length=10)
    class Meta:
        managed = True
        db_table = 'role'

# 用户表
class User(models.Model):
    uid = models.AutoField(primary_key=True)
    username = models.CharField(max_length=50)
    password = models.CharField(max_length=50)
    user = models.CharField(max_length=50)
    role = models.ForeignKey(Role,default=1)
    groups = models.ManyToManyField(UserGroup)

    class Meta:
        managed = True
        db_table = 'user'
  # 解释:
  # Role与User表建立一对多关联关系
  # 其他表之间建立多对多关联关系,比如User与UserGroup表之间,是在User类中定义一个名字为groups的类属性,利用ManyToManyField多对多关系关联两表,此类型字段只需要在两张表中任意一张表定义即可,无需两张表都定义,模型的管理器会自动在数据库中建立中间表来实现。
  # 数据库中,表情况:
数据库表 多对多关系表生成中间表
2、问题解答:(访问test接口测试更新数据)

1、利用模型对象更新数据(无外键):

def test(request):
    for i in xrange(1,4):
        rl = Role()
        rl.name = "role" + str(i)
        rl.save()
    return HttpResponse("data")
# 往role表中插入数据,定义Role对象,字段,对象调去save()方法即可,模型管理器会自动识别你是否在此类中定义主键,如果没有会自动添加id字段为主键,自增长。

2、利用模型对象更新数据(有外键):

def test(request):
    # for i in xrange(1,4):
    #     rl = Role()
    #     rl.name = "role" + str(i)
    #     rl.save()

    for i in xrange(1,15):
        if i <= 3:
            rl = Role.objects.get(pk=1)
            us = User()
            us.username = 'admin' + str(i)
            us.password = 'admin' + str(i)
            us.user = 'neo' + str(i)
            us.role = rl
            us.save()
        elif 3 < i <= 7:
            rl = Role.objects.get(pk=2)
            us = User()
            us.username = 'admin' + str(i)
            us.password = 'admin' + str(i)
            us.user = 'neo' + str(i)
            us.role = rl
            us.save()
        elif 7 < i <= 10:
            rl = Role.objects.get(pk=3)
            us = User()
            us.username = 'admin' + str(i)
            us.password = 'admin' + str(i)
            us.user = 'neo' + str(i)
            us.role = rl
            us.save()
  # 利用模型类对象更新具有外键约束表时,需要先创建外键约束对应对象,接在在更新到表中,否则会失败。
3、问题解答:(一对多关系是外键约束更新数据上面既是)

关联管理器在一对多,多对多的关联上下文中使用的管理器:
ForeignKey关系:(一对多关系)

class Role(models.Model):
    # ...
    pass
class User(models.Model):
    role = models.ForeignKey(Role)
# 这样,管理器可以使用role.user_set方法。

ManyToMany关系:(多对多关系)

class UserGroup(models.Model):
    # ...
    pass
class User(models.Model):
    groups = models.ManyToManyField(UserGroup)
# 这样,管理器可以使用usergroup.user_set和user.groups方法。

多对多关联关系更新数据:先将host,hostgroup,usergroup数据填充上。

# 填充host数据
for i in xrange(1,10):
    ser = Host()
    ser.hostname = "hostname" + str(i)
    ser.lanip = "10.10.10." + str(i)
    ser.save()
# 填充hostgroup数据
for i in xrange(1,5):
    hg = HostGroup()
    hg.hgname = "hg" + str(i)
    hg.hginfo = "hginfo" + str(i)
    hg.save()
# 填充usergroup数据
for i in xrange(1,5):
    ug = UserGroup()
    ug.groupname = 'ugname' + str(i)
    ug.save()

多对多关联关系更新数据:
比如User与UserGroup表之间的多对多关系。

# 获取用户组对象
ug1 = UserGroup.objects.get(pk=1)
ug2 = UserGroup.objects.get(pk=2)
ug3 = UserGroup.objects.get(pk=3)
ug4 = UserGroup.objects.get(pk=4)
# 获取用户对象
u1 = User.objects.get(pk=1)
u2 = User.objects.get(pk=2)
u3 = User.objects.get(pk=3)
u4 = User.objects.get(pk=4)
u5 = User.objects.get(pk=5)
u6 = User.objects.get(pk=6)
u7 = User.objects.get(pk=7)
u8 = User.objects.get(pk=8)
u9 = User.objects.get(pk=9)
u10 = User.objects.get(pk=10)
# 多对多关系数据更新:
# 例一:将ug1用户组关联u1~u3这个三个用户。
 ug1.user_set.add(u1,u2,u3)    # 利用user_set方法
 数据库表展示:
用户与用户组关联关系表
# 反之例二:将u4这个用户,关联到ug2,ug3,ug4这三个用户组中。
u4.groups.add(ug2,ug3,ug4)   # 利用groups这个类属性
数据库表展示:
用户与用户组关联关系表
# 例三:移除关联对象的关联关系
# 将用户id 4的用户从用户组4中移除
ug4.user_set.remove(u4)    # 从ug4角度移除
u4.groups.remove(ug4)    # 从u4角度移除
# 两种方式效果一样
# 数据库展示:
关联关系移除
4、问题解答:多对多关联关系查询
 # 例:查找用户组ug1中,关联的所有用户组
ug1 = UserGroup.objects.get(pk=1)
users = ug1.user_set.all()
lu = []
for u in users:
    lu.append(u.user)
return HttpResponse(lu) 
用户组ug1中的用户

数据库确认:


用户组ug1中的用户
5、问题解答:多级关联关系查询
建立用户组,主机组,主机表关联关系。
h1 = Host.objects.get(pk=1)
h2 = Host.objects.get(pk=2)
h3 = Host.objects.get(pk=3)
h4 = Host.objects.get(pk=4)
h5 = Host.objects.get(pk=5)
h6 = Host.objects.get(pk=6)
h7 = Host.objects.get(pk=7)
h8 = Host.objects.get(pk=8)
hg1 = HostGroup.objects.get(pk=1)
hg2 = HostGroup.objects.get(pk=2)
ug1 = UserGroup.objects.get(pk=1)
ug1.hostgroups.add(hg1,hg2)
hg1.hosts.add(h1,h2,h3,h4)
hg2.hosts.add(h5,h6,h7,h8)
return HttpResponse("hehe")
# 主机h1~h4关联到hg1中,h5~h8关联到hg2中。
# 用户组ug1 关联hg1与hg2两个主机组

数据库展示


关联关系展示
例一:查询role id 为1 的所有用户的,所有用户组的,所有主机组的,所有主机。也就是从role表,查到host表。

    hostset = Host.objects.filter(hostgroup__usergroup__user__role=1)
    host = []
    for i in hostset:
        host.append(i.hostname)
        host.append('\n')
    return HttpResponse(host)

查询结果:


查询结果

role id 为1的用户有admin1,admin2,admin3,所属的组是usergroup1,关联的主机组有hostgroup1,hostgroup2,其中hostgroup1中有主机hostname1,2,3,4 另外hostgroup2中有主机hostname5,6,7,8,所以查询结果是正确。

 例二:查询host id 为1 的主机,所属的关联用户,也就是从host表,查到user表。
users = User.objects.filter(groups__hostgroups__hosts=1)
user = []
for i in users:
    user.append(i.user)
    user.append('\n')
return HttpResponse(user)
# 查询结果:
查询结果

# 以上两例子是从不同方向使用关联对象查询,注意:user.groups与usergroup.user_set方法的使用。

总结:

1、django中模型通过模型管理器objects(默认,可以重写),操作数据库。
2、模型使得数据库操作对象抽象为python语言的类对象,并且将一对多关系与多对多关系,抽象成为两个对象之间的关联关系。
3、利用模型封装好的user.groups与usergroup.user_set方法,来实现多对多关系的操作,具体操作方法有(add(),remove(),create(),clear())
4、操作关联对象关系的深度是无限制的,只要两个对象之间至少存在一条关联关系链即可,相互查询。

自己提问自己,自己解答问题。

参考官方文档:
https://docs.djangoproject.com/en/1.11/
https://docs.djangoproject.com/en/1.11/ref/models/instances/
https://docs.djangoproject.com/en/1.11/ref/models/relations/

相关文章

  • 一个模糊的问题,梳理清楚

    django模型中一对多与多对多关系梳理,三天时间慢慢梳理完。 一对多关系即是数据库中外键约束。多对多关系既是数据...

  • 清楚与模糊

    透过车窗,重新审视自己,在欲望恒生,越来越浮躁的社会,才发现自己真的不了解自己,当初是为了梦想,而现在是为了工作...

  • 清楚又模糊

    走出去看见了眼前的一切,可繁华是怎么构造起来的。 需要辛勤的劳动,由汗水换来的。 有时好像又看不见了,走过去就没有...

  • 不管完美与否,先干起来才会知道真相

    写作就是自己梳理问题的一个过程,梳理清楚了,才能解决掉问题。 写作能赚到钱更好,目前赚不到钱不要放弃写作,它让你学...

  • 又模糊到清楚和由清楚到模糊

    由模糊到清楚和由清楚到模糊 在不知道保护眼睛重要的时刻,不注意用眼卫生,造成了视力下降的后果,戴眼镜成了终...

  • 清楚和模糊

    我很喜欢那些有些模糊的照片,做作中显得自然。而且我觉得很好看。哈哈哈~ 2018年我有很多想做事情,九月的任贤齐剧...

  • 时而清楚时而模糊

    新课标颁布后,里面有很多有“新鲜感”的词,这些有“新鲜感”的词总是会在一个时间内让我们“走火入魔”。比如学习任务群...

  • 开发团队流程如何来优化?

    问题1,PM对于需求梳理清楚,测试同学给予保障。 针对第一个问题不是前端工程师和设计师的问题,是PM问题,PM在前...

  • 中国式洗脑五重奏,永不停止的催眠流水线(上)

    这篇文章是过年梳理了一个月的逻辑,终于把洗脑这个模糊的概念里,最关键的逻辑能够解释清楚。 催眠很神秘,洗脑又神秘又...

  • 运营之光-学习笔记

    运营问题分析逻辑: 1、界定清楚我想要的目标和结果; 2、梳理清楚,这个问题从起始到结束的全流程是怎样的,会经历那...

网友评论

      本文标题:一个模糊的问题,梳理清楚

      本文链接:https://www.haomeiwen.com/subject/ffxfdxtx.html