python - 根据 Django 数据库中的当前项目数生成默认值 - 循环导入问题
问题描述
我正在处理一个 Django 项目,但我真的不知道如何避免 Django 模型和自定义 python 文件之间的循环导入generators.py
帐户/模型.py
from django.db import models
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager
from django.utils import timezone
from core.generators import make_id_number
class UserManager(BaseUserManager):
def create_user(self, email, username, fname, lname, password, **others):
if not email:
raise ValueError(_('Please Provide Email Address!'))
if not username:
raise ValueError(_('Please Provide User Name!'))
if not fname:
raise ValueError(_('Please Provide First Name!'))
if not lname:
raise ValueError(_('Please Provide Last Name!'))
email = self.normalize_email(email)
user = self.model(
email=email,
username=username,
fname=fname,
lname=lname,
password=password,
**others
)
user.set_password(password)
user.save()
return user
def create_superuser(self, email, username, fname, lname, password, **others):
others.setdefault('is_staff', True)
others.setdefault('is_superuser', True)
others.setdefault('is_active', True)
if others.get('is_staff') is False:
raise ValueError(_('Superuser must have \'staff\' permissions!'))
if others.get('is_active') is False:
raise ValueError(_('Superuser must be active!'))
if others.get('is_superuser') is False:
raise ValueError(_('Superuser must have \'superuser\' permissions!'))
return self.create_user(email, username, fname, lname, password, **others)
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(_('Email'),max_length=150,unique=True)
username = models.CharField(_('Username'),max_length=150,unique=True)
fname = models.CharField(_('First Name'),max_length=150)
mname = models.CharField(_('Middle Name'),max_length=150,null=True,blank=True)
lname = models.CharField(_('Last Name'),max_length=150)
date_joined = models.DateTimeField(_('Date Joined'),default=timezone.now)
last_login = models.DateTimeField(_('Last Login'),auto_now=True)
is_staff = models.BooleanField(_('Staff'),default=False)
is_active = models.BooleanField(_('Active'),default=False)
is_superuser = models.BooleanField(_('Superuser'),default=False)
objects = UserManager()
EMAIL_FIELD = 'email'
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email', 'fname' , 'lname']
def __str__(self):
return self.username
def get_full_name(self):
full_name = (f'{self.fname} {self.lname}')
return full_name.strip()
def get_short_name(self):
return self.fname
class UserIdentification(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
id_number = models.BigIntegerField(_('ID Number'), default=make_id_number, unique=True)
reg_code = models.CharField(_('Registration Code'), max_length=150, unique=True)
def __str__(self):
return (f'{self.user.username}-{self.id_number:09d}')
核心/发电机.py
import pytz
from django.utils.crypto import get_random_string
from django.utils import timezone
from django.conf import settings
from accounts.models import UserIdentification
# Generate a random password with the given length and given allowed_chars.
# The default value of allowed_chars does not have "I" or "O" or letters and digits that look similar to avoid confusion.
def make_random_password(length=12, allowed_chars='!@#$%^&*()_+-=abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789'):
return get_random_string(length, allowed_chars)
def make_id_number(local_tz=settings.TIME_ZONE):
local_tz = pytz.timezone(local_tz)
local_date = local_tz.normalize(timezone.now()).date()
mm=int(local_date.month)
dd=int(local_date.day)
yy=int(local_date.year-2000)
ccc=int(UserIdentification.objects.all().count())
# ccc=0
id_number=int(f'{mm:02d}{dd:02d}{yy:02d}{ccc+1:03d}')
return id_number
如您所见,这肯定会导致循环导入问题,因为我make_id_number
从中导入core/generators.py
会查询数据库中使用模型UserIdentification
from的当前用户数accounts/models.py
,这反过来会要求core\generators.py
生成一个 id 号。
我将非常感谢任何能给我解决方案、提示或教程的人,我该如何避免这种情况。
解决方案
在python中有一个避免循环导入的技巧
只导入模块,不从模块导入
在模型.py 中: import core.generators
在 generators.py 中:import accounts.models
推荐阅读
- microsoft-graph-api - 图形邮件 API 返回 504 网关超时错误
- excel - 将 Excel VBA 用户表单另存为 PDF
- figure - 图与文字之间的间距
- elasticsearch - 无法为持久文档时看到的类型类的未知值写入 xcontent
- firebase - 将用户添加到 firebase 项目中的单个应用程序
- node.js - 在将它们与 FFmpeg 连接之前如何检查文件是否损坏?
- php - 根据 WooCommerce 中的付款方式和购物车项目总数添加费用
- python - 运行 for 循环时,ResultSet 对象没有属性“find”
- javascript - Node.js & Express - 错误和成功模式一起出现在错误情况下
- c# - EF Core 字符串包含字符串数组