2024--Django平台开发-订单项目管理用户认证+动态菜单+权限控制(十三)

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模板

    <html>
        {% if 角色 "管理员"%}
        	<a href="/xxx/x">用户管理</a>
        	<a href="/xxx/x">级别管理</a>
        	<a href="/xxx/x">级别管理</a>
        	...
        {% else %}
        	<a href="/xxx/x">xxx管理</a>
        	<a href="/xxx/x">级别管理</a>
        {% endif %}
    </html>
    
  • 将菜单放在配置文件中 (选择

    # settings.py
    
    ADMIN = [
        {"title":"用户管理", "url":"...." },
        {"title":"用户管理", "url":"...." },
        {"title":"用户管理", "url":"...." },
        {"title":"用户管理", "url":"...." },
    ]
    
    USER = [
        {"title":"用户管理", "url":"...." },
        {"title":"用户管理", "url":"...." },
        {"title":"用户管理", "url":"...." },
        {"title":"用户管理", "url":"...." },
    ]
    
    <html>
        {% if 角色 "管理员"%}
        	{% for item in ADMIN%}
    		    <a href="{{item.url}}">{{item.title}}</a>
    	    {%emdfor%}
        {% else %}
        	{% for item in USER%}
    		    <a href="{{item.url}}">{{item.title}}</a>
    	    {%emdfor%}
        {% endif %}
    </html>
    

如果想要显示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 动态菜单

2.9 权限控制

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/334504.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MyBatis 使用报错: Can‘t generate mapping method with primitive return type

文章目录 前言问题原因解决方案个人简介 前言 今天在新项目中使用 MyBatis 报如下错误&#xff1a;Cant generate mapping method with primitive return type 问题原因 发现是 Mapper 注解引入错误&#xff0c;错误引入 org.mapstruct.Mapper, 实际应该引入 org.apache.ibat…

CodeGeex全能的智能编程助手

大家好我是在看&#xff0c;记录普通人学习探索AI之路。 一、介绍 CodeGeeX&#xff0c;一款由清华大学知识工程实验室研发的基于大型模型的全能智能编程辅助工具&#xff0c;能够实现包括代码生成与补全、自动注释添加、代码翻译以及智能问答等多种功能。经过对包含前后端工…

【代码随想录08】232. 用栈实现队列 225. 用队列实现栈

目录 232. 用栈实现队列题目描述参考代码 225. 用队列实现栈题目描述参考代码 232. 用栈实现队列 题目描述 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff1a; 实现 MyQueue 类&#xff1a…

leetcode2312卖木头块

其实不难&#xff0c;主要是你得一眼看出来这个问题缩小规模然后就可以用DP来做了 using ll long long; class Solution { public:long long sellingWood(int m, int n, vector<vector<int>>& prices) {ll f[m10][n10];ll p[m10][n10];memset(p,0,sizeof p)…

JS封装本地缓存的设置,读取,移除,清空方法及使用示例

我封装了一个JS通用的缓存管理对象&#xff0c;可以提供缓存的设置&#xff0c;读取&#xff0c;移除&#xff0c;清空操作&#xff0c;使用也很方便&#xff0c;封装方法的代码在最下方。 Q: 为什么不直接用原生的缓存方法&#xff0c;要封装&#xff1f; A1:原生的缓存管理…

【随机化约束控制 解的概率_2024.01.19】

约束控制 //constraint_mode() constraint c {length inside {[1:32]};} p.c.constraint.mode(0);//0关闭&#xff0c;1打开&#xff0c;默认打开//rand_mode p.length.rand_mode(0);//随机进行关闭 p.length42;//randomiza()with{} assert(c.randmize()with{data<10;});//…

Python中HTTP代理的配置和使用

在Python中&#xff0c;HTTP代理是一种常用的技术&#xff0c;用于控制和修改HTTP请求和响应。通过使用HTTP代理&#xff0c;我们可以更好地控制网络请求的行为&#xff0c;提高安全性、隐私性和效率。下面我们将详细介绍如何在Python中配置和使用HTTP代理。 一、配置HTTP代理…

Linux编写简易shell

思路&#xff1a;​ ​ ​ 所以要写一个shell&#xff0c;需要循环以下过程:​ 获取命令行解析命令行建立一个子进程&#xff08;fork&#xff09;替换子进程&#xff08;execvp&#xff09;父进程等待子进程退出&#xff08;wait&#xff09; 实现代码&#xff1a;​ #inc…

Linux———sort命令总结详解(狠狠爱住)

目录 sort命令&#xff1a; 命令参数及描述&#xff1a; 示例&#xff1a; 使用-b参数&#xff0c;忽略行首空白字符&#xff0c;按照第一列进行排序&#xff1a; -d 选项是 sort 命令中一个非常有用的选项&#xff0c;它可以按照字典顺序进行排序&#xff0c;同时忽略非字…

UI开发布局-HarmonyOS应用UI开发布局

UI页面的构建不用再像Android开发过程中在.xml文件中书写&#xff0c;可直接在页面上使用声明式UI的方式按照布局进行排列&#xff0c;构建应用的页面。 如下代码使用Row、Column构建一个页面布局&#xff0c;在页面布局中添加组件Text、Button&#xff0c;共同构成页面&#…

sd-wan跨境专线ip是固定的吗?

SD-WAN&#xff08;软件定义广域网&#xff09;是一种网络技术&#xff0c;它可以通过集中的管理和控制来提供更好的网络性能和可靠性。跨境专线是指连接不同国家之间的网络连接。 固定IP是指在网络中分配给特定设备的永久性 IP 地址&#xff0c;与动态 IP&#xff08;每次连接…

python tkinter 最简洁的计算器按钮排列

代码如下&#xff0c;只要再加上按键绑定事件函数&#xff0c;计算器既可使用了。 import tkinter as tk from tkinter.ttk import Separator,Buttonif __name__ __main__:Buttons [[%,CE,C,←],[1/x,x,√x,],[7, 8, 9, x],[4, 5, 6, -],[1, 2, 3, ],[, 0, ., ]]root tk.T…

RK3568平台 LT9211转接芯片调试笔记

一.简介 龙讯LT9211是一个高性能转换器&#xff0c;支持MIPI LVDS TTL两两之间转换。 使用此款芯片大部分为MIPI与LVDS进行互相转换。 下图为LT9211的典型应用图&#xff1a; 二.LT9211原理图 三.车载显示器和摄像头系统 四.调试LT9211输出 MIPI数据 &#xff08;1&#xf…

红队打靶练习:NULLBYTE: 1

目录 信息收集 1、arp 2、nmap 3、nikto 4、whatweb 目录探测 1、dirsearch 2、gobuster WEB web信息收集 图片信息收集 hydra爆破 sql注入 闭合 爆库 爆表 爆列 爆字段 hashcat SSH登录 提权 信息收集 1、arp ┌──(root㉿ru)-[~/kali] └─# arp-scan…

Unity-场景

创建场景 创建新的场景后&#xff1a; 文件 -> 生成设置 -> Build中的场景 -> 将项目中需要使用的场景拖进去 SceneTest public class SceneTest : MonoBehaviour {// Start is called before the first frame updatevoid Start(){// 两个类&#xff1a; 场景类、场…

配置zabbix平台对数据库以及主从状态的监控

引言&#xff1a;明人不说暗话&#xff0c;今天分享下配置zabbix平台对数据库以及主从状态的监控 准备好zabbix监控平台&#xff08;zabbix-server端&#xff09;例10.12.153.235 db1客户端&#xff08;zabbix-agent&#xff09;例10.12.153.73 1.安装Zabbix存储库 # rpm -Uv…

策略路由与NQA联动示例

某公司网络使用SwitchA做汇聚层交换机&#xff0c;接入层交换机LSW做用户网关&#xff0c;LSW和SwitchA之间路由可达。汇聚层交换机SwitchA通过两条链路连接到两个核心交换机上&#xff0c;一条是高速链路&#xff0c;网关为10.1.20.1/24&#xff1b;另外一条是低速链路&#x…

算法 动态分析 及Java例题讲解

动态规划 动态规划&#xff08;英语&#xff1a;Dynamic programming&#xff0c;简称 DP&#xff09;&#xff0c;是一种在数学、管理科学、计算机科学、经济学和生物信息学中使用的&#xff0c;通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。动态规划常常适…

「 网络安全常用术语解读 」杀链Kill Chain详解

1. 简介 早在2009年&#xff0c;Lockheed Martin公司就提出了杀链(Kill Chain)理论&#xff0c;现在也称之为攻击者杀链(Attacker Kill Chain)。杀链其实就是攻击者进行网络攻击时所采取的步骤。杀链模型包括7个步骤&#xff1a;1侦察 -> 2武器化 -> 3交付 -> 4利用 …

【Python】PyCharm设置控制台输出的行数限制

在使用PyCharm的时候&#xff0c;如果在控制台输出的信息过多室&#xff0c;控制台仅会保留一部分的输出信息。想要改变这个限制&#xff0c;设置方法如下&#xff1a; 进入到PyCharm的安装目录下&#xff0c;我的是C:\Develop\PyCharm202303\PyCharm 2023.3进入bin找到文件id…