Here is my project folder structure.
<pre>
front
├── __init__.py
├── __init__.pyc
├── manage.py
├── middleware.py
├── settings.py
├── news
│ ├── __init__.py
│ ├── __init__.pyc
│ ├── admin.py
│ ├── admin_views.py
│ ├── models.py
│ ├── search_indexes.py
│ ├── search_sites.py
│ ├── utils.py
│ ├── views.py
</pre>
After I run
./manage.py runserver
then I visit http://127.0.0.1:8000/
It gives me error:
No module named front
This is caused by the following line in file views.py under news folder.
from front import settings
So the front folder is one level up to the views.py file. How I import the settings from one level up folder?
Thanks!
Either way this is wrong, whenever you're importing your own settings you should be importing from django.conf
from django.conf import settings
This isn't a module, its an object that does magic to import any settings you have set in your DJANGO_SETTINGS_MODULE
From the docs:
Also note that your code should not import from either global_settings or your own settings file. django.conf.settings abstracts the concepts of default settings and site-specific settings; it presents a single interface. It also decouples the code that uses settings from the location of your settings.
Related
I have a question regarding pytest and django 3.1. I have an app structure like that:
main_app
├── config
│ └── settings
│ └── base.py / local.py / prod.py
├── main_app
│ ├── sub_apps
│ │ └── models.py tests.py apps.py views.py etc...
│ ├── templates
│ │ ├── account
│ │ ├── sub_apps
│ │ ├── pages
│ │ ├── userpreferences
│ │ └── users
│ ├── userpreferences
│ │ └── models.py tests.py apps.py views.py etc...
│ ├── users
│ │ └── tests --> test_models.py test_views.py test_forms.py etc...
│ └── utils
└── requirements
Following the structure of pydanny/cookiecutter.
With this cookiecutter, the preferred test method is via pytest. But pytest is giving me a bunch of headaches:
In my settings, INSTALLED_APPS I register sub_apps within the
LOCAL_APPS =["sub_app_1", "sub_app_2", ...]
When I start django, everything is fine. But if I want to run tests, pytest is complaining heavily, it can't import the sub_app modules.
I suspect mixed up relative and absolute import paths but am not seeing how to solve this atm.
As a background: I use a separate userpreferences model which is imported in the settings via
LOCAL_APPS = ["main_app.userpreferences.apps.UserpreferencesConfig"]
In the apps.py I have to define the app name as
name = "main_app.userpreferences"
Otherwise I get an Runtime error stating the Model class does'nt declare an explicit app_label / is not installed in INSTALLED_APPS.
While django runs just fine with these imports, pytest exits before running tests with:
ModuleNotFoundError: No module named "sub_app_1"
I tried to change every import of modules in the sub_apps to e.g.:
from .sub_app_1 import models --> from main_app.sub_app_1 import models
but then django won't run anymore while the tests seem to run (pytest is starting and telling me 5/7 tests passed, while also occasionally printing import errors)
How do I resolve this?
coming from php, the namespaces are always well defined in php, typically using psr-4 from composer
https://getcomposer.org/doc/04-schema.md#psr-4
e.g. you have a folder
src/Foo/Bar/Baz
you then define in the composer.json file that
src/Foo is where the namespace Foo starts
thereafter, all subfolders are by convention, a new sub namespace e.g.
src/Foo/Bar/Baz/MyClass.php turns into
Foo.Bar.Baz.MyClass
Say I want to drop a utility python class into my django project, that I want to use in all django "apps"
Where would I drop it, and how to properly define the namespace? what is the transparent way to understand namespaces in python?
From this document:
https://docs.djangoproject.com/en/2.2/ref/applications/#projects-and-applications
Is this snippet:
A project’s root directory (the one that contains manage.py) is usually the container for all of a project’s applications which aren’t installed separately.
You can create whatever hierarchy you chose under that directory for utilities, which can conform to python's package system:
https://docs.python.org/3/tutorial/modules.html#packages
In Python, there is a search path for modules. It can be initialized from the command line with the PYTHONPATH environment variable and accessed programmatically via sys.path.
By default, the directory of the script you use to start the Python interpreter is the first entry in the search path.
Any module or package on the python path "starts a new namespace", to use your wording. Let's assume your project called mysite has an app called polls and has this structure:
mysite
├── manage.py
├── mysite
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ ├── utils.py
│ └── wsgi.py
├── polls
│ ├── __init__.py
│ ├── models.py
│ ├── utils.py
...
If you start it with python manage.py runserver, the packages mysite and polls are available.
I'd say a good place for project-wide utils module is the project package mysite. So you do import mysite.utils in any of your apps. If it grows beyond a single file, you can turn it into a subpackage, so instead of a utils.py, you have a utils directory containing an __init__.py file.
The above structure clutters the global namespace a bit. So some people prefer a structure where all your apps are subpackages of your project package, like this:
mysite
├── manage.py
├── mysite
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ ├── utils.py
│ ├── wsgi.py
│ └── apps
│ └── polls
│ ├── __init__.py
│ ├── models.py
│ ├── utils.py
...
After reading this, and crying a lot, I'm trying to make my Django app work with Python 2.7.
Here's my Django web dir:
├── locale
│ ├── en
│ ├── fr
│ └── sv
├── produits
│ ├── migrations
│ └── templatetags
├── pyweb
├── templates
│ └── produits
├── third_party
│ ├── authomatic_0_1_0
│ ├── defusedxml-0.4.1
│ ├── google_appengine_1_9_25
│ ├── python-openid_2_2_5
│ └── python3-openid
└── uploads
The most important to notice is that I've tried to add all my "external" module into a folder third_party.
In my views.py, the following code was working:
from third_party.authomatic_0_1_0 import authomatic
from third_party.authomatic_0_1_0.authomatic import adapters
from third_party.authomatic_0_1_0.authomatic.providers import oauth1, oauth2
It was working because I added those lines in settings.py at the very beginning:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR+'/third_party/defusedxml-0.4.1')
sys.path.append(BASE_DIR+'/third_party/python3-openid')
sys.path.append(BASE_DIR+'/third_party/google_appengine_1_9_25')
sys.path.append(BASE_DIR+'/third_party/authomatic_0_1_0')
But now, with python 2.7 it doesnt work anymore. What should I do to make it work? And what is a good practice in Python (because Pycharm doesn't recognize all the subfolders of third_party)?
Two problems: (1) encoding, so I added in all files at the very beginning:
# coding=UTF-8
(2) Decorator python_2_unicode_compatible: needed this for all my models with __str__ implemented, for example:
#python_2_unicode_compatible
class Texte(models.Model):
texte = models.CharField(max_length=200)
def __str__(self):
return self.texte
See here for more information
I know there have been many questions here on accessing static files in a Django project, but I could not find a satisfactory answer to a problem I am dealing with. So, here's my project structure:
.
├── project
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ ├── wsgi.py
├── db.sqlite3
├── manage.py
└── app
├── admin.py
├── __init__.py
├── migrations
│ ├── __init__.py
├── models.py
├── static
│ └── app
│ └── file.txt
├── tests.py
├── urls.py
└── views.py
As per Django 1.7 documentation I have stored the static file file.txt in app/static/app folder. Now, how do I reference this file in a view? Lets just say I need to read the contents of this file for every call defined in app/views.py.
As usual, I have default setting of STATIC_URL = '/static/' in project/settings.py
Thanks
You can import the static template tag into your view and use it as such:
from django.templatetags.static import static
url = static('app/file.jpg')
You can do this by defining STATIC_ROOT in your settings. Then before running your project you can run
python manage.py collectstatic
And the static files then can be accessed using:-
file = open(os.path.join(settings.STATIC_ROOT, 'app/a.txt'))
This is basically the way, it is supposed to be done in a production environment, as static files are hosted separately from the django html views.
To load the name of app dynamically in project/urls.py
url(r'^', include('app.urls', app_name="app")),
and then in views:-
from django.core.urlresolvers import resolve
def appname(request):
return resolve(request.path).app_name
I'm working through the official Django tutorial. At the end of part two they have you customize the admin template just a bit (changing some heading text). I think I've done everything right, but apparently I haven't because the admin site looks exactly the same after running syncdb and restarting the server. My project directory (excluding the virtualenv part) looks like this:
mysite
├── manage.py
├── mysite
│ ├── __init__.py
│ ├── __init__.pyc
│ ├── settings.py
│ ├── settings.pyc
│ ├── urls.py
│ ├── urls.pyc
│ ├── wsgi.py
│ └── wsgi.pyc
├── polls
│ ├── admin.py
│ ├── admin.pyc
│ ├── __init__.py
│ ├── __init__.pyc
│ ├── models.py
│ ├── models.pyc
│ ├── tests.py
│ └── views.py
└── templates
└── admin
└── base_site.html
In settings.py I have these lines added to make the project use the template in templates/admin:
import os
PROJECT_PATH = os.path.realpath(os.path.dirname(__file__))
later:
TEMPLATE_DIRS = (os.path.join(PROJECT_PATH, 'templates'),)
I've tried several combinations of slashes and variations on assigning the value to PROJECT_PATH and TEMPLATE_DIRS, but haven't gotten anything to work. Each time I verified that it was actually making a filepath string (with a simple print statement).
To try to see what was going on I edited the original Django base_site.html it its admin folder and that changed my site, so it's obviously still using that. I've read several SO posts, and I don't really know what to do anymore.
Oh, and if it's relevant: Python 2.7.3 and Django 1.4.3
First thing I would try is deleting your *.pyc files they often contain stale information which sometimes can cause issues likes this.
If that isn't the case I would then double check your PROJECT_PATH which I believe is the issue here.
dirname gets you the containing directory. so if that line is in the settings.py it will return /path/to/inner/mysite the one inside the main mysite and since there is not templates directory in your inner mysite it wont work.
what you need to do is this.
PROJECT_PATH = os.path.realpath(os.path.dirname(os.path.dirname(__file__)))
Which will return you the outer mysite path when combined with templates it will return you the correct path.
Everything should then work.