Files
sixGuoDjango/wechat_数据库/用户数据库/小程序登陆用户.py
T
2026-08-21 23:48:29 +08:00

205 lines
9.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""注释"""
from django.db import models
"""
输入 :当前用户实例(self)
输出 :包含所有下级用户的 扁平化列表 (多级结构被展开)
递归逻辑 :
先获取当前用户的直接下级(通过 self.subordinates.all())
对每个下级用户 递归调用自身,继续向下查找
合并所有结果到一个列表中
用户A
├─ 用户B
│ ├─ 用户C
│ └─ 用户D
└─ 用户E
[用户B, 用户C, 用户D, 用户E] # 按深度优先顺序
语法: wei = weiuser.objects.get(unionid="元宝零售")
print( wei.get_all_subordinates( ) )
结果: [<weiuser: weiuser object (oy4Jw6A1T3WkKOOhMxcbQTDSM8rs)>]
"""
defautl_img = (
"https://oss.fujugongxiang.com/six/%E7%A6%8F%E8%81%9A%E8%B4%A1%E7%BF%94%E5%B0%8F%E7%A8%8B%E5%BA%8F/home%E9%A1%B5%E9%9D%A2%E4%B8%BB%E5"
"%9B%BE/%E5%A4%B4%E5%83%8F.png")
from django.utils.translation import gettext_lazy
models_app_name = "django_app"
class weiuser用户角色表choicesStatus(models.TextChoices):
"""商家转账订单状态"""
推广员 = "推广员", gettext_lazy("推广员")
企微员工 = "企微员工", gettext_lazy("企微员工")
无状态 = "无状态", gettext_lazy("无状态")
普通会员 = "普通会员", gettext_lazy("普通会员")
六果科技有限公司 = "六果科技有限公司", gettext_lazy("六果科技有限公司")
群好友 = "群好友", gettext_lazy("群好友")
class weiuser(models.Model):
"""用户基础信息表"""
objects = models.Manager() #
class ChoicesStatus(models.TextChoices):
"""商家转账订单状态"""
推广员 = "推广员", gettext_lazy("推广员")
企微员工 = "企微员工", gettext_lazy("企微员工")
无状态 = "无状态", gettext_lazy("无状态")
unionid = models.CharField(primary_key=True, max_length=120)
user_角色权限 = models.CharField(choices=weiuser用户角色表choicesStatus, default=weiuser用户角色表choicesStatus.普通会员)
user_企微角色权限 = models.CharField(max_length=128, null=True, blank=True, )
mini_openid = models.CharField(max_length=100, db_comment="自身id", null=True, blank=True, unique=True)
wechat_openid = models.CharField(max_length=100, db_comment="服务号自身id", null=True, blank=True, unique=True)
wecom_openid = models.CharField(max_length=100, db_comment="企微自身id", null=True, blank=True, unique=True)
external_userid = models.CharField(max_length=100, db_comment="外部联系人ID", null=True, blank=True, )
uesr_手机号码 = models.CharField(null=True, blank=True, )
user_昵称 = models.CharField(max_length=120, db_comment="用户的昵称", default="匿名用户")
user_头像 = models.CharField(max_length=245, db_comment="用户头像",
default="https://hudie.xiao.band/%E6%9C%AA%E5%91%BD%E5%90%8D.png")
user_用户当前的等级 = models.IntegerField(default=1, ) # 自身的等级
user_省份 = models.CharField(max_length=128, null=True, blank=True, )
user_城市 = models.CharField(max_length=128, null=True, blank=True, )
user_区县 = models.CharField(max_length=128, null=True, blank=True, )
user_街道信息 = models.CharField(max_length=128, null=True, blank=True, )
user_绑定企微usrID账号 = models.CharField(max_length=128, null=True, blank=True, )
user_绑定企微UNIONID = models.CharField(max_length=128, null=True, blank=True, )
user_IP地址 = models.GenericIPAddressField(null=True, blank=True, )
user_手机设备参数 = models.JSONField(null=True, blank=True, )
user_绑定用工关系 = models.CharField(max_length=128, null=True, blank=True, )
codeConfigId = models.TextField(blank=True, null=True, ) # 企微的标签ID
codeQrCode = models.TextField(blank=True, null=True, ) # 企微的二维码
codeRemark = models.TextField(blank=True, null=True, ) # 企微备注的信息
parent = models.ForeignKey(to="self", on_delete=models.SET_NULL, related_name="children", null=True,
blank=True, ) # 模式:保护模式,有数据话是不能删除的;
add_time = models.DateTimeField(null=True, blank=True, db_comment="用户添加好友的时间")
dateAndTime = models.DateTimeField(auto_now_add=True, db_comment="创建时间") # 数据创建时间
updateTime = models.DateTimeField(auto_now=True, db_comment="更新时间") # 更新时间(需要用 save() )
class Meta:
db_table = "weiuser" # 给数据表自定义一个名称;默认的会是在 应用名+类名
app_label = models_app_name
ordering = ["-dateAndTime", "-updateTime"]
def get_all_subordinates(self):
"""递归获取所有下级(包括间接下级)"""
subs = []
for sub in self.children.all():
subs.append(sub)
subs.extend(sub.get_all_subordinates())
return subs
# ↓↓↓ 新增方法:获取所有上级(递归实现)↓↓↓
def get_all_superiors(self):
"""
返回列表格式:[直接上级, 上上级, 上上上级...]
"""
superiors = []
# 递归终止条件:没有上级时停止
if self.parent:
superiors.append(self.parent)
# 递归获取上级的上级
superiors.extend(self.parent.get_all_superiors())
return superiors
def get_nth_level_superior(self, n):
"""
获取第n级上级
:param n: 上级层级 (1=直接上级, 2=上上级, 以此类推)
:return: Weiuser对象或None
"""
"""
获取当前用户往上 n 级的父元素
:param n: 要查询的上级层级数 (必须 >=1)
:return: weiuser 对象或 None (如果不存在)
"""
if n < 1:
raise ValueError("n 必须大于或等于 1")
current = self
# 循环向上查询 n 次
for _ in range(n):
if not current.parent:
return None # 没有父级时提前终止
current = current.parent
return current
"""
这种实现方式更加简洁,但需要注意:
它使用了链式递归调用,可能会增加递归深度
每次递归都会重新检查字段是否存在,虽然安全但效率稍低
性能考虑
对于树形结构操作,递归实现通常更简洁,但在实际应用中需要注意:
Python递归深度限制:默认1000层,可通过sys.setrecursionlimit()调整
性能开销:递归调用比循环有更高的开销
内存使用:递归会占用更多栈空间
在大多数实际应用中,树结构的深度不会超过100层,因此递归实现通常是可行的。但如果预期树结构会非常深(如超过1000层),建议使用循环实现或混合实现。
"""
def find_ancestor_by_field(self, field_name, target_value, include_self=False):
"""
从当前用户向上查找,找到第一个指定字段等于目标值的祖先
:param field_name: 要查找的字段名
:param target_value: 目标值
:param include_self: 是否包含自身
:return: Weiuser对象或None
"""
# 验证字段名是否有效 - 修复方法
if not hasattr(self, field_name):
raise ValueError(f"无效字段名: {field_name}")
# 如果包含自身且满足条件,直接返回
if include_self and getattr(self, field_name) == target_value:
return self
# 向上遍历祖先
current = self.parent
while current:
if getattr(current, field_name) == target_value:
return current
current = current.parent
return None
def find查找指定的上级(self, field_name, target_value, include_self=False):
"""
从当前用户向上查找,找到第一个指定字段等于目标值的祖先
:param field_name: 要查找的字段名
:param target_value: 目标值
:param include_self: 是否包含自身
:return: Weiuser对象或None
"""
# 验证字段名是否有效 - 修复方法
if not hasattr(self, field_name):
raise ValueError(f"无效字段名: {field_name}")
# 如果包含自身且满足条件,直接返回
if include_self and getattr(self, field_name) == target_value:
return self
# 向上遍历祖先
current = self.parent
while current:
if getattr(current, field_name) == target_value:
return current
current = current.parent
return None
# class weiuser用户角色表(models.Model):
# """城市信息表"""
# objects = models.Manager() #
# idKeyweiuser用户角色表 = models.UUIDField(primary_key=True, default=uuid8)
# id_str = models.CharField(max_length=128, default=generator.generate_str)
# user用户角色名称 = models.CharField(max_length=128, choices=weiuser用户角色表choicesStatus,
# default=weiuser用户角色表choicesStatus.普通会员.value)
# user用户的unionid = models.CharField(max_length=128, )
# dateAndTime = models.DateTimeField(auto_now_add=True, db_comment="创建时间") # 数据创建时间
# updateTime = models.DateTimeField(auto_now=True, db_comment="更新时间") # 更新时间(需要用 save() )
#
# class Meta:
# db_table = "weiuser用户角色表" # 给数据表自定义一个名称;默认的会是在 应用名+类名
# app_label = models_app_name
# ordering = ["-dateAndTime", "-updateTime"]