Day1 表结构/权限/路径导航/登录

day13 订单管理项目开发

1.表结构设计

1.1 abstract类

from django.db import models

class ActiveBaseModel(models.Model):
active = models.SmallIntegerField(verbose_name="状态", default=1, choices=((1, "激活"), (0, "删除"),))

class Meta:
abstract = True

class Administrator(ActiveBaseModel):
""" 管理员表 """
username = models.CharField(verbose_name="用户名", max_length=32, db_index=True)
password = models.CharField(verbose_name="密码", max_length=64)
mobile = models.CharField(verbose_name="手机号", max_length=11, db_index=True)
create_date = models.DateTimeField(verbose_name="创建日期", auto_now_add=True)

1.2 自增和主键

默认:DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

class Administrator(models.Model):
""" 管理员表 """
uid = models.AutoField(verbose_name="自增", primary_key=True)

username = models.CharField(verbose_name="用户名", max_length=32, db_index=True)
password = models.CharField(verbose_name="密码", max_length=64)
mobile = models.CharField(verbose_name="手机号", max_length=11, db_index=True)
create_date = models.DateTimeField(verbose_name="创建日期", auto_now_add=True)

1.3 逻辑删除

class Administrator(ActiveBaseModel):
""" 管理员表 """
username = models.CharField(verbose_name="用户名", max_length=32, db_index=True)
password = models.CharField(verbose_name="密码", max_length=64)
mobile = models.CharField(verbose_name="手机号", max_length=11, db_index=True)
create_date = models.DateTimeField(verbose_name="创建日期", auto_now_add=True)
active = models.SmallIntegerField(verbose_name="状态", default=1, choices=((1, "激活"), (0, "删除"),))

1.4 数据库连接

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'day06', # 数据库名字
'USER': 'root',
'PASSWORD': 'root123',
'HOST': '127.0.0.1',
'PORT': 3307,
}
}

1.5 表结构参考

点击查看代码
    from django.db import models
    
    
    class ActiveBaseModel(models.Model):
        active = models.SmallIntegerField(verbose_name="状态", default=1, choices=((1, "激活"), (0, "删除"),))
    
        class Meta:
            abstract = True
    
    
    class Administrator(ActiveBaseModel):
        """ 管理员表 """
        username = models.CharField(verbose_name="用户名", max_length=32, db_index=True)
        password = models.CharField(verbose_name="密码", max_length=64)
        mobile = models.CharField(verbose_name="手机号", max_length=11, db_index=True)
        create_date = models.DateTimeField(verbose_name="创建日期", auto_now_add=True)
    
    
    class Level(ActiveBaseModel):
        """ 级别表 """
        title = models.CharField(verbose_name="标题", max_length=32)
        percent = models.IntegerField(verbose_name="折扣", help_text="填入0-100整数表示百分比,例如:90,表示90%")
    
        def __str__(self):
            return self.title
    
    
    class Customer(ActiveBaseModel):
        """ 客户表 """
        username = models.CharField(verbose_name="用户名", max_length=32, db_index=True)
        password = models.CharField(verbose_name="密码", max_length=64)
        mobile = models.CharField(verbose_name="手机号", max_length=11, db_index=True)
        # mobile = models.CharField(verbose_name="手机号", max_length=11, db_index=True, validators=[RegexValidator(r'^\d{11}$', '手机号格式错误'), ], )
        balance = models.DecimalField(verbose_name="账户余额", default=0, max_digits=10, decimal_places=2)
        level = models.ForeignKey(verbose_name="级别", to="Level", on_delete=models.CASCADE)
        # level = models.ForeignKey(verbose_name="级别", to="Level", on_delete=models.CASCADE, limit_choices_to={'active': 1})
        create_date = models.DateTimeField(verbose_name="创建日期", auto_now_add=True)
        creator = models.ForeignKey(verbose_name="创建者", to="Administrator", on_delete=models.CASCADE)
    
    
    class PricePolicy(models.Model):
        """ 价格策略(原价,后续可以根据用级别不同做不同折扣)
        1  1000 10
        2  2000 18
        """
        count = models.IntegerField(verbose_name="数量")
        price = models.DecimalField(verbose_name="价格", default=0, max_digits=10, decimal_places=2)
    
    
    class Order(ActiveBaseModel):
        """ 订单表 """
        status_choices = (
            (1, "待执行"),
            (2, "正在执行"),
            (3, "已完成"),
            (4, "失败"),
            (5, "已撤单"),
        )
        status = models.SmallIntegerField(verbose_name="状态", choices=status_choices, default=1)
    
        # 202211022123123123
        oid = models.CharField(verbose_name="订单号", max_length=64, unique=True)
        url = models.URLField(verbose_name="视频地址", db_index=True)
        count = models.IntegerField(verbose_name="数量")
    
        price = models.DecimalField(verbose_name="价格", default=0, max_digits=10, decimal_places=2)
        real_price = models.DecimalField(verbose_name="实际价格", default=0, max_digits=10, decimal_places=2)
    
        old_view_count = models.CharField(verbose_name="原播放量", max_length=32, default="0")
    
        create_datetime = models.DateTimeField(verbose_name="创建时间", auto_now_add=True)
        customer = models.ForeignKey(verbose_name="客户", to="Customer", on_delete=models.CASCADE)
        memo = models.TextField(verbose_name="备注", null=True, blank=True)
    
    
    class TransactionRecord(ActiveBaseModel):
        """ 交易记录 """
        charge_type_class_mapping = {
            1: "success",
            2: "danger",
            3: "default",
            4: "info",
            5: "primary",
        }
        charge_type_choices = ((1, "充值"), (2, "扣款"), (3, "创建订单"), (4, "删除订单"), (5, "撤单"),)
        charge_type = models.SmallIntegerField(verbose_name="类型", choices=charge_type_choices)
    
        customer = models.ForeignKey(verbose_name="客户", to="Customer", on_delete=models.CASCADE)
        amount = models.DecimalField(verbose_name="金额", default=0, max_digits=10, decimal_places=2)
    
        creator = models.ForeignKey(verbose_name="管理员", to="Administrator", on_delete=models.CASCADE, null=True, blank=True)
    
        order_oid = models.CharField(verbose_name="订单号", max_length=64, null=True, blank=True, db_index=True)
        create_datetime = models.DateTimeField(verbose_name="交易时间", auto_now_add=True)
        memo = models.TextField(verbose_name="备注", null=True, blank=True)

2.用户认证相关

两种登录方式:

  • 用户名 + 密码 登录
  • 手机号 + 短信 登录

当用户登录成功后,将用户信息保存至Session【数据库 or 缓存】,不同类型用户登录 显示不同的菜单项。

2.1 发送短信

  • 腾讯云短信
  • 云通信短信
  • 互亿无线106短信

2.2 缓存和Session

pip install django-redis

CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {"max_connections": 100}
"PASSWORD": "qwe123",
# 'MAX_ENTRIES': 300, # 最大缓存个数(默认300)
# 'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)
}
}
}

############
# SESSIONS #
############
# Session存储在哪里?
# SESSION_ENGINE = "django.contrib.sessions.backends.db"

如果存储到文件中,文件的路径。

SESSION_ENGINE = "django.contrib.sessions.backends.file"

SESSION_FILE_PATH = None

存储到缓存

SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"

此时也可以手动操作,将数据保存到redis中:

from django_redis import get_redis_connection

conn = get_redis_connection("default")
conn.set("xx","123123")
conn.get("xx")

2.3 动态菜单

不同角色的用户登录,看到不同的菜单。

  • 页面写死 HTML模板


    {% if 角色 "管理员"%}
    用户管理
    级别管理
    级别管理
    ...
    {% else %}
    xxx管理
    级别管理
    {% endif %}

  • 将菜单放在配置文件中 (选择

    settings.py

    ADMIN = [
    {"title":"用户管理", "url":"...." },
    {"title":"用户管理", "url":"...." },
    {"title":"用户管理", "url":"...." },
    {"title":"用户管理", "url":"...." },
    ]

    USER = [
    {"title":"用户管理", "url":"...." },
    {"title":"用户管理", "url":"...." },
    {"title":"用户管理", "url":"...." },
    {"title":"用户管理", "url":"...." },
    ]


    {% if 角色 "管理员"%}
    {% for item in ADMIN%}
    {{item.title}}
    {%emdfor%}
    {% else %}
    {% for item in USER%}
    {{item.title}}
    {%emdfor%}
    {% endif %}

如果想要显示2级菜单:

ADMIN = [
{"title":"用户管理", "url":"...." },
{"title":"用户管理", "url":"...." },
{"title":"用户管理", "url":"...." },
{"title":"用户管理", "url":"...." },
]

ADMIN = [
{
"title":"用户管理",
"children":[
{"title":"级别列表","url":"....", "name":"level_list",}
{"title":"级别列表","url":"...."}
{"title":"级别列表","url":"...."}
]
},
{
"title":"订单管理",
"children":[
{"title":"订单列表","url":"...."}
{"title":"订单列表","url":"...."}
{"title":"订单列表","url":"...."}
]
},
]

  • 菜单选中和展开

    1.获取当前用户请求的 URL pricepolicy/list/ 或 url对应的name
    2. pricepolicy/list/ 配置 ADMIN中的URL ->默认选中

  • 路径导航的问题

    1.获取当前用户请求的 URL pricepolicy/list/ 或 url对应的name
    2.获取上级,展示导航信息
    3.设置菜单与下级关系

2.4 权限控制

权限的判断时,要考虑:正常的点击、非法输入。

v1 = [11,22,33,44]
if 33 in v1:
pass

v1 = {11,22,33,44}
if 33 in v1:
pass

v1 = {
11:123123,
22:123123
33:123123
44:123123
}

if 33 in v1:
pass

  • 文件settings.py的方式(编写)

    admin_permisions = {
    "level_list":{...},
    "level_edit":{..., 'parent':'level_list'},
    "level_add":{... 'parent':'level_list'},
    "level_delete":{..'parent':'level_list'.},

    "user_list":{...},
    "user_edit":{...},
    "user_add":{...},
    "user_delete":{...},
    }

    user_permisions = {
    ...
    }

    admin访问某个URL + 路由信息(name、namespace),获取当前的URL /level/edit/4/ -> 是否存在URL

    在中间件中根据URL中的name进行权限的校验。

2.5 local_settings.py

线上部署和本地settings.py想要隔离,可以使用local_settings.py来进行配置。

try:
from .local_settings import *
except ImportError:
pass

注意:在做版本控制提交代码时,在.gitignore中设置上 local_settings.py

2.6 用户名登录

...

2.7 短信登录

...

2.8 动态菜单

...

posted @ 2023-09-03 13:11  khalil12138  阅读(44)  评论(0)    收藏  举报