Django 1.10 - 子目录中的App模型无法按预期工作

时间:2016-09-01 11:43:08

标签: django django-models

关于Django 1.10的tutorial之后有一些小的偏差:

  • polls应用程序存在于mysite/apps/polls中,可通过apps.polls在项目中访问。
  • 已删除默认models.py文件,并添加了新模块:
    mysite/
    |
    |- apps/
    |  |- polls/
    |  |  |- models/
    |  |  |  |- __init__.py
    |  |  |  |- Question.py
    |  |  |  |- Choice.py

apps/polls/models/__init__.py正在导入QuestionChoice,两个模型都从django.db.models.Model延伸。

问题
运行makemigrations会抛出异常:

Traceback (most recent call last):
  File "/mysite/lib/python3.5/site-packages/django/db/models/fields/related.py", line 742, in __init__
    to._meta.model_name
AttributeError: module 'apps.polls.models.Question' has no attribute '_meta'

但是,Question模型显然具有_meta属性,因为它从django.db.models.Model延伸。据我所知,从Django 1.7开始,定义_meta.app_label不是必需的(在任何情况下,定义app_label都不起作用)。知道我需要做些什么才能使用子目录中的模型而不会在整个项目中引起额外的重构?

其他资源

1 个答案:

答案 0 :(得分:1)

您正在导入Question模块而不是Question模型。你需要改变它:

from django.db import models

from .Question import Question


class Choice(models.Model):
    question = models.ForeignKey(Question,
                                 on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=250)
    votes = models.IntegerField(default=0)

此处第一个.Question表示模块,第二个Question表示模型。 apps/polls/models/__init__.py中的import语句也是如此。

使用区分模块和类的命名方案是个好主意。这可以避免混淆您实际导入的内容。通常的惯例是对模块名称使用小写,对类名使用CamelCase。那会给你questions.pyclass Question(models.Model):

mysite/
|
|- apps/
|  |- polls/
|  |  |- models/
|  |  |  |- __init__.py
|  |  |  |- question.py
|  |  |  |- choice.py

# apps/polls/models/choice.py
from django.db import models

from .question import Question


class Choice(models.Model):
    question = models.ForeignKey(Question,
                                 on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=250)
    votes = models.IntegerField(default=0)

通过遵循这样的惯例,模块question和模型Question之间的区别乍一看是显而易见的。