I have a Flask app that has its configurations in a file called settings.py. I've put this file in .gitignore because the project is in a public repo. Travis-CI was working before I added tests into my project even though settings.py was in .gitignore. After adding tests to the project, the build started failing with the following output:
Debugged import:
- 'settings' not found.
Original exception:
ImportError: No module named 'settings'
My .travis.yml file looks like this:
language: python
python:
- "3.4"
- "3.5"
# command to install dependencies
install:
- pip install -r requirements.txt
# command to run tests
script: python tests.py
Does this mean that in order to use travis-ci, we have to include all necessary files in the repo? Or is there a workaround? The repo on GitHub can be found here.
#dirn's comment of using a default settings.py file and then overriding some settings with encrypted environment variables on Travis is a good idea, certainly worth it if there are only a couple of differences.
However, if you can't be bothered or it's too complicated breaking up your settings, you could install the Ruby Travis command line client gem, which is useful for quite a few things.
With the client on your machine you can use Travis' file encryption feature to encrypt your whole settings.py file, and then commit the encrypted version (which will have an .enc file extension) to GitHub. Travis will then be able to decrypt the file during the CI run, as long as you add the right commands to the .travis.yml file, say in a before_install step. Detailed instructions are on the file encryption page.
I did a trick in .travis.yml
After commit and before Travis build, create the ignored file like this:
before_install:
- cp .ignored.file.copy ignored.file
This way, the build will succeed without the actual gitignore-ed file.
I'm running Windows 10 (sorry) and I'm trying to set up the django-nonrel test app for GAE from github, https://github.com/django-nonrel/django-testapp.
I've downloaded and installed it and I've also installed the various modules from Django and NoSQL on github.
So my filestructure is dbindexer, django, djangoappengine and djangotoolbox as subdirectories of testapp. I've put these in place as I've come across install errors in the log file.
I'm now getting the message
ImproperlyConfigured: Error importing module autoload.middleware: "No
module named autoload.middleware"
This is reasonable since settings.py has autoload as an installed app.
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.contenttypes',
'django.contrib.auth',
'django.contrib.sessions',
'djangotoolbox',
'autoload',
'dbindexer',
# djangoappengine should come last, so it can override a few manage.py commands
'djangoappengine',
)
But I don't know where I find this module. I know I must be being really thick but I cannot work out how to get this running.
EDIT - here is the requirements.txt file
-e git+http://github.com/django-nonrel/djangotoolbox#toolbox-1.4#egg=djangotoolbox
-e git+http://github.com/django-nonrel/djangoappengine#appengine-1.4#egg=djangoappengine
-e git+http://github.com/django-nonrel/django-dbindexer#dbindexer-1.4#egg=django-dbindexer
-e git+http://github.com/django-nonrel/django#nonrel-1.4#egg=django-nonrel
-e hg+http://bitbucket.org/twanschik/django-autoload#egg=django-autoload
So I've downloaded this autoload and I'm now getting the following error.
ImportError: No module named fcntl
This was solved by going to a MySQL solution rather than django-nonrel. It took some time but lots on StackOverflow to help through it.
I want to install the external app django-disqus in my blog. However, instead of install the module in the system via pip install or python setup.py install, I would like to download the code to a specific folder called libs and then link it to my project.
My folder structure is like this:
-root_folder
-- project (here I have settings.py, urls.py and wsgi.py)
-- blog (here I have models.py, admin.py, urls.py, templatetags/, template/)
-- libs (here I want to add the code of disqus)
If I downloaded the code in libs, how can I link it to INSTALLED_APPS in setting.py?
Note: I run django 1.8
You should be able to register it the same way you'd register any django app.
Make libs a package by adding __init__.py file
Then add it to your settings.INSTALLED_APPS
INSTALLED_APPS = (
...
'libs.disqus',
)
I am trying to translate a string.
{% load i18n %}
{% trans "Well, Hello there, how are you?" %}
to...
Hola amigo, ¿que tal?
My settings.py file has this:
LOCALE_PATHS = (
os.path.join(BASE_DIR, 'translations'),
)
And I am getting this:
(env)glitch:translations nathann$ django-admin.py compilemessages
CommandError: Can't find msgfmt. Make sure you have GNU gettext tools 0.15 or newer installed.
I also don't understand this error message.
(env)glitch:ipals nathann$ django-admin.py makemessages -l es
CommandError:
This script should be run from the Django Git tree or your project or
app tree. If you did indeed run it from the Git checkout or your project
or application, maybe you are just missing the conf / locale(in the
django tree) or locale(for project and application) directory? It is not
created automatically, you have to create it by hand if you want to
enable i18n for your project or application.
The docs: https://docs.djangoproject.com/en/1.6/ref/django-admin/#django-admin-makemessages
And for bonus upvotes, a related question:
gettext wasn't linked when I installed it... Any help with this one? Should I force it?
glitch:translations nathann$ brew link gettext
Warning: gettext is keg-only and must be linked with --force
Note that doing so can interfere with building software.
Thanks!
UPDATES:
I have since changed the name of translations to locale and updated my settings.py accordingly. then I ran this again and it's still complaining about gettext:
(env)glitch:ipals nathann$ mv translations/ locale
(env)glitch:ipals nathann$ django-admin.py makemessages -l es
CommandError: Can't find xgettext. Make sure you have GNU gettext tools 0.15 or newer installed.
I also found this:
Understand homebrew and keg-only dependencies
after reading this:
(env)glitch:ipals nathann$ brew install gettext
Warning: gettext-0.18.3.2 already installed
(env)glitch:ipals nathann$ brew link gettext
Warning: gettext is keg-only and must be linked with --force
Note that doing so can interfere with building software.
After making sure I had this in settings:
LOCALE_PATHS = (
os.path.join(BASE_DIR, 'locale'),
)
print(LOCALE_PATHS)
I double checked I had the locale directory in the right place with its name spelled correctly.
I ended up linking gettext (after asking about that on superuser):
brew link gettext --force
manage.py compilemessages
django-admin.py makemessages -l es
And BAM. I've got my po file.
But the doctor says:
Warning: Some keg-only formula are linked into the Cellar.
Linking a keg-only formula, such as gettext, into the cellar with
`brew link <formula>` will cause other formulae to detect them during
the `./configure` step. This may cause problems when compiling those
other formulae.
Binaries provided by keg-only formulae may override system binaries
with other strange results.
You may wish to `brew unlink` these brews:
gettext
Please try this in Ubuntu
sudo apt-get install gettext
And use brew install gettext in OSX
Also make sure to set the local path in settings.py file.
Here is the solution for those having problems with translations or are creating a multi-language site for the very first time in Django. Here is the way I do it, and I have been doing since Django 1.4, below is tested in 1.7.1:
In settings.py …
Add to MIDDLEWEAR_CLASSES, locale, it enables language selection based on request:
'django.middleware.locale.LocaleMiddleware',
Add LOCALE_PATHS, this is where your translation files will be stored, also enable i18N:
USE_I18N = True
LOCALE_PATHS = (
os.path.join(PROJECT_PATH, 'locale/'),
)
Set LANGUAGES that you will be translating the site to:
ugettext = lambda s: s
LANGUAGES = (
('en', ugettext('English')),
('fr', ugettext('French')),
('pl', ugettext('Polish')),
)
Add i18n template context processor, requests will now include LANGUAGES and LANGUAGE_CODE:
TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.debug',
'django.core.context_processors.i18n', # this one
'django.core.context_processors.request',
'django.core.context_processors.static',
'django.contrib.messages.context_processors.messages',
)
Nest, in urls.py :
In url_patterns, add the below, it will enable the set language redirect view:
url(r'^i18n/', include('django.conf.urls.i18n')),
See Miscellaneous in Translations for more on this.
Add the following imports, and encapsulate the urls you want translated with i18n_patterns. Here is what mine looks like:
from django.conf.urls.i18n import i18n_patterns
from django.utils.translation import ugettext_lazy as _
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^i18n/', include('django.conf.urls.i18n')),
)
urlpatterns += i18n_patterns('',
(_(r'^dual-lang/'), include('duallang.urls')),
(r'^', include('home.urls')),
)
Note: You can also drop your admin urls into the i18n_patterns.
Now anywhere you use text and want to convert it, import lazytext and wrap every string with it like so _('text'), you can even go to your other urls.py files and do url translation like so:
url(_(r'^dual_language/$'), landing, name='duallang_landing'),
You can wrap text that you want translated in your other files, such as models.py, views.py etc.. Here is an example model field with translations for label and help_text:
name = models.CharField(_('name'), max_length=255, unique=True, help_text=_("Name of the FAQ Topic"))
Django translation docs are great for this!
In your html templates...
Now you can go into your templates and load the i18n templatetag and use trans and transblock on the static stuff you want to translate. Here is an example:
{% load i18n %}
{% trans "This is a translation" %}<br><br>
{% blocktrans with book_t='book title'|title author_t='an author'|title %}
This is {{ book_t }} by {{ author_t }}. Block trans is powerful!
{% endblocktrans %}
Now run a makemessages for each of your locales:
./manage.py makemessages -l pl
And now all is left is to go into your /locales folder, and edit each of the .po files. Fill in the data for each msgstr. Here is one such example of that:
msgid "English"
msgstr "Angielski"
And finally compile the messages:
./manage.py compilemessages
There is a lot more to learn with translations and internationalization is closely related to this topic, so check out the docs for it too. I also recommend checking out some of the internationalization packages available for Django like django-rosetta, and django-linguo. They help translate model content, django-rosetta does not create new entries for this in your database, while django-linguo does.
If you followed this you should be off to a good start. I believe this is the most standardized way to get your site running in multiple languages. Cheers!
For Mac users brew link gettext --force can be risk, as Brew advises. A better work around is to set a new PATH variable for your virtual environment. So, in the postactivate file, which is located in the bin folder of your virtual environment folder, type:
export TEMP_PATH=$PATH
export PATH=$PATH:/usr/local/Cellar/gettext/0.19.7/bin
Note that you have to replace 0.19.7 by the version that is installed in your machine.
And in your predeactivate file, which is located in the same folder of postactivate file, type:
export PATH=$TEMP_PATH
unset TEMP_PATH
Now you can use the python manage.py makemessages -l <desired_language> without worries. :)
Cheers.
For macOS :
brew install gettext
export PATH="/usr/local/opt/gettext/bin:$PATH"
Have you added {% load i18n %} to the top of your template?
Bonus: You don't need to link gettext, what is the output from brew doctor?
Please install gettext in your ubuntu OS
using sudo apt-get command
Or in Mac
using brew command
If you don't want to link gettext (which you shouldn't because messing about with OS X internals is bad) then you can set the PATH for the makemessages command. The following should work (but you need to adjust your gettext version number):
PATH=/usr/local/Cellar/gettext/<installed version>/bin/:$PATH && \
django-admin makemessages -l <language>
If you do it that way your installed gettext remains keg-only and django-admin will be happy and find all the programms it needs.
One of the possibilities is that after you have successfully done all the above and done
pip install python-gettext
you may have improperly configured your IDE or venv. In order to bypass this, go to the command prompt, navigate to your root folder and run py manage.py makemessages from there. It will work.
For me, on Windows 10, the problem was that I used gettext installed with pip install (I got version 0.19-something). I made it work by:
Uninstalling gettext with pip.
downloading gettext (as a zip) from here istead: https://mlocati.github.io/articles/gettext-iconv-windows.html
Extracting the files in a foler on "C:/program files"
Added the path to the "bin" folder (inside the extracted folder) to PATH in my environment variables in windows.
After that it worked! (after 5 h frustrated debugging...)
I'm starting on my first large django project and have realized that the default directory structure isn't going to work well.
I saw this question and answer and decided to implement something similar.
Large Django application layout
What do I need to do to make something like this work? How can I change where django looks for apps/modules?
Python works automatically with deep directory structures. That's porbably you didn't find any instructions on how to do it.Here are some instructions on how to get classes and models to work.
If you want to have a module in folder yourproject/apps/firstapp you can just add it to INSTALLED_APPS by adding line 'apps.firstapp',. You will have to add a __init__.py file to each of the directories so that they are recognized as python packages.
When you import classes you can simply use from yourproject.apps.firstapp.filename import yourclass.
You should also make sure all template directories are listed in TEMPLATE_DIRS.
I have two methods to handle this; one for production and one for development.
In development:
Append the path to your apps in your settings.py. In my case, I have my main project in ~/hg/django/project/ and my apps are in ~/hg/django/apps/. So I use:
if DEVEL:
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'apps'))
I also use the production method on my development box. This method has a knock on effect of letting me roll back to the most recent production version by simply commenting out the line path insertion in the settings.py.
In production:
I install the apps using distutils so that I can control deployment per server, and multiple projects running on each server can all access them. You can read about the distutils setup scripts here. Then, to install, you simply:
./setup.py install
if you add:
import os
PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
to your settings .py and the following to your manage.py:
sys.path.insert(0, join(settings.PROJECT_ROOT, "apps"))
sys.path.insert(0, join(settings.PROJECT_ROOT, "lib"))
then you can include them in your installed apps just as you would if they were in your project root:
INSTALLED_APPS = (
#local apps
'myapp',
#local libs
'piston_dev',
)
this allows you a bit more freedom to move apps around without having to redeclare imports and such.