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

news2024/11/16 3:29:09

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 权限控制

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一个简单的Web程序(详解创建一个Flask项目后自带的一个简单的Web程序)

程序代码截图如下&#xff1a; 1.应用初始化 在创建 Flask 程序时&#xff0c;通常需要先创建一个应用实例进行应用初始化。 from flask import Flask # 应用的初始化 app Flask(__name__) 上述代码中&#xff0c;使用 Flask 类创建了一个应用实例 app。 __name__ 参数用…

RocketMQ常见面试题及答案梳理

1、RocketMQ有什么作用&#xff1f; 异步:数据的产生方不需要关心谁来使用数据&#xff0c;只需要将数据发送到broker,后续需要管消费流程&#xff0c;Rocket也有保证消息可靠性的方案消峰&#xff1a;正常业务系统当流量激增时&#xff0c;有可能会将系统压垮&#xff0c;有了…

【论文阅读】ControlNet、文章作者 github 上的 discussions

文章目录 IntroductionMethodControlNetControlNet for Text-to-Image DiffusionTrainingInference Experiments消融实验定量分析 在作者 github 上的一些讨论消融实验更进一步的探索Precomputed ControlNet 加快模型推理迁移控制能力到其他 SD1.X 模型上其他 Introduction 提…

深入探究Python的filter()函数

Python是一种多用途的编程语言&#xff0c;提供了许多内置函数&#xff0c;以简化和增强代码的可读性。其中一个强大的函数就是​filter()​。在本文中&#xff0c;我们将深入研究​filter()​函数&#xff0c;探讨其用途、语法和实际示例&#xff0c;以了解如何在Python编程中…

3.C语言——函数

函数 1.什么是函数2.函数的分类1.库函数2.自定义函数 3.函数的参数1.实际参数&#xff08;实参&#xff09;2.形式参数&#xff08;形参&#xff09; 4.函数的声明1.同一个文件的函数声明2.多文件的函数声明 5.函数的调用6.函数的嵌套调用和链式访问1.嵌套调用2.链式访问 7.函数…

CSS中隐藏页面元素的几种方式和区别

前言、 在平常的样式排版中&#xff0c;我们经常遇到将某个模块隐藏的场景&#xff0c;通过css隐藏的元素方法有很多种&#xff0c;它们看起来实现的效果是一致的&#xff0c;但实际上每一种方法都有一丝轻微的不同&#xff0c;这些不同决定了在一些特定场合下使用哪一种方法。…

POKT Network (POKT) :进军百亿美元市场规模的人工智能推理市场

POKT Network&#xff08;又称 Pocket Network&#xff09;是一个去中心化的物理基础设施网络&#xff08;DePIN&#xff09;&#xff0c;它能够协调并激励对任何开放数据源的访问&#xff0c;最初专注于向应用程序和服务提供商提供区块链数据。 自 2020 年主网上线以来&#x…

图像分割实战-系列教程15:deeplabV3+ VOC分割实战3-------网络结构1

&#x1f341;&#x1f341;&#x1f341;图像分割实战-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 本项目的网络结构在network文件夹中&#xff0c;主要在modeling.py和_deeplab.py中&#xff1a; mo…

利用浏览器开发者工具进行网页性能优化

目录 学习目标&#xff1a; 学习内容&#xff1a; 学习时间&#xff1a; 学习产出&#xff1a; 网页性能优化的基本概念和指标&#xff1a; 浏览器开发者工具的基本功能和使用方法&#xff1a; 使用网络面板进行网页加载性能分析&#xff1a; 使用性能面板进行网页渲染性能分析…

最长上升子序列模型(LIS)

最长上升子序列模型就像它的名字一样&#xff0c;用来从区间中找出最长上升的子序列。它主要用来处理区间中的挑选问题&#xff0c;可以处理上升序列也可以处理下降序列&#xff0c;原序列本身的顺序并不重要。 模型 895. 最长上升子序列&#xff08;活动 - AcWing&#xff0…

机器学习:何为监督学习和无监督学习

目录 一、监督学习 &#xff08;一&#xff09;回归 &#xff08;二&#xff09;分类 二、无监督学习 聚类 一、监督学习 介绍&#xff1a;监督学习是指学习输入到输出&#xff08;x->y&#xff09;映射的机器学习算法&#xff0c;监督即理解为&#xff1a;已知正确答案…

【算法】斐波那契数列 [递推,矩阵快速幂]

方法一. 递推 class Solution { public:int fib(int n) {int MOD 1e9 7;if (n < 2) return n;int p 0, q 0, r 1;for (int i 2; i < n; i) {p q;q r;r (p q) % MOD;}return r;} }; 方法二&#xff1a;矩阵快速幂 class Solution { public:const int MOD 1e…

AI 编程的机会和未来:从 Copilot 到 Code Agent

大模型的快速发展带来了 AI 应用的井喷。统计 GPT 使用情况&#xff0c;编程远超其他成为落地最快、使用率最高的场景。如今&#xff0c;大量程序员已经习惯了在 AI 辅助下进行编程。数据显示&#xff0c;GitHub Copilot 将程序员工作效率提升了 55%&#xff0c;一些实验中 AI …

《Python数据分析技术栈》第01章 03 Python基础(Python Basics)

03 Python基础&#xff08;Python Basics&#xff09; 《Python数据分析技术栈》第01章 03 Python基础&#xff08;Python Basics&#xff09; In this section, we get familiar with the syntax of Python, commenting, conditional statements, loops, and functions. 在…

dns正反解析配置

1.配置正向解析baidu.com 1、下载bind包 [rootlocalhost ~]# yum install bind -y 2、对配置文件修改 [rootlocalhost ~]# vim /etc/named.conf 3、对数据文件修改 [rootlocalhost ~]# vim /var/named/baidu 4、重启服务 [rootlocalhost ~]# systemctl restart named.service 5…

2.【C语言】(函数指针||sizeof||笔试题)

0x01.函数指针 void test(const char* str) {printf("%s\n", str); }int main() {void (*pf)(const char*) test;//pf是函数指针变量void (*pfarr[10])(const char*);//pfarr是存放函数指针的数组void (*(*p)[10])(const char*) &pfarr;//p是指向函数指针数组…

ROS学习笔记8——实现ROS通信时的常用命令

机器人系统中启动的节点少则几个&#xff0c;多则十几个、几十个&#xff0c;不同的节点名称各异&#xff0c;通信时使用话题、服务、消息、参数等等都各不相同&#xff0c;一个显而易见的问题是: 当需要自定义节点和其他某个已经存在的节点通信时&#xff0c;如何获取对方的话…

【Docker】Nacos的单机部署及集群部署

一、Nacos的介绍 Nacos是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。 动态服务发现&#xff1a;Nacos支持DNS与RPC服务发现&#xff0c;提供原生SDK、OpenAPI等多种服务注册方式和DNS、HTTP与API等多种服务发现方式。服务健康监测&#xff1a;Nacos提供…

VUE组件--动态组件、组件保持存活、异步组件

动态组件 有些场景可能会需要在多个组件之间进行来回切换&#xff0c;在vue中则使用<component :is"..."> 来实现组件间的来回切换 // App.vue <template><component :is"tabComponent"></component><button click"change…

基于Springboot+vue图书管理系统(前后端分离)

该项目完全免费 项目技术栈前后端分离&#xff1a; 后端&#xff1a;Springboot Mybatis-plus 前端&#xff1a;Vue ElementUI 数据库&#xff1a; MySQL 项目功能描述 管理员&#xff1a; 登录、个人信息、修改密码、管理后台管理系统所有数据 首页统计&#xff1a;…