美文网首页
多对多关系的数据库操作

多对多关系的数据库操作

作者: LittleJessy | 来源:发表于2018-11-20 11:44 被阅读0次

    以权限管理模块中角色和权限、用户和角色均为多对多关系,一个角色可以匹配多个权限,一个用户可以有多个角色。
    角色表中设置:
    permissions = models.ManyToManyField("Permission")
    用户表中设置:
    roles = models.ManyToManyField(to='Role',verbose_name='角色')

    具体model.py如下:

    # _*_ encoding:utf-8 _*_
    from django.db import models
    from django.contrib.auth.models import AbstractUser
    
    class Menu(models.Model):
        """
        菜单
        """
        title = models.CharField(max_length=32, unique=True,verbose_name=u'菜单',default='')
        icon = models.CharField(max_length=10,verbose_name=u'菜单图标',null=True, blank=True,default='')
        parent = models.ForeignKey("Menu", null=True, blank=True,on_delete=models.CASCADE,default='')
        # 定义菜单间的自引用关系
        # 权限url 在 菜单下;菜单可以有父级菜单;还要支持用户创建菜单,因此需要定义parent字段(parent_id)
        # blank=True 意味着在后台管理中填写可以为空,根菜单没有父级菜单
    
        def __str__(self):
            # 显示层级菜单
            title_list = [self.title]
            p = self.parent
            while p:
                title_list.insert(0, p.title)
                p = p.parent
            return '-'.join(title_list)
    
        class Meta:
            verbose_name = u"菜单"
            verbose_name_plural = verbose_name
    
    
    class Permission(models.Model):
        """
        权限
        """
        title = models.CharField(max_length=32, unique=True,verbose_name = u"权限",default='')
        url = models.CharField(max_length=128, unique=True,default='')
        icon = models.CharField(max_length=10, verbose_name=u'权限图标', null=True, blank=True,default='')
        menu = models.ForeignKey("Menu", null=True, blank=True,on_delete=models.CASCADE)
    
        def __str__(self):
            # 显示带菜单前缀的权限
            return '{menu}---{permission}'.format(menu=self.menu, permission=self.title)
    
        class Meta:
            verbose_name = u"权限"
            verbose_name_plural = verbose_name
    
    
    class Role(models.Model):
        """
        角色:绑定权限
        """
        title = models.CharField(max_length=32, unique=True,verbose_name = u"角色")
    
        permissions = models.ManyToManyField("Permission")
        # 定义角色和权限的多对多关系
    
        def __str__(self):
            return self.title
    
        class Meta:
            verbose_name = u"角色"
            verbose_name_plural = verbose_name
    
    
    class UserInfo(models.Model):
        """
        用户:划分角色
        """
        username = models.CharField(max_length=32,verbose_name=u"用户名",default='')
        password = models.CharField(max_length=8,verbose_name=u"密码",default='123456')
        real_name = models.CharField(max_length=50, verbose_name=u"真实姓名", default="")
        mobile = models.CharField(max_length=11, null=True, blank=True, verbose_name=u"手机号",default='')
        roles = models.ManyToManyField(to='Role',verbose_name='角色')
    
        class Meta:
            verbose_name = u"用户"
            verbose_name_plural = verbose_name
    
        def __str__(self):
            return self.username
    
    

    数据库中会根据多对多关系自动生成关联表:


    image.png

    此时对用户和角色的一些操作不仅涉及本身pemission、role、userinfo三张表,对于关联表也要进行一定的操作。
    下面view.py中以角色和权限的增删改查为例:

    # 增加角色
    def addrole(request):
        if request.method == 'POST':
            title = request.POST.get("title")
            permissions_id = request.POST.getlist("permissions")
            isRepeat = len(Role.objects.filter(title=title).values())
            # 不重复则新增数据
            if isRepeat == 0:
                obj = Role.objects.create(title=title)
                obj.permissions.add(*permissions_id) #关系表中增加该角色的权限
    
            menu_list = Menu.objects.all()
            user_list = UserInfo.objects.all()
            role_list = Role.objects.all()
            return render(request, "rbac/permissionToUser.html",{'role_list': role_list,"menu_list": menu_list,"user_list":user_list, "isRepeat": isRepeat})
    
    # 角色权限修改
    def editrole(request):
        if request.method == 'POST':
            role_id = request.POST.get("id")
            permissions_id = request.POST.getlist("permissions") #获取新的权限列表
    
            obj = Role.objects.get(id=role_id)  #获取角色对象
            obj.permissions.clear()  #将该角色之前的权限清空
            obj.permissions.add(*permissions_id) #重新为该角色添加权限
    
            return HttpResponseRedirect('/rbac/permissions/')
    # 角色删除
    def deleterole(request):
        if request.method == 'POST':
            role_id = request.POST.get("id")
            role_obj = Role.objects.get(id=role_id)
    
            if len(role_obj.userinfo_set.all()):
                NotDeletRole = 1
                return HttpResponse(json.dumps({
                    "NotDeletRole": NotDeletRole
                }))
            else:
                obj = Role.objects.get(id=role_id)  #获取角色对象
                obj.permissions.clear()  #该角色的权限清空
                Role.objects.filter(id=role_id).delete()  #然后删除该角色
                NotDeletRole = 0
    
                return HttpResponse(json.dumps({
                    "NotDeletRole": NotDeletRole
                }))
    

    相关文章

      网友评论

          本文标题:多对多关系的数据库操作

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