On Aug 15, 6:42 pm, Yuri Baburov <[email protected]> wrote:
> On Sat, Aug 15, 2009 at 12:24 PM, Graham
>
>
>
>
>
> Dumpleton<[email protected]> wrote:
> > On Aug 15, 1:15 pm, Yuri Baburov <[email protected]> wrote:
> >> Hi all,
>
> >> I'm trying to figure out correct overall and settings path usage
> >> strategy for my Django applications.
> >> What I am experiencing now is that settings.py is imported 4 times on
> >> "python manage.py runserver" command,
> >> twice as "settings", and twice as "myapp.settings", given that my
> >> project is named "myapp".
> >> It also doesn't care if I set DJANGO_SETTINGS_MODULE env option and
> >> PYTHONPATH env option.
>
> >> My desire is to make it use "settings", and don't ever use project
> >> prefix "myapp."
>
> > Personally I believe that eliminating the project prefix is a bad
> > idea. By doing that you start to push to much stuff into global module
> > namespace and too much change of a conflict.
>
> Maybe let's rename all apps to UUIDs then? :)
> I have never experienced namespace conflicts you are talking about.
> Chance of conflict is almost zero.
> You underestimate python import agility.
You underestimate stupid users. I have seen many times where users
stuff up because they do something like call a script file django.py
or test.py and wander why the latter standard packages/modules of same
name can't seem to be found, or why their own code isn't found. There
are lots of other standard modules in Python which one can conflict
with as well because of use of quite generic names.
> Only global modules get into global modules namespace, app modules get
> into app namespaces.
You said that your 'desire is to make it use "settings" , and don't
ever use project prefix "myapp."'. To do that, it means that
'settings' has been promoted to global modules namespace.
Django runserver is a pain in that it effectively allows this by
default, and in part why you are seeing the problem you are having in
the first place.
That is, it may add sys.path temporarily to import site package root
into sys.modules so that 'site.settings' works, but the current
working directory of the runserver is the actual site directory. This
means importing 'settings' works as well. That is, 'settings.py' is
importable as both sub module of site package, but as global module in
it is own right. Thus why it can be imported twice. If the runserver
had been implemented to change to a different directory, it would get
rid of this problem and also get rid of the problem where people use
relative path names for stuff which may work for runserver but then
doesn't work when they move to hosting with mod_python, mod_wsgi, or
fastcgi.
> Local modules are checked before global ones. If you will load "q"
> from "w", it will be imported as "q.w" into sys.modules
> Say, realapp1 can have module models.py and can be accessed as
> "models" from inside and "realapp1.models" from outside. Local modules
> will be checked before global from inside, and no name conflict will
> ever arise.
> But most times internal "models" are also accessed as
> "realapp1.models", of course.
> This will work until you will use app as sub-app of some other app
> (say, I want to use django-filter as beautils/filter/ and it will not
> work because it uses filter.* form of imports). Such reuse will be
> possible only with local imports imports.> What I would suggest is
> experimenting with standardising on one prefix
> > and having everything internally reference via that no matter what the
> > project directory is called. You can then set up a dummy module as
> > entry point.
>
> It's just very bad idea to have 2 apps with the same name, but single
> global namespace won't help it!
> Be it project name, or "djangosite".
You possibly don't fully understand why I am suggesting this and how
it would be of use. Maybe the problem is that you are after something
other than the problem I perceive you are trying to solve. You perhaps
also haven't encountered as many times the issues around this double
import and fact that imports can be done without listing site package
root at same time as I have in answering Django questions on the lists
over the years. It is one part of Django I would really like to have
seen be done differently because of the grief it keeps causing people
who want to host with mod_python and mod_wsgi.
FWIW, having all sites use the same logical package root name wouldn't
cause any harm because for Django, it is impossible to host multiple
Django site instances within the same Python interpreter. Thus there
can be no conflict. Some other Python web frameworks also get away
with always effectively having site package root be same name, because
they, like Django can only have one instance in a Python interpreter.
Thus the concept works albeit the means they do it may be different.
One of the problems it would solve is where people leave off the site
package root name because they want the ability to easily copy view
code or other stuff from one Django site to another without having to
change imports within that code. Because runserver current working
directory isn't changed, they unfortunately have the back door, as
they can leave off the site package root name from imports and they
will allow them to migrate code as they want. As explained though,
that results in multiples ways to import the code, ie., problem isn't
just with 'settings.py' but any code within a site. Result is you
sometimes see people having problems with code working strangely and
that is because of double imports of their code.
Anyway, rather than going the direction of aliasing the package name
for site root, you want to get rid of it entirely, meaning that
everything in the site directory in effect is a global module/package
scope.
Graham
> I also use few more techniques:
> I could use "apps/" folder to put my project-specific apps inside if i
> wanted to. Apps will get names like "apps.somename". I tried, for IDE
> to show in better way, but it wasn't really needed :)
>
> And I symlink apps I need into my project directory.
> Typical folder structure in my projects:
> ~django/ -> ../django-trunk/django
> ~beautils/ -> ../beautils
> realapp1/
> templates/
> media/
> media/~admin/ -> ../django-trunk/django/contrib/admin/media
> media/~beautils/ -> ../beautils/media/beautils
> media/~realapp1/ -> ../realapp1/media
> settings.py
> urls.py
>
> I include only apps i needed, maybe that's the reason I don't
> experience conflicts.
> Two conflicts I've got within a year of work with django were "blog"
> app with "blog" project and "utils" app with "utils" module, because I
> left utils.pyc when removed utils.py. I can do nothing with second,
> but first required a hour to find, and not only me, but my friend once
> also get the exactly same problem and would also spent a lot of time
> to find it if he didn't ask me :)
>
> Will manage.py startapp raise an error if a project has the same name
> as application? Will python manage.py validate do so?
>
> And installing django modules into python environment I believe is a bad
> thing,
> mainly because different projects might use different versions of
> applications.
>
> I apply the following general rule here:
> You should be able to update a library or application in one project,
> not breaking others.
>
>
>
>
>
> >> Because this will cause much greater app reusability in different
> >> projects, because of "blog" project and "blog" application possible
> >> import clashes (and weird errors from urlconf loader), because I want
> >> to be able to rename project at any moment, because i want "111" or
> >> "project-v1.1" to be also correct project folders. This is my general
> >> rule: my apps shouldn't start with project prefix.
>
> > So for your example, do the following:
>
> > import imp
> > import sys
> > import os
>
> > djangosite = imp.new_module('djangosite')
> > djangosite.__path__ = [ '/some/path/projects/projects-v1.1' ]
> > djangosite.__file__ = '/some/path/projects/projects-v1.1/
> > __init__.py'
>
> > sys.modules['djangosite'] = djangosite
>
> > os.environ['DJANGO_SETTINGS_MODULE'] = 'djangosite.settings'
>
> > Doing this also means you do not even need the parent projects
> > directory in sys.path, which is effectively what runserver does as it
> > adds it only long enough to import the __init__.py file as package
> > root and then removes the directory.
>
> > Anyway, within urls.py and all your code you could then always perform
> > import references as 'djangosite.etc.etc'. With it standardised, then
> > quite easy to move stuff between site implementations or rename site
> > directory and not have to change everything in it.
>
> And as I explained above, this is not better than "etc.etc"...
> I wish "etc.etc" be standardised :)
> And everything will work even for "project-v1.1" without any dummy packages.
>
> > This does mean that __init__.py in root of Django site package should
> > always be empty, but normally it is anyway.
>
> Well, I don't find any reasons to put anything there.
> You have settings.py and urls.py for that, and they can be reloaded
> easily if needed.
> It's like "we allow you to make your life more painful, that's why
> __init__.py is there".
> But I don't have any problems with it, so let __init__.py be.
>
> > Another thing to consider is creating another dummy module entry point
> > for a directory holding all your reusable applications. This one could
> > be called 'djangoapps' with references always made via that path.
>
> All my applications are "reusable", but not all will be ever reused.
> So I don't understand why I need this folder. I can create a folder
> "djangoapps" instead of the dummy module, if I need to.
> But why should I?
>
> --
> Best regards, Yuri V. Baburov, ICQ# 99934676, Skype: yuri.baburov,
> MSN: [email protected]
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Django developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/django-developers?hl=en
-~----------~----~----~----~------~----~------~--~---