Django views not getting setting variables - django

Views.py is not picking up anything from settings.py
views.py has import on top
from django.conf import settings
if tried to run in this file
name = settings.APP_NAME
it throws this error
AttributeError at /test/app
'_CheckLogin' object has no attribute 'APP_NAME'

You must have redefined settings elsewhere in the module.

I think we need more information. Is it possible you're overwriting your settings variable? This suggests that your settings object is a '_CheckLogin' object Try to debug with pdb. Here's a good tutorial: http://simonwillison.net/2008/May/22/debugging/

Related

ModuleNotFoundError: No module named 'register'

I am working on a Django project. I am working on the register page. When I try to import my register/views.py to my mysite/urls.py file I get an error message. ModuleNotFoundError: No Module named 'register'. Both files are are in the same directory.
from django.contrib import admin
from django.urls import path, include
from register import views as v
Adding full exception message
Try the following:-
from . import views
Please add a blank __init__.py file in the register folder.
Only then python will understand that register is an importable package
Edit:
After seeing the exception, it looks like a working directory issue in pycharms. Please try the fix mentioned in this link

Django-Filebrowser settings not defined

Quick (probably silly) question regarding Django-Filebrowser. I'm adding the lines from readthedocs in my settings.py
MEDIA_ROOT = getattr(settings, "FILEBROWSER_MEDIA_ROOT", settings.MEDIA_ROOT)
and I'm getting
NameError: name 'settings' is not defined
If I'm right, adding an import
import filebrowser.settings
Will throw a circular reference error (it comes up asking for a SECRET_KEY) if I do so. What do I do to fix this and define settings?!
Thanks!
By looking at the source it looks like you should import Django settings:
from django.conf import settings

Calling a model's method from outside Django

I have a Django model with some static methods. I'd like to call the methods from outside the application (cronjob).
The model I have:
class Job(models.Job):
#Irrelevant information
#staticmethod
def methodIwantToCall():
#statements
I have the following python file that I'm using for the cron job:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
from myapp.models import Job
Job.methodIwantToCall()
At first, I was having an error about DJANGO_SETTINGS_MODULE not being set and I fixed that, however, now I have the following error: No module named myapp.utils
I feel like I'm doing something that I'm not supposed to do. So how do I call that static method the way I want it to be called?
EDIT: It looks like the paths are getting messed up when I'm importing from outside Django. For example, I have an import in my models file, when I call the cron file it fails importing with the message ImportError: No module named myapp.utils even though it's working.
The proper solution is to create custom manage.py command.
Assuming your cron job code resides in the same directory as your settings file, use the following setup code at the beginning:
from django.core.management import setup_environ
import settings
setup_environ(settings)

Detect django testing mode

I'm writing a reusable django app and I need to ensure that its models are only sync'ed when the app is in test mode. I've tried to use a custom DjangoTestRunner, but I found no examples of how to do that (the documentation only shows how to define a custom test runner).
So, does anybody have an idea of how to do it?
EDIT
Here's how I'm doing it:
#in settings.py
import sys
TEST = 'test' in sys.argv
Hope it helps.
I think the answer provided here https://stackoverflow.com/a/7651002/465673 is a much cleaner way of doing it:
Put this in your settings.py:
import sys
TESTING = sys.argv[1:2] == ['test']
The selected answer is a massive hack. :)
A less-massive hack would be to create your own TestSuiteRunner subclass and change a setting or do whatever else you need to for the rest of your application. You specify the test runner in your settings:
TEST_RUNNER = 'your.project.MyTestSuiteRunner'
In general, you don't want to do this, but it works if you absolutely need it.
from django.conf import settings
from django.test.simple import DjangoTestSuiteRunner
class MyTestSuiteRunner(DjangoTestSuiteRunner):
def __init__(self, *args, **kwargs):
settings.IM_IN_TEST_MODE = True
super(MyTestSuiteRunner, self).__init__(*args, **kwargs)
NOTE: As of Django 1.8, DjangoTestSuiteRunner has been deprecated.
You should use DiscoverRunner instead:
from django.conf import settings
from django.test.runner import DiscoverRunner
class MyTestSuiteRunner(DiscoverRunner):
def __init__(self, *args, **kwargs):
settings.IM_IN_TEST_MODE = True
super(MyTestSuiteRunner, self).__init__(*args, **kwargs)
Not quite sure about your use case but one way I've seen to detect when the test suite is running is to check if django.core.mail has a outbox attribute such as:
from django.core import mail
if hasattr(mail, 'outbox'):
# We are in test mode!
pass
else:
# Not in test mode...
pass
This attributed is added by the Django test runner in setup_test_environment and removed in teardown_test_environment. You can check the source here: https://code.djangoproject.com/browser/django/trunk/django/test/utils.py
Edit: If you want models defined for testing only then you should check out Django ticket #7835 in particular comment #24 part of which is given below:
Apparently you can simply define models directly in your tests.py.
Syncdb never imports tests.py, so those models won't get synced to the
normal db, but they will get synced to the test database, and can be
used in tests.
I'm using settings.py overrides. I have a global settings.py, which contains most stuff, and then I have overrides for it. Each settings file starts with:
from myproject.settings import settings
and then goes on to override some of the settings.
prod_settings.py - Production settings (e.g. overrides DEBUG=False)
dev_settings.py - Development settings (e.g. more logging)
test_settings.py
And then I can define UNIT_TESTS=False in the base settings.py, and override it to UNIT_TESTS=True in test_settings.py.
Then whenever I run a command, I need to decide which settings to run against (e.g. DJANGO_SETTINGS_MODULE=myproject.test_settings ./manage.py test). I like that clarity.
Well, you can just simply use environment variables in this way:
export MYAPP_TEST=1 && python manage.py test
then in your settings.py file:
import os
TEST = os.environ.get('MYAPP_TEST')
if TEST:
# Do something
Although there are lots of good answers on this page, I think there is also another way to check if your project is in the test mode or not (if in some cases you couldn't use sys.argv[1:2] == ["test"]).
As you all may know DATABASE name will change to something like "test_*" (DATABASE default name will be prefixed with test) when you are in the test mode (or you can simply print it out to find your database name when you are running tests). Since I used pytest in one of my projects, I couldn't use
sys.argv[1:2] == ["test"]
because this argument wasn't there. So I simply used this one as my shortcut to check if I'm in the test environment or not (you know that your DATABASE name prefixed with test and if not just change test to your prefixed part of DATABASE name):
1) Any places other than settings module
from django.conf import settings
TESTING_MODE = "test" in settings.DATABASES["default"]["NAME"]
2) Inside the settings module
TESTING_MODE = "test" in DATABASES["default"]["NAME"]
or
TESTING_MODE = DATABASES["default"]["NAME"].startswith("test") # for more strict checks
And if this solution is doable, you don't even need to import sys for checking this mode inside your settings.py module.
I've been using Django class based settings. I use the 'switcher' from the package and load a different config/class for testing=True:
switcher.register(TestingSettings, testing=True)
In my configuration, I have a BaseSettings, ProductionSettings, DevelopmentSettings, TestingSettings, etc. They subclass off of each other as needed. In BaseSettings I have IS_TESTING=False, and then in TestingSettings I set it to True.
It works well if you keep your class inheritance clean. But I find it works better than the import * method Django developers usually use.

PyLint failing for a number of Django imports

I am using PyLint,
pylint -e app/views.py
Gives me errors like
E: 3: No name 'shortcuts' in module 'django'
E: 7: No name 'db' in module 'django'
But passes for other django imports. Since it passes for other Django import Django is on my pythonpath.
I think I figured it out -- if you jump into a python session and actually try to import anything from django.db
from django.db import *
you'll get an error about DJANGO_SETTINGS_MODULE not being set. Setting the environment variable and pointing it to your settings.py like app.settings should fix the error for you.
When I tried this in an Eclipse/PyDev config I had to disable pylint, build, then re-enable pylint to finally clear out those errors.
Have you tried djangolint, which is a wrapper around Pylint with Django-specific settings?