Python import problem with Django management commands - python

For whatever reason, when I was new to Python and Django, I wrote some import statements like this at the top of a models.py file:
from django.contrib import auth
And I'd use it like this:
class MyModel(models.Model):
user = models.ForeignKey(auth.models.User)
# ...
This worked fine. A long time later, I wrote a custom management command, and it would do this:
from myapp.models import MyModel
When I ran my custom command (python manage.py my_command) this would result in Python complaining that the module auth had no attribute models on the line declaring the ForeignKey in models.py.
To work around this problem, I changed my models.py to the more usual:
from django.contrib.auth.models import User
class MyModel(models.Model):
user = models.ForeignKey(User)
# ...
Can someone explain to me what I am missing? Is there something different in the environment when you run a management command? Or was I just doing it wrong the whole time? Thanks!
Edit: Following dmitko's hunch about circular imports, here are the imports used in my models.py file. I'm showing the original import of auth commented out, along with the only model that has a foreign key to the auth user model:
import datetime
from django.db import models
# from django.contrib import auth
from django.contrib.auth.models import User
class UserLastVisit(models.Model):
# user = models.ForeignKey(auth.models.User, unique=True)
# ^^^^^^^^^^^^^^^^
# after adding mgmt command, error occurred here; change to the line below
user = models.ForeignKey(User, unique=True)
last_visit = models.DateTimeField(db_index=True)
And here are the imports of the management command that uncovered the problem:
import datetime
from django.core.management.base import NoArgsCommand
from core.models import UserLastVisit, AnonLastVisit, Statistic
Was this setting up a circular import type situation?

If some random module ever imports module x.y.z, then a later person who imports just x.y will see a z in the x.y namespace.
The reason this happens is that import x.y.z is actually three import statements in one. It works something like this:
x = __internal_import('x')
x.y = __internal_import('x/y')
x.y.z = __internal_import('x/y/z')
Next time someone does __internal_import('x/y'), they'll get the same object, because python is smart enough not to import the same one twice. That object already has its z member assigned to the z module.
In your full app, probably you had a module that did import django.contrib.auth.models. But your minimal standalone program didn't import that module, so the name was never assigned.
(Note: there's no such thing as __internal_import. It's just an illustration. The real function has some other name that you would have to look up.)

I guess that if you do from django.contrib import auth that means you're importing auth package as a module and what it exports is driven by __init__.py in the auth folder:
>>> from django.contrib import auth
>>> dir(auth)
['BACKEND_SESSION_KEY', 'ImproperlyConfigured', 'REDIRECT_FIELD_NAME', 'SESSION_
KEY', '__builtins__', '__doc__', '__file__', '__name__', '__path__', 'authentica
te', 'datetime', 'get_backends', 'get_user', 'import_module', 'load_backend', 'l
ogin', 'logout']
You can check __init__.py in django\contrib\auth and see the same function list. When you import from django.contrib.auth.models import User that means that you're importing a submodule from the auth package and it works.
BTW. I was unable to use auth.models.User in any case - whether I run from console or from my django app.

It's hard to say exactly what's going on without seeing the new manage.py command that you added. However, I often see the " has no attribute " in cases with circular imports, and it's almost always fixed by changing the module-level imports to function- or class-level imports, as you did here. You might check if anything like that is going on here.

Related

Unable to call a class using Django

If I do that :
from myapp import models
User.objects.first()
I got that error :
NameError : name 'User' is not defined
whereas if I do that
import myapp
myapp.models.User.objects.first()
it works
I don't understand at all why I have that problem
Thank you very much for your help !
Replace:
from myapp import models
with the following:
This way, you are telling Django which model classes to import rather than leaving Django guessing what to do with it.
It prevents you from loading unnecessary models which might not be used right away and could potentially increase load time.
from myapp.models import User
In your example, your have not imported class User actually. You have imported it's module called models
You can do one of these:
from myapp import models
models.User.objects.first()
Or:
from myapp.models import User
User.objects.first()

AttributeError: module 'django.db.models' has no attribute 'Models'

When I'm trying to migrate a new app onto the server i get this error
AttributeError: module 'django.db.models' has no attribute 'Models'- in terminal
I'm using PyCharm. I am very fresh to Django and web development so any tips will help. Thanks!
from django.db import models
# Create your models here.
class product(models.Model):
item = models.Textfiels()
description = models.Textfields()
price = models.Textfields()
There's no such class django.db.models.TextFields but this works for me on any recent version :
from django.db import models
class product(models.Model):
item = models.TextFiel()
description = models.TextField()
price = models.TextField()
You made 2 typos : the correct name is TextField and you typed Textfields (Python is case sensitive)
I suspect you didn't setup correctly your project under PyCharm. When correctly setup, it shows warnings on misspelled names (names underlined with red dots with default setting).
There's another variation to this question and that is in the form of:
AttributeError: module 'django.contrib.auth' has no attribute 'models'
As far as I can tell this is typically caused by conflicting imports or improperly imported files. Another cause could be changes to Django's updates but I'm not sure about that as I didn't find any documentation that changed that aspect of the Django library.
Short term solution to this is as follows:
from django.contrib.auth import models
class MyClass(models.User): """ """
This will allow you to at least test your runserver command and website on a browser of your choosing.
I'm still trying to figure out any other solutions to this problem that can be a fix for individually importing the 'auth' module itself.
At the time of this writing I'm using Django 2.2.6 whereas Django 2.2.7 is out and 2.2.8 is on the way to be released.
I'm not sure if this is the solution , but when I had this problem it was because in my admin.py file I had
from django.contrib import admin
from meetings.models import Meeting, Room
admin.site.register(Meeting, Room)
But changing it to solved the issue
from django.contrib import admin
# Register your models here.
from meetings.models import Meeting, Room
admin.site.register(Meeting)
admin.site.register(Room)

How to import a class from ndb.Model?

I'm working with Google App Engine and I want to use my ndb model in another .py file but I couldn't import it.
Here is my main.py;
from google.appengine.ext import ndb
class User(ndb.Model):
username = ndb.StringProperty()
created_date = ndb.DateTimeProperty(auto_now=True)
follower_list = ndb.StringProperty(repeated=True)
And this is some code from my cron.py file:
from google.appengine.ext import ndb
save_user = User.query().filter(User.username == username)
But I'm getting:
ImportError: No module named User
How can I import the User class?
When you create the model you're just instantiating a class and assigning it to the variable named User. In python those variables are bound to the module they were declared in, and there are no implicit globals, so if you want to use it in another module you would need to import it:
from google.appengine.ext import ndb
import main
save_user = main.User.query().filter(main.User.username == username)
However the best practice would be to create the models in a models.py file, and import that anytime you need them.
BTW, your error hints that you're trying to import User earlier in your cron file, is that so? Either way I think you should get the idea now :)

Python, Flask, SQLAlchemy: cannot import from models

I've got a weird problem.
I am building a Flask app with SQLAlchemy. I have a file with models, namely, models.py. And I have a User model there.
If I open my "views.py" and insert a string
import models
and then use the User model like
u=models.User.query.filter_by(name='John',password='Doe').first()
everything works fine.
But if instead of "import models" i put
from models import User
Python crashes and says:
ImportError: cannot import name User
how can this be possible?
you most likely have a circular import; your, lets say 'app' module:
# app.py
import models
...
def doSomething():
models.User....
but your models module also imports app
import app
class User:
...
since models imports app, and app imports models, python has not finished importing models at the point app tries to import models.User; the User class has not been defined (yet). Either break the cyclic import (make sure models doesn't import anything that also imports models), or you'll just have to make do with models.User instead of the shorter User in app.
Instead of
from models import User
use
from models import *
In this case, you are importing the models into views.py therefore if you need a class from models, import it from views.py and the circular import problem will be resolved.

Django Splitting models from models.py file

I am trying to separate all the models from models.py file.What I am doing is mentioned in this link. But Problem is My one model is django.contrib.auth.user and I am wring one function in models.py as follows to generate token.
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
post_save.connect(create_user_profile, sender=User)
So how do I import that thing in _init_.py file as we are importing model as
from myapp.models.foo import Foo
You should only have either models.py or models/__init__.py, and it seem like you have both. One of these modules will probably shadow the other, so don't have both (i.e. get rid of the models.py)
If I'm following your question correctly, you don't need to import User into __init__.py. You just need to import it in the file in which you declare create_user_profile. The import itself is standard:
from django.contrib.auth.models import User
You can't import a command, but for example importing the function defined above it, ensures running the connect call. Function calls in the body of the models.py file are also executed of the same raeson (i.e. models are imported).
# p.py:
print "hello" # a command executed while importing anything
def x(): # a definition that can be imported
pass
# python shell
>>> from p import x
hello
>>>

Categories