I'm trying to make my way through the Django Project's tutorial.
I've made it as far as this: https://docs.djangoproject.com/en/1.3/intro/tutorial02/#s-make-the-poll-app-modifiable-in-the-admin but I'm seeing errors in some of the files, e.g. in the admin.py file:
from polls.models import Poll
from django.contrib import admin
admin.site.register(Poll)
I'm getting the error
Unresolved import: Poll
The models are defined as outlined in the tutorial:
import datetime
from django.db import models
class Poll(models.Model):
question = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
def __unicode__(self):
return self.question
def was_published_today(self):
return self.pub_date.date() == datetime.date.today()
class Choice(models.Model):
poll = models.ForeignKey(Poll)
choice = models.CharField(max_length=200)
votes = models.IntegerField()
def __unicode__(self):
return self.choice
The tutorial states that when I restart the server after adding the admin file, I should see the Poll app referenced in the Admin page at 127.0.0.1:8000, but all I'm seeing is this:
I'm also seeing
Unresolved import: Poll admin.py /newProj/src/newProj/polls line 0 PyDev Problem
Unresolved import: settings manage.py /firstproject/firstproject line 10 PyDev Problem
Unresolved import: settings manage.py /newProj/src/newProj line 10 PyDev
Are the errors the reason why I wouldn't be seeing the Site administration page updated with the Polls app?
How can I resolve these errors?
/newProj/src/newProj/polls and /firstproject/firstproject... eeek, this looks to be honest like the source of a few problems. OK, a few concepts:
Python packages: All python applications can be comprised of packages. These are basically just directories containing a __init__.py file.
How python finds packages: Well, python can do one of two things when it looks for packages:
If the current directory is a package, i.e. contains __init__.py, it can import from files in it.
It can search on the python path (PYTHONPATH environment variable, or sys.path - same thing) and then down into sub packages.
How django projects are laid out: A default django project looks something like this:
project_folder/
__init__.py
settings.py # config
urls.py # url config
polls/
__init__.py # makes polls a package
models.py # models
admin.py # admin
views.py # app views
forms.py # per app forms
urls.py # per app urls
In this layout, there are two possibilities for your admin.py when you runserver:
from models import Poll - this works because you're remaining within the scope of your package.
from polls.models import Poll - works because polls is a package and so is the parent from where you're running runserver.
Although it's tempting, don't use project_folder as a package. It'll break the code as soon as you rename the dir (for example, during deployment).
So, with all that in mind:
verify your __init__.py files exist in the right places and that you're using a directory structure kinda like the one above. Might be best to check outside the IDE too - IDEs can be... difficult.
verify your path is searching where you think it is. The current directory should work just fine; if it isn't, you can see
import sys
print sys.path
will allow you to view where you're looking. You can explicitly add the current directory, but you shouldn't need to.
I don't like PyDev. Totally personal preference here, but I find it hard work, over and above the usual editor of choice + terminal + file browser. You might too, especially if you find the directory structure is radically different in your file browser as compared to what you think you have with the IDE.
You are using Pydev, which add an additional layer of abstraction on the importing process.
Use a light text editor and a console for learning. You can switch to an IDE once the Python Path and the import logic are clear enough in your head so you can setup Pydev yourself.
Are the errors the reason why I wouldn't be seeing the Site
administration page updated with the Polls app?
The answer to this question is in the same page, at https://docs.djangoproject.com/en/1.3/intro/tutorial02/#customize-the-admin-form
try this:
import newProj.poll.models
Related
I want to use a Django model in an external python script. This python script is placed within the root directory of my project and I also created an init.py module for easy importing. Can anyone please instruct on what is the most secure and efficient way of importing a Django model into the python script?
I would also appreciate it if someone could advise me whether or not it is accurate to place an init.py module within the root directory. If not, what is the best way of doing this?
use this solution only if you want your scripts to be standalone (you want to access models when server is not running)
There are basically two different ways to do that:
If you are going to run this code frequently, I strongly suggest that you create a management command for the code. (check instructions here)
But if it's a bulk-data-import or something that's not gonna run many times, you can use something like this (put this in the root of your django app - beside manage.py):
import os
import django
if __name__ == '__main__':
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "<your_project_name>.settings")
django.setup()
# now you have access to your models
# as an example:
# from users.models import User
#
# for user in User.objects.all():
# print(user)
also keep in mind that you should always import your models after django.setup(), otherwise, you'll get an error.
I would also appreciate it if someone could advise me whether or not it is accurate to place an init.py module within the root directory. If not, what is the best way of doing this?
If you want to have multiple script files, it's not a good idea to put them in the root of django project. You can create a python package, say my_scripts, beside manage.py and put your scripts there.
So you will end up with something like this:
...
manage.py
my_scripts
├── __init__.py
└── first_script.py
But now you need to make a little change in the script file to make it work correctly. You should append the BASE_DIR to your path so that python can recognize the settings file (or module, if you extend it):
import os
import sys
import django
if __name__ == '__main__':
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "<your_project_name>.settings")
django.setup()
# now you have access to your models
# as an example:
# from users.models import User
#
# for user in User.objects.all():
# print(user)
I think it makes sense to organize my Django apps in a different way (by protocol):
📂myapp
apps.py
models.py
utilities.py
📂html
admin.py
urls.py
views.py
📂rest
serializers.py
urls.py
views.py
📂graphql
etc
This would move the admin.py file into the html folder, but sadly autodiscover does not seem to find it anywhere else than in the myapp folder. Is there a way to point to the correct location: perhaps in apps.py? I am sure a symlink would work, but not really what I am after.
There's nothing magic about either admin.py or autodiscover. All admin.py does is run any register calls on import, and all autodiscover does is look for an admin.py file in each installed app and import it. There's nothing to stop you importing your admin.py in its custom location from somewhere else, eg the models or views files.
This was somewhat tricky, but the comment by #Joran Beasley set me in the right direction.
For admin.py to be autodiscovered it needs to be either in the top level app folder, or be imported in a file. However... not every file works.
If you do from .html import admin
into __init__.py or apps.py: django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
into models.py: Results in an importerror from models into admin. I think due to the circular nature of the imports.
However the following works: from . import admin inside the urls.py. Make sure to add a comment that this import is needed for autodiscover purposes.
I am trying to reference a model (Person) from one app, in the views-file of another app. Unfortunately, I get an "unresolved reference"-error. Is it possible to reference models from other apps in Django? If so, what am I doing wrong?
Let me demonstrate with an example:
The image below shows my project. I am currently in the views.py (marked in green), in the app called "autocomplete". I want to reference a person-model in the file "models.py" (marked in red), that belongs to the app "resultregistration". However, I get the error "Unresolved reference Person", even though the class Person does exist in models.py
The file settings.py is in the athlitikos/athlitikos - folder, and manage.py is in only athlitikos (as seen in the image below)
Any help would be strongly appreciated!
Edit: I now tried running "from ..resultregistration.models import Person", because I saw that what I did in the screenshot was obviously wrong. However, then I get the error message " attempted relative import beyond top-level package"
Thank you for your time!
If the resultregistration app is in the project directory (the one containing manage.py) then you shouldn't include the project name athlitikos in the import at all. Try the following:
from resultregistration.models import Person
mm why you repeat athlitikos?, try replacing:
from athlitikos.athlitikos.resultregistration.models import Person
with
from resultregistration.models import Person
When doing the import from pycharm, it starts looking from the level of your present file, which is autocomplete/views.py, but Django starts from the project level, which is the level of your manage.py, so you can use from resultregistration.models import Person directly. Even though pycharm's inspections will show you errors in the code, it will pass when you running the project.
If we analyse your directory tree, we can see that:
athlitikos
autocomplete
views.py
resultregistration
models.py
In the views.py in autocomplete you can reference to other modules with relative path. Try this:
from ..resultregistration.models import Person
The first dot goes up to autocomplete, the second dot goes up to athlitikos. Now from there you can access resultregistration and everything underneath.
I think it will work:
from athlitikos.resultregistration.models import Person
resultregistration.models should do it. Just make sure the app is added to the installed apps in your settings.py.
Let's have a django project using a 3rd party application.
I'd like to override some of its modules without touching original files.
Simple subclassing is not possible here, need to override code transparently as many other apps rely on original class names and functions.
Project's structure looks like:
django_project/
__init__.py
settings.py
overrides/ <-- here is a subdir with apps overrides
__init__.py
payment/ <-- here is an example of app to override
__init__.py
admin.py
forms.py <-- this file is ignored, original is imported
models.py
tests.py
views.py
settings.py was modified with
INSTALLED_APPS=(
'satchmo_store.shop'
#'payment' # original values
'overrides.payment' # modified app
...
)
The above solution however does not work, because Django does not insert path of added app into modules search path (sys.path).
Django just loads admin.py, models.py, tests.py and views.py, other files like forms.py are ignored.
Is this behaviour documented somewhere ? What exactly placing a module name in INSTALLED_APPS does behind scenes ?
I hacked the situation with hardcoding new modules search path in manage.py and Apache's setting of WSGIPythonPath.
import os.path
import sys
DIRNAME = os.path.dirname(__file__)
APPS_OVERRIDE = os.path.join(DIRNAME, 'overrides')
if not APPS_OVERRIDE in sys.path:
sys.path.insert(1, APPS_OVERRIDE)
I doubt this is the right way. Cann't find a guide describing apps overriding.
So, how can I properly override external Django application in my project ?
The bonus question: Do I need to copy whole application directory tree, not just particular files which are really modified ? As far as I know, Python stops at first matching module path, so it won't import other modules available in following parts of the search path.
Example of how to override your form:
overrides/payment/forms.py
from django import forms
class YourNewFormThingy(forms.Form): pass
overrides/payment/models.py
from satchmo.payment import forms as satchmo_payment_forms
from . import forms
satchmo_payment_forms.SomeForm = forms.YourNewFormThingy
Try including payment as well along with override.payment as satchmo uses payment module to process payments and payment code is flexible enough to include your code as well.
I have the following project structure:
apps(python package)
|
|
|----------trips(python package)
|----__init__.py
|----urls.py
|----views.py
project
manage.py
urls.py file has the following imports:
from django.conf.urls import patterns, url
from django.contrib.auth.decorators import login_required
from . import views
The app works perfectly fine when running on a local machine (I've made lots of apps like this, so I don't think the mistake is that obvious, but who knows)
When I upload this to a production server (Openshift with python 3), I see Django's debug template, stating an ImportError ocurred:
ImportError at /
cannot import name views
The line of the Exception is:
from . import views
I've tried also:
from apps.trips import views
with no luck...
Any ideas?
Update:
This is my Python path:
Python Path:
['/var/lib/openshift/52a6379ae0b8cd1b10000001/app-root/runtime/repo',
'/var/lib/openshift/52a6379ae0b8cd1b10000001/python/virtenv/venv/lib/python3.3/site-packages/distribute-0.6.49-py3.3.egg',
'/var/lib/openshift/52a6379ae0b8cd1b10000001/python/virtenv/venv/lib/python3.3/site-packages/pip-1.4.1-py3.3.egg',
'/var/lib/openshift/52a6379ae0b8cd1b10000001/app-root/runtime/repo',
'/var/lib/openshift/52a6379ae0b8cd1b10000001/python/virtenv/venv/lib/python3.3/site-packages/psycopg2-2.5.1-py3.3-linux-x86_64.egg',
'/var/lib/openshift/52a6379ae0b8cd1b10000001/python/virtenv/venv/lib/python3.3/site-packages/Django-1.6-py3.3.egg',
'/var/lib/openshift/52a6379ae0b8cd1b10000001/python/virtenv/venv/lib/python3.3/site-packages/django_selectable-0.7.0-py3.3.egg',
'/var/lib/openshift/52a6379ae0b8cd1b10000001/python/virtenv/venv/lib/python3.3/site-packages/django_autocomplete_light-2.0.0a4-py3.3.egg',
'/var/lib/openshift/52a6379ae0b8cd1b10000001/python/virtenv/venv/lib/python3.3/site-packages/six-1.4.1-py3.3.egg',
'/var/lib/openshift/52a6379ae0b8cd1b10000001/python/virtenv/venv/lib/python3.3/site-packages/South-0.8.4-py3.3.egg',
'/var/lib/openshift/52a6379ae0b8cd1b10000001/python/opt/lib/python33.zip',
'/var/lib/openshift/52a6379ae0b8cd1b10000001/python/opt/lib/python3.3',
'/var/lib/openshift/52a6379ae0b8cd1b10000001/python/opt/lib/python3.3/plat-linux',
'/var/lib/openshift/52a6379ae0b8cd1b10000001/python/opt/lib/python3.3/lib-dynload',
'/var/lib/openshift/52a6379ae0b8cd1b10000001/python/virtenv/venv/lib/python3.3/site-packages',
'/var/lib/openshift/52a6379ae0b8cd1b10000001/python/virtenv/venv/lib/python3.3/site-packages/setuptools-0.6c11-py3.3.egg-info',
'/var/lib/openshift/52a6379ae0b8cd1b10000001/python/opt/lib/python3.3/site-packages',
'/var/lib/openshift/52a6379ae0b8cd1b10000001/app-root/runtime/repo/wsgi/hector_transporte']
The last line points to my project folder (the one that contains the apps module). Another strange thing is django seems to be able to find my settings.py
I'm using the python 3 cartridge because "it's the present and future of the language"
Is there a reason you need to use the python 3 cartridge at this time? We have a new one coming out in about 3 weeks that will be more standard. We even have a quickstart for django with the 2.7 cart - github.com/openshift/django-example
I don't see the reference to {python_home}/Lib/site-packages/django. You might try adding that to your path.
ImportError can arise when there is a problem with the module you are importing. In this case, one of the dependences for the views module was missing on the server.