一.項目文件路徑
1.在項目路徑下新建python_package,取名apps,然後新建app名rbacs
<code>startapp rbacs/<code>
2.model.py新建要使用的model層(也就是我們經常說的數據庫結構)
<code>from datetime import datetime from django.contrib.auth.models import AbstractUser from django.db import models from apps.utils.common import Utils class Menu(models.Model): """ 菜單 """ menu_code = models.CharField(max_length=50, unique=True, verbose_name="菜單編號") menu_name = models.CharField(max_length=100, verbose_name="菜單名稱") table_name = models.CharField(max_length=50, verbose_name="表名", default='', blank=True) desc = models.CharField(max_length=100, verbose_name="描述", default='', blank=True) icon = models.CharField(max_length=100, default='', blank=True, verbose_name="圖標") sort = models.IntegerField(default=0, verbose_name="排序") parent = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, verbose_name="上級菜單") is_last = models.CharField(max_length=10, choices=(("T", "一級"), ("M", "二級"), ("L", "三級")), verbose_name="層級", default="T") is_out = models.BooleanField(default=False, verbose_name="跨域否") add_time = models.DateTimeField(auto_now_add=True, verbose_name="添加時間") upd_time = models.DateTimeField(default=datetime.now, verbose_name="更新時間") class Meta: verbose_name = "菜單表" verbose_name_plural = verbose_name def __str__(self): name_list = [self.menu_name] p = self.parent while p: name_list.insert(0, p.menu_name) p = p.parent return "-".join(name_list) class Accession(models.Model): """ 權限(URL) """ url = models.CharField(max_length=500, verbose_name="鏈接(url)", default='', blank=True) desc = models.CharField(max_length=100, verbose_name="名稱", default='', blank=True) menu = models.ForeignKey(Menu, on_delete=models.CASCADE, verbose_name="菜單") is_menu = models.BooleanField(default=False, verbose_name="菜單顯示") add_time = models.DateTimeField(auto_now_add=True, verbose_name="添加時間") upd_time = models.DateTimeField(default=datetime.now, verbose_name="更新時間") class Meta: verbose_name = "權限表" verbose_name_plural = verbose_name unique_together = ('url', 'menu') def __str__(self): return '{menu}:{url}'.format(menu=self.menu.menu_name, url=self.url) class Action(models.Model): """ 操作碼 """ action_code = models.CharField(max_length=50, verbose_name="操作編號") action_name = models.CharField(max_length=100, verbose_name="操作名稱") accession = models.ForeignKey(Accession, on_delete=models.CASCADE, verbose_name="權限菜單", null=True, blank=True) desc = models.TextField(verbose_name="描述", default='', blank=True) add_time = models.DateTimeField(auto_now_add=True, verbose_name="添加時間") upd_time = models.DateTimeField(default=datetime.now, verbose_name="更新時間") class Meta: verbose_name = "操作碼錶" verbose_name_plural = verbose_name unique_together = ('action_code', 'accession') def __str__(self): return '{code}:{name}'.format(code=self.action_code, name=self.action_name) class Role(models.Model): """ 角色 """ role_code = models.CharField(max_length=50, unique=True, verbose_name="角色編號") role_name = models.CharField(max_length=100, verbose_name="角色名稱") desc = models.TextField(verbose_name="描述", default='', blank=True) # 定義角色和權限(URL)的多對多關係 accessions = models.ManyToManyField(Accession, verbose_name="權限", related_name="role", blank=True) add_time = models.DateTimeField(auto_now_add=True, verbose_name="添加時間") upd_time = models.DateTimeField(default=datetime.now, verbose_name="更新時間") class Meta: verbose_name = "角色表" verbose_name_plural = verbose_name def __str__(self): return '{code}:{name}'.format(code=self.role_code, name=self.role_name) class Role2Accession2Action(models.Model): """ 角色權限操作碼 """ role = models.ForeignKey(Role, on_delete=models.CASCADE, verbose_name="角色") accession = models.ForeignKey(Accession, on_delete=models.CASCADE, verbose_name="權限") action = models.ForeignKey(Action, on_delete=models.CASCADE, verbose_name="操作碼") add_time = models.DateTimeField(auto_now_add=True, verbose_name="添加時間") upd_time = models.DateTimeField(default=datetime.now, verbose_name="更新時間") class Meta: verbose_name = "角色權限操作碼錶" verbose_name_plural = verbose_name unique_together = ('role', 'accession', 'action') def __str__(self): return '{role}:{accession}:{action}'.format(role=self.role.role_name, accession=self.accession.url, action=self.action.action_name) class UserProfile(AbstractUser): """ 自定義用戶 """ nick_name = models.CharField(max_length=50, verbose_name="暱稱", default="小親親", blank=True) birthday = models.DateField(verbose_name="生日", null=True, blank=True) gender = models.CharField(max_length=2, verbose_name="性別", choices=(("F", "女"), ("M", "男"))) address = models.CharField(max_length=100, verbose_name="地址", default='', blank=True) mobile = models.CharField(max_length=11, verbose_name="手機號碼", default='', blank=True) image = models.ImageField(verbose_name="用戶頭像", upload_to="head_image/%Y/%m", default="head_image/default.png", help_text="114x113") employee = models.OneToOneField('bases.Employee', on_delete=models.CASCADE, related_name="user_employee", blank=True, null=True) plants = models.ManyToManyField('bases.plant', verbose_name="所屬工廠", related_name="user_plant", blank=True) add_time = models.DateTimeField(auto_now_add=True, verbose_name="添加時間") upd_time = models.DateTimeField(default=datetime.now, verbose_name="更新時間") class Meta: verbose_name = "用戶表" verbose_name_plural = verbose_name def __str__(self): if self.nick_name: return '{name}:{nick_name}'.format(name=self.username, nick_name=self.nick_name) return self.username def full_name(self): if self.last_name and self.first_name: return '{last_name}{first_name}'.format(last_name=self.last_name, first_name=self.first_name) return None full_name.short_description = "姓名" 3.model 層知識點介紹 3.1新建完app 後一定要在setting 文件下添加app,否則無法做makemigrations 和migrate。 INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'apps.rbacs.apps.RbacsConfig', ] 3.2 一對多(多對一) 顧名思義,一對多,即是一條數據對多條數據。如上述model 中的 Menu 和Accession就是一對多的關係,理解成數據庫結構就是Menu 是Accession的外鍵 menu = models.ForeignKey(Menu, on_delete=models.CASCADE, verbose_name="菜單") CASCADE 的意思就是Menu 數據刪除了,那麼Accession 的數據也同時被刪除 DO_NOTHING 就是刪除了menu 數據,accession 的數據不受影響 限於篇幅限制,下篇繼續。 /<code>