In my app, I have file structure:
myapp/
...
models.py
helpers/
__init__.py
RandomFileName.py
...
In RandomFileName.py I have helper class that generates random file names for my models:
class RandomFileName(object):
...
In models I want to treat helpers/ directory as a module:
from myapp.helpers import RandomFileName
class MyImage(models.Model):
...
image = models.ImageField(upload_to=RandomFileName('images/'))
...
Then, I run python3 manage.py makemigrations myapp
Looks good.
Then, I run python3 manage.py migrate and get an error:
in Migration
('image', models.ImageField(upload_to=myapp.helpers.RandomFileName.RandomFileName('images/'))),
AttributeError: type object 'RandomFileName' has no attribute 'RandomFileName'
Why is the RandomFileName doubled in migrations? Where did I go wrong?
Somehow your init.py file could have imported your object. Check. If not, then simply doing myapp.helpers.RandomFileName('images/') instead (based on the exception message) will fix the issue.
Related
This is in Django 2.0 , python 3.6.5
I have an app called posts, and I changed models.py to a folder structure, i.e., create a directory models and move the file models.py insid. Also config __ init__.py file, as explained next.
The project runs ok, but my test suite fails.
In my settings, installed apps i have the app as:
'myproject.apps.posts.apps.PostsConfig'
My app config (posts/apps.py)
from django.apps import AppConfig
class PostsConfig(AppConfig):
name = 'posts'
verbose_name = 'posts'
I have move posts/models.py to a directory structure. So I have
posts/models/models.py
posts/models/proxymodels.py
posts/models/__init__.py
inside models/__ init__.py I do import my models as explained in doc
from .models import Job
from .proxys import ActiveJob
The project works well, but when trying to run tests:
python manage.py test
I have this error:
RuntimeError: Model class tektank.apps.posts.models.models.Job doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.
The model is a normal one, with fields, nothing extrange. The thing is that if I declare in the meta
class Meta:
app_label = 'posts'
I got the following error:
RuntimeError: Conflicting 'job' models in application 'posts': <class 'posts.models.models.Job'> and <class 'tektank.apps.posts.models.models.Job'>.
Note: If I use pytest, I run the command:
pytest
It runs OK
UPDATE
Same error if I execute:
./manage.py test myproject/apps/posts
If I execute only with app name, no tests are detected
./manage.py test posts
Ran 0 tests in 0.000s
OK
If I put the path of the tests folder, it works ok.
./manage.py test myproject/apps/posts/tests
Ran 2 tests in 0.074s
OK
./manage.py test posts.tests
Ran 2 tests in 0.103s
OK
But I am not satisfied with this, if I want to run all tests, it will still fail.
Having followed the advice in these two answers, I'm still unable to run only a single django test in the way it describes. I can run them all, but that takes a long time and makes debugging harder.
My project structure looks like this:
mainapp/mainapp/users/
├── __init__.py
├── tests
│ ├── __init__.py
│ ├── test_views.py
└── views.py
For example, when the whole test suite is run, one of the failing tests gives this output:
FAIL: test_changepassword (mainapp.users.tests.test_views.ChangePasswordTest)
But when I try to run that Django TestCase with either the Django...
~/mainapp$ python manage.py test mainapp.users.tests.test_views.ChangePasswordTest
File "/usr/lib/python2.7/unittest/loader.py", line 100, in loadTestsFromName
parent, obj = obj, getattr(obj, part)
AttributeError: 'module' object has no attribute 'test_views'
or django-nose syntax...
~/mainapp$ python manage.py test mainapp.users.tests.test_views:ChangePasswordTest
File "/usr/lib/python2.7/unittest/loader.py", line 100, in loadTestsFromName
parent, obj = obj, getattr(obj, part)
AttributeError: 'module' object has no attribute 'test_views:ChangePasswordTest'
When I run this in PyCharmCE debug mode it confirms that the module object has no attributes, but I don't know why.
I have django-nose (1.4.5) installed and it's in my INSTALLED_APPS, but I don't know if anything else is required to use it.
This works fine down to a certain level. For example this is OK:
~/mainapp$ python manage.py test mainapp.users.tests
What's going on?
I recently upgraded from Django 1.4 to 1.9 and realized something weird was going on with my tests. Here is the project structure:
project
manage.py
app/
__init__.py
tests/
__init__.py
test_MyTests.py
The test_MyTests.py file looks like this:
from django.test import TestCase
class MyTests(TestCase):
def test_math(self):
self.assertEqual(2, 2)
def test_math_again(self):
self.assertEqual(3, 3)
The test runner can find all of the tests when I run
./manage.py test app or ./manage.py test app.tests. However when I try running ./manage.py test app.tests.MyTests I get:
File "/usr/lib/python2.7/unittest/loader.py", line 100, in loadTestsFromName
parent, obj = obj, getattr(obj, part)
AttributeError: 'module' object has no attribute 'MyTests'
If I change the test class name to test_MyTests I can then run ./manage.py test app.tests.test_Mytests and it will find all tests. I was reading the Django docs though and it seems the file name and class name don't have to be the same. In either case that I showed above I still can't run individual tests like this, ./manage.py test app.tests.MyTests.test_math
I would like to be able to run individual tests and test classes, can someone help me here? Thanks.
In app.tests.test_MyTests part test_MyTests is module name, not class. To run test_math you should specify full path to this method:
python manage.py test app.tests.test_MyTests.MyTests.test_math
Y had the same problem and it was that I forgot to remove the default file tests.py that django create automatic when you create the app.
I have a flask app with the following directory structure:
myapp/
application.py
__init__.py
models/
__init__.py
user.py
The models use Flask-SQLAlchemy, and therefore, they need to have access to the db object (a SQLAlchemy instance) from application.py
user.py:
import sys,os
sys.path.append('/path/to/application/package')
from testapp import db
class User(db.Model):
id = db.Column(db.Integer,primary_key=True)
username = db.Column(db.String(255),unique=True)
age = db.Column(db.Integer)
def __init__(self,username,age):
self.username = username
self.age = age
def __repr__(self):
return '<User %r>' % self.username
Because any of the models need access to the application's SQLAlchemy instance, the db property, I have to throw this whole package on the path and then import from the main application module. For sanity's sake, I would like to keep the models in separate files. Will I need to put the path code on top of every model? Is there a better way? I'd rather not have the full path input like that, as they may be deployed to different hosts with different directory structures. Ideally there would be some way to internally handle the path so when it is used as another user via mod_wsgi I don't have to manually change the code.
1st approach:
I've ended up with the following structure:
project_root — also holds some configs, .gitignore file, etc
start.py
flask_root
__init__.py
application.py
module_1
__init__.py
models.py
module_2
__init__.py
models.py
Topmost start.py just runs the app:
#! /usr/bin/env python
from flask_root import applicaiton
if __name__ == '__main__':
application.manager.run()
Python searches for packages in the directory you script started from, so now you don't need add them to sys.path (as for me, modification of sys.path looks ugly).
Now you have full-working flask_root python package, and you can import everything from it, from any place of your application:
from flask_root.application import db
2nd approach:
If you start your Flask application from it's directory,
./application.py runserver
the directory you've started from is not be accessible as python package, even if it has __init__.py in it.
Though, with your directory layout you can do the following trick:
models/__init__.py:
from application import db
...
models/user.py:
from . import db
...
The first approach is more clean and universal. The second possibly can be useful when you need to share same blueprints between multiple Flask projects.
In the name of maintainability, I moved some of my larger models to their own files. So before i had this:
app/
models.py
and now I have this:
app/
models/
__init__.py
model_a.py
model_b.py
This works fine, but when I use manage.py to do sync db, it doesn't create a table for these models anymore.
Am I forgetting something?
Thanks,
Models must be found in module named app.models where app is an app name. So you should write in app/models/__init__.py file
from model_a import *
from model_b import *
In Django < 1.7
Note fron django 1.7 onwards this is not neccessary.
Moreover --- (that's what I had problem with) you will have to manually update app_label attribute for your models, so write:
__all__ = ["ModelA", "ModelA1"]
class ModelA(models.Model):
class Meta:
app_label = 'your_app'
without it app will be set incorrectly by django.
If you are afreid that from model_a import * are evil you allways can set up __all__ attributes in all modules.
You need to set Meta.app_label for each of the models to the app name where it belongs and make sure they are imported from models/__init__.py.
You can have a look here for more details: https://code.djangoproject.com/wiki/CookBookSplitModelsToFiles