Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
238 views
in Technique[技术] by (71.8m points)

python - Django 3 NameError: name 'model_name' is not defined

I know this question has come up but many answers refer to older versions of Django and Python. I am running Django 3 and Python 3. Besides in our project we have decided to separate each model in its own file under a "models" folder. Please see below our tree structure:

├── db.sqlite3
├── manage.py
├── poi
│   ├── admin.py
│   ├── apps.py
│   ├── CHANGELOG.md
│   ├── fabfile.py
│   ├── __init__.py
│   ├── LICENSE
│   ├── migrations
│   │   ├── 0001_initial.py
│   │   ├── 0002_auto_20210104_1048.py
│   │   ├── __init__.py
│   │   └── __pycache__
│   │       ├── 0001_initial.cpython-38.pyc
│   │       ├── 0002_auto_20210104_1048.cpython-38.pyc
│   │       └── __init__.cpython-38.pyc
│   ├── models
│   │   ├── __init__.py
│   │   ├── layer.py
│   │   ├── poi.py
│   │   ├── __pycache__
│   │   │   ├── __init__.cpython-38.pyc
│   │   │   ├── layer.cpython-38.pyc
│   │   │   ├── poi.cpython-38.pyc
│   │   │   └── tag.cpython-38.pyc
│   │   └── tag.py
│   ├── models.py

In our models/init.py we have:

    from .poi import Poi
    from .tag import Tag
    from .layer import Layer

In our models/poi/poi.py we have:

from django.db import models
from .tag import Tag
from .layer import Layer


class Poi(models.Model):
    ...
    ...
    tags = models.ManyToManyField('Tag', through='Layer')


    def __str__(self):
        return self.name

In our models/poi/tag.py we have:

from django.db import models
import poi.models.poi
import poi.models.layer


class Tag(models.Model):
    name = models.CharField(max_length=100)
    pois = models.ManyToManyField('Poi', through='Layer')


    def __str__(self):
        return self.name

In our models/poi/layer.py we have:

from django.db import models
import poi.models.poi
import poi.models.tag


class Layer(models.Model):
    poi = models.ForeignKey(Poi, on_delete=models.CASCADE)
    tag = models.ForeignKey(Tag, on_delete=models.CASCADE)

The error comes up when we run python3 manage.py makemigrations. Error:

File "/media/elena/DATA2/Python-projects/osm-pois/osm-pois/upoi/poi/models/layer.py", line 8, in Layer
    poi = models.ForeignKey(Poi, on_delete=models.CASCADE)
NameError: name 'Poi' is not defined

We have tried other ways of import in layer.py such as:

from .poi import Poi
from .tag import Tag

But that gave us the following error:

File "/media/elena/DATA2/Python-projects/osm-pois/osm-pois/upoi/poi/models/layer.py", line 2, in <module>
    from .poi import Poi
ImportError: cannot import name 'Poi' from partially initialized module 'poi.models.poi' (most likely due to a circular import) (/media/elena/DATA2/Python-projects/osm-pois/osm-pois/upoi/poi/models/poi.py)

Any idea of how to solve this? Thanks!

question from:https://stackoverflow.com/questions/65641580/django-3-nameerror-name-model-name-is-not-defined

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I am posting as an answer what @TonySuffolk66 suggested via a comment since it worked perfectly. Thanks again!

Because your models are defined in different files, try doing this : poi = models.ForeignKey('Poi', on_delete=models.CASCADE) That is using a string for the model name, not a reference name. You can't 'easily' import other models like this due to the way that Django initializes


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...