【问题标题】:Import Error for models in Django while importing model in validators file在验证器文件中导入模型时,Django 中的模型导入错误
【发布时间】:2019-10-21 09:13:13
【问题描述】:

我收到一个错误 文件“D:\DjangoProjects\StudentExam\website\Student\validators.py”,第 2 行,从 .models 导入分支

ImportError: cannot import name 'Branch' from 'Student.models' (D:\DjangoProjects\StudentExam\website\Student\models.py)

对于语句“from .models import Branch”,写在validators.py文件中。 即使这两个文件在同一个应用程序中,它也会出错。我不明白出了什么问题。

我什至尝试过“从 Student.models/website.models 导入分支”,但它显示未解析的参考分支。

目录结构如下:-

StudentExam
  -venv
  -website
     -Student
        -migrations
        -__init__.py
        -admin.py
        -apps.py
        -models.py
        -tests.py
        -urls.py
        -validators.py
        -views.py
     -website
        -__init__.py
        -settings.py
        -urls.py
        -wsgi.py
     -db.sqlite3
     -manage.py

validators.py :-

from django.core.exceptions import ValidationError
from .models import Branch

def increment_id():
    last_branch_id = Branch.objects.all().order_by('id').last()
    new_branch_id = last_branch_id + 1
    return new_branch_id

models.py :-

from django.db import models
from .validators import validate_sem,cie_out_of,ese_out_of,increment_id

class Branch(models.Model):
    branchID = models.PositiveSmallIntegerField(primary_key = True, serialize = True, validators = increment_id())
    branchName = models.CharField(max_length = 30)

    objects = models.Manager()

    def __str__(self):
        return ', '.join('{} = {}'.format(key, value) for key, value in self.__dict__.items() if key != "_state")

【问题讨论】:

  • 你有一个循环导入。您需要将它们放在同一个文件中。但请注意,您根本不想这样做,您应该只使用已经自动递增的自动主键。做这一切是没有意义的。尤其是验证器是用于验证,而不是用于创建新值

标签: python django-models


【解决方案1】:

简答:改用AutoField,或者根本不指定主键:Django 会自动构造一个名为id的主键。

您在此处进行循环导入:您的models 模块依赖于您的validators,反之亦然。

但是,您可以通过在 increment_id 中导入 models 模块来延迟加载它:

# app/validators.py

from django.core.exceptions import ValidationError

def increment_id():
    from .models import Branch
    last_branch_id = Branch.objects.all().order_by('BranchId').last().BranchId
    new_branch_id = last_branch_id + 1
    return new_branch_id

在您的模型中,您可以使用:

# app/models.py

class Branch(models.Model):
    branchID = models.PositiveSmallIntegerField(primary_key=True, serialize=True, default=increment_id)

但是请注意,这不是验证器,您在这里有一个默认值。此外,您应该必须这样写:Django 有一个AutoField [Django-doc],即:

一个根据自动递增的 IntegerField 可用的 ID。您通常不需要直接使用它;一种 主键字段将自动添加到您的模型中,如果您 请勿另行指定。请参阅自动主键字段。

因此,您可以更好地将其定义为:

class Branch(models.Model):
    branch_id = models.AutoField(primary_key=True)
    # ...

根据PEP-8 Style Guidelines,建议使用lowercase_with_underscores命名属性,因此branch_id而不是branchId

此外,将主键命名为 id 以外的名称通常是没有意义的。通过在其前面加上 branch_id,您可以减少 duck typing 的使用。因此,最好完全省略该字段,如documentation on Automatic primary key fields says

默认情况下,Django 为每个模型提供以下字段

id = models.AutoField(primary_key=True)

这是一个自动递增的主键。

如果您想指定自定义主键,只需指定 primary_key=True 在您的一个字段上。如果 Django 看到 你已经 显式设置Field.primary_key,它不会添加自动 id专栏

因此,除非您有充分的理由自己指定一个,否则您可以只列出数据列:

class Branch(models.Model):
    # ...
    # other non-pk fields

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-23
    • 1970-01-01
    • 2019-03-13
    • 1970-01-01
    • 2012-03-27
    • 2019-01-01
    • 2012-10-06
    • 2016-08-20
    相关资源
    最近更新 更多