INSTALLED_APPS = InstalledApps(
'django.contrib.auth', # strings will be converted to App()
App('django.contrib.contenttypes'),
App('django.contrib.sessions'),
App('django.contrib.sites'),
App('django.contrib.messages'),
App('django.contrib.admin'),
App('django.contrib.admin', name=‘demo’),
)
- Admin app display name (by .title())
- Admin permissions prefix
- DB table creation prefix
- Dumpdata/Loaddata fixture prefix identifier
- When explicitly set, used to associate models elsewhere in the app structure.
- RelatedObject explicit cross-app identification.
- contrib.contenttypes identification
INSTALLED_APPS = InstalledApps(
App('django.contrib.admin', db_prefix='chewie'),
)
So, I think the big question is how exactly step 2 is accomplished. I
wrote about some of the problems here:
http://alexgaynor.net/2010/mar/28/towards-application-objects-django/,
the issue is how do you install multiple apps with different
db_prefixes (for example), do you copy.copy() the Model class and
alter the attribute, and when you import one of them, which version do
you get?
I think a lot more detail is needed here.
Alex
--
"I disapprove of what you say, but I will defend to the death your
right to say it." -- Voltaire
"The people's good is the highest law." -- Cicero
"Code can always be simpler than you think, but never as simple as you
want" -- Me
* Assume an app1 which requires another app2 (and has some
ForeignKeys to it). Currently that's easy; just import the model and
ForeignKey it. How would those imports look like in your case (eg to
which models would app1 link)?! [This problem could be solved by
adding an app column to the models and patch all queries to just
select from the current app. And yes alex's link covers that, but a
reuseable app doesn't know to which app (instance) it will get linked
-- yet another setting to the rescue; ah no a whole dict of settings,
to specify which app instance the setting belongs to…]
* What happens to login procedures etc? Eg one of the auth
middlewares would stick an user object onto request.user and most of
the apps won't be able to link to it, as their foreign keys point to
the wrong instance of the auth app.
While I am more than happy to see improvements in the app loading area
(customisable names etc…), I don't like the idea of multiple instance
deployments like you/alex propose (especially if that means the same
set of models being installed twice/trice…; I however do like the way
the admin takes).
Cheers,
Florian
Strings will be converted to App()... by What? When?
What happens to existing code that is using "for app in INSTALLED_APS"
as an idiom?
> App('django.contrib.contenttypes'),
> App('django.contrib.sessions'),
> App('django.contrib.sites'),
> App('django.contrib.messages'),
> App('django.contrib.admin'),
> App('django.contrib.admin', name=‘demo’),
> )
>
> The InstalledApps and App classes will be added to core.apps. The
> db.models.loading module will be deprecated and redirect to core.apps.
Is there a specific reason for this move? Is it just shuffling
deckchairs, or is there a purpose behind the move?
I agree with Alex - there's a lot more detail needed here. How will I
get access to the App instance that a model belongs to? How will
legacy attributes like db_prefix be proxied? What is the order of
precedence when a model and an app disagree on db_prefix?
For the record - I don't think the "multiple versions of a single app"
problem is one worth solving. I'm not even convinced it can be solved
at all, for all the reasons Florian identified, and then some.
Although it may have been part of the original use case for #3591,
much of that use case has since been replaced by namespaced URLs and
class-based applications. If you're going to tackle this problem, I'd
rather see you concentrate on issues like:
* Translating application names
* Solving the "two applications called auth" problem
* Providing configurability for db-level naming convention at the
deployment level (e.g., so you can override db_prefix and table names
when you deploy an app)
* Providing configurability for 'app level' settings; for example,
when deploying contrib.comments, setting the name of the model that
will be used for content.
> Step 3
> ---------
> The current app loading implementation in Django was designed to load model
> classes. However, there are many applications which just provide
> templatetags or management commands and don’t use Django’s ORM at all. These
> applications have to ship with an empty models.py file in order to be loaded
> correctly. The goal of Step 3 is to make it possible to load applications
> without a models.py file.
I would have thought this step would have been a logical consequence
of Step 1; if you're going to massively rewrite app loading, it would
seem unusual to embed all the old problems in your rewrite.
Yours,
Russ Magee %-)
This is already done by the #3591 patch, in
django.db.models.loading.py.
> What happens to existing code that is using "for app in INSTALLED_APS"
> as an idiom?
>
The #3591 patch does this by replacing settings.INSTALLED_APPS with
get_installed_app_paths, which obviously wouldn't work for 3rd party
code out in the wild. ISTM that to keep things backward-compatible,
you need two lists - INSTALLED_APPS and an internal list of App()
instances. You could for instance allow users to specify a mixture of
strings and App instances in settings.INSTALLED_APPS, and once the
loading has happened, this list would contain only strings, whereas an
internal list would contain only App instances and be accessed via a
new function such as get_installed_apps().
> > App('django.contrib.contenttypes'),
> > App('django.contrib.sessions'),
> > App('django.contrib.sites'),
> > App('django.contrib.messages'),
> > App('django.contrib.admin'),
> > App('django.contrib.admin', name=‘demo’),
> > )
>
> > The InstalledApps and App classes will be added to core.apps. The
> > db.models.loading module will be deprecated and redirect to core.apps.
>
> Is there a specific reason for this move? Is it just shuffling
> deckchairs, or is there a purpose behind the move?
>
If apps are to have first-class-citizen status, then this I suppose
would serve to emphasize that status, but other than that I'm not sure
it's necessary.
>
> I agree with Alex - there's a lot more detail needed here. How will I
> get access to the App instance that a model belongs to? How will
> legacy attributes like db_prefix be proxied? What is the order of
> precedence when a model and an app disagree on db_prefix?
>
Agreed that a more detailed specification is required, but wouldn't at
least some of that detailing be part of the actual GSoC work?
> For the record - I don't think the "multiple versions of a single app"
> problem is one worth solving. I'm not even convinced it can be solved
> at all, for all the reasons Florian identified, and then some.
I agree, but IIRC it was quoted as one reason why this feature was
left out of the running in the recent Django revisions. It doesn't
make a lot of sense to me for any app where models are concerned, and
I believe there would be no point in duplicating the models for
multiple instances of an app.
> Although it may have been part of the original use case for #3591,
> much of that use case has since been replaced by namespaced URLs and
> class-based applications. If you're going to tackle this problem, I'd
> rather see you concentrate on issues like:
Class-based applications? Can someone point me to some of those?
Googling for "django class-based applications" doesn't throw up
anything.
> * Translating application names
This is handled in the #3591 patch AFAIK.
> * Solving the "two applications called auth" problem
> * Providing configurability for db-level naming convention at the
> deployment level (e.g., so you can override db_prefix and table names
> when you deploy an app)
> * Providing configurability for 'app level' settings; for example,
> when deploying contrib.comments, setting the name of the model that
> will be used for content.
>
> > Step 3
> > ---------
> > The current app loading implementation in Django was designed to load model
> > classes. However, there are many applications which just provide
> > templatetags or management commands and don’t use Django’s ORM at all. These
> > applications have to ship with an empty models.py file in order to be loaded
> > correctly. The goal of Step 3 is to make it possible to load applications
> > without a models.py file.
>
> I would have thought this step would have been a logical consequence
> of Step 1; if you're going to massively rewrite app loading, it would
> seem unusual to embed all the old problems in your rewrite.
>
I think that would all come out in the wash; for example the #3591
patch doesn't require a models.py, and the app instance has slots for
two modules: the app package itself and the models sub-package or
module within it. It should be very easy to handle the case of an app
with no models.
Regards,
Vinay Sajip
It's fair to assume that there will always be *some* details that are
worked out as part of the GSoC work. My intention isn't to try and
nail down all the details before the project starts - it's to try and
work out how much Arthur has thought about the problem, and how well
he can communicate what he is thinking.
The GSoC application process is a lot like a job interview. Although
Django itself isn't paying the stipend to students, we are going to
commit a lot of resources to mentoring a student. As a result, we
aren't going to take on students just to make up the numbers. Asking
questions like this one allows me to kill 3 birds with 1 stone - I get
to improve the design, *and* I get to see the design skills of the
prospective student in action, *and* I get to see how well the
prospective student is able to communicate those designs to the wider
community.
>> For the record - I don't think the "multiple versions of a single app"
>> problem is one worth solving. I'm not even convinced it can be solved
>> at all, for all the reasons Florian identified, and then some.
>
> I agree, but IIRC it was quoted as one reason why this feature was
> left out of the running in the recent Django revisions. It doesn't
> make a lot of sense to me for any app where models are concerned, and
> I believe there would be no point in duplicating the models for
> multiple instances of an app.
Not to my reading. The reason for rejection at official voting has
always been "incomplete design". I can see that the subject of
multi-deployed apps has come up in the past, but it's also been
identified as a *hard* problem, and possibly one that doesn't need
solving. Unless someone can provide a particularly compelling use
case, I'm inclined to put it on the ignore pile.
>> Although it may have been part of the original use case for #3591,
>> much of that use case has since been replaced by namespaced URLs and
>> class-based applications. If you're going to tackle this problem, I'd
>> rather see you concentrate on issues like:
>
> Class-based applications? Can someone point me to some of those?
django.contrib.admin is the most notable example.
Yours,
Russ Magee %-)
Having tried to solve this problem myself a while ago, I agree -- multiple app instances are out of scope of the summer of code.
Jannis
Seems eminently sensible to me :-)
> >> For the record - I don't think the "multiple versions of a single app"
> >> problem is one worth solving. I'm not even convinced it can be solved
> >> at all, for all the reasons Florian identified, and then some.
>
> > I agree, but IIRC it was quoted as one reason why this feature was
> > left out of the running in the recent Django revisions. It doesn't
> > make a lot of sense to me for any app where models are concerned, and
> > I believe there would be no point in duplicating the models for
> > multiple instances of an app.
>
> Not to my reading. The reason for rejection at official voting has
> always been "incomplete design". I can see that the subject of
> multi-deployed apps has come up in the past, but it's also been
> identified as a *hard* problem, and possibly one that doesn't need
> solving. Unless someone can provide a particularly compelling use
> case, I'm inclined to put it on the ignore pile.
>
Agree - and the incompleteness of the design was IIRC (and perhaps I
don't) partly because it didn't address the multiple app instances
issue. That's one of the issues mentioned in
http://code.djangoproject.com/wiki/InstalledAppsRevision
and that page was referred to as containing what needed to be
addressed in a viable design.
>
> > Class-based applications? Can someone point me to some of those?
>
> django.contrib.admin is the most notable example.
>
Oh right, I thought you were talking about something else :-)
Regards,
Vinay Sajip
So shortly do you imply that the "app loading" problem is indeed the
problem of integrating several application via db tables through
configuration in deployment?
--
Dagvadorj GALBADRAKH
On Mon, Apr 5, 2010 at 5:35 AM, Arthur Koziel <art...@arthurkoziel.com> wrote:Hi,I’m going to apply for GSoC with the goal of refactoring the app loading[0]. I’ve been looking at Django’s current app loading implementation(db.models.loading), Vinay Sajip’s patch in #3591 [1] and the notes on theInstalledAppsRevision wiki page [2]. Here's what I'm planning to change. Anyfeedback is appreciated.Step 1---------Deal with the two main problems of the current app loading implementation,and make it possible to:- deploy several instances of the same app- deploy two apps with the same nameThe INSTALLED_APPS setting will be changed to:INSTALLED_APPS = InstalledApps('django.contrib.auth', # strings will be converted to App()
Strings will be converted to App()... by What? When?
What happens to existing code that is using "for app in INSTALLED_APS"
as an idiom?
App('django.contrib.contenttypes'),App('django.contrib.sessions'),App('django.contrib.sites'),App('django.contrib.messages'),App('django.contrib.admin'),App('django.contrib.admin', name=‘demo’),)The InstalledApps and App classes will be added to core.apps. Thedb.models.loading module will be deprecated and redirect to core.apps.
Is there a specific reason for this move? Is it just shuffling
deckchairs, or is there a purpose behind the move?
Step 3---------The current app loading implementation in Django was designed to load modelclasses. However, there are many applications which just providetemplatetags or management commands and don’t use Django’s ORM at all. Theseapplications have to ship with an empty models.py file in order to be loadedcorrectly. The goal of Step 3 is to make it possible to load applicationswithout a models.py file.
I would have thought this step would have been a logical consequence
of Step 1; if you're going to massively rewrite app loading, it would
seem unusual to embed all the old problems in your rewrite.
Yours,
Russ Magee %-)
> On Mon, Apr 5, 2010 at 5:35 AM, Arthur Koziel <art...@arthurkoziel.com> wrote:
>> Hi,
>> I’m going to apply for GSoC with the goal of refactoring the app loading
>> [0]. I’ve been looking at Django’s current app loading implementation
>> (db.models.loading), Vinay Sajip’s patch in #3591 [1] and the notes on the
>> InstalledAppsRevision wiki page [2]. Here's what I'm planning to change. Any
>> feedback is appreciated.
>> Step 1
>> ---------
>> Deal with the two main problems of the current app loading implementation,
>> and make it possible to:
>> - deploy several instances of the same app
>> - deploy two apps with the same name
>> The INSTALLED_APPS setting will be changed to:
>>
>> INSTALLED_APPS = InstalledApps(
>> 'django.contrib.auth', # strings will be converted to App()
>
> Strings will be converted to App()... by What? When?
>
> What happens to existing code that is using "for app in INSTALLED_APS"
> as an idiom?
I'm worried that creating the app instances with an ``app()`` callable would require an import and contradicts with the convention of having dotted paths for any configurable extension. That's why I think INSTALLED_APPS should be kept as an iterable of dotted paths which is converted to an app registry during the start-up (which already happens for wildcard entries like "django.contrib.*"). Each entry of the list would be a string with one of the following values:
- Dotted path to an app module (current default, e.g. 'django.contrib.auth'). During the start-up an anonymous app instance would be initialized, using the models module of the loaded app module.
- Dotted path to an app class (e.g. 'django.contrib.auth.AuthApp'). During the start-up a named app instance would be created, either with the models module of the module the app class is located in, the model attribute of the class or none (model-less app).
- Dotted path to an app instance (e.g. 'django.contrib.admin.site'). During the start-up an existing app instance would be handled like it has been loaded in one of the former two cases.
Iterating over the INSTALLED_APPS setting would still be supported given the fact each app instance has it's own label that sets its models db_prefix, so the check for a custom app would be:
if "acme.auth" in INSTALLED_APPS:
# do something
An app class could look like this:
from django.contrib import auth
from django.conf.urls.defaults import patterns
from django.utils.translation import ugettext_lazy as _
class AcmeAuthApp(auth.AuthApp):
label = 'acme' # sets the db_prefix
models = auth.models
verbose_name = _('acme auth')
def get_urls(self):
return patterns('acme.auth.views',
url(r'^login/$', 'login', name="acme_auth_login"),
)
Jannis
I agree with Alex - there's a lot more detail needed here. How will I
get access to the App instance that a model belongs to? How will
legacy attributes like db_prefix be proxied? What is the order of
precedence when a model and an app disagree on db_prefix?
For the record - I don't think the "multiple versions of a single app"
problem is one worth solving. I'm not even convinced it can be solved
at all, for all the reasons Florian identified, and then some.
Although it may have been part of the original use case for #3591,
much of that use case has since been replaced by namespaced URLs and
class-based applications. If you're going to tackle this problem, I'd
rather see you concentrate on issues like:
* Translating application names
* Solving the "two applications called auth" problem
* Providing configurability for db-level naming convention at the
deployment level (e.g., so you can override db_prefix and table names
when you deploy an app)
* Providing configurability for 'app level' settings; for example,
when deploying contrib.comments, setting the name of the model that
will be used for content.
I'm afraid I don't even understand the question.
The app loading problem is potentially many things. The list of bullet
points I gave is an indication of a working subset of those problems
that I think is worth pursuing for GSoC.
Yours,
Russ Magee %-)
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.admin',
'foo.gsoc',
('foo.gsoc', 'taiwan', {'verbose_name': _('GSoC'), \
'lang': 'zh-TW', \
'name': 'gsoc_tw', \
'db_prefix': 'gsoctw_', \
'skin': 'orient'}),
)
So that app-level configuration would have been satisfied:
Internationalization of the app name in admin, differentiated db
prefices, default highlighting language for the app, etc.
Every existence of an app will be defined as namespace URL in the
code, thus no app with duplicate name. For instance: 'foo.gsoc' is
named 'foo.gsoc' and models are accessed as 'from foo.gsoc.models
import Idea', while '('foo.gsoc', 'taiwan', ..)' would be named as
'foo.gsoc.taiwan' if 'name' in dict is not existent, and like
'gsoc_tw' if 'name' attribute exists. Maybe 'name' and 'db_prefix'
would be associated.
Integration of a model with another model in a different app would be
simpler, since everything is namespace-based:
class Idea(models.Model):
title = models.CharField(max_length=200)
description = models.CharField(max_length=200)
organization = models.ForeignKey(foo.gsoc.models.Organization,
to_field='name') # notice full path
> Russell Keith-Magee <freakboy3...@gmail.com>
> wrote:
>> Providing configurability for 'app level' settings; for example,
>> when deploying contrib.comments, setting the name of the model that
>> will be used for content.
In addition, yet most important, the extra dict (attributes) in the
tuple declaration of an app in INSTALLED_APPS will be stored in a
module like 'foo.gsoc.ATTR', so that the application itself can
access, hence providing a dynamic (configured app-level, rather than
hard-coded in a model) app-level configuration.
> --
> You received this message because you are subscribed to the Google Groups "Django developers" group.
> To post to this group, send email to django-d...@googlegroups.com.
> To unsubscribe from this group, send email to django-develop...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/django-developers?hl=en.
>
>
--
Dagvadorj GALBADRAKH
May I have few questions.
1) And what if foo.gsoc has taiwan submodule already?
2) How will module know what name(s) it has got?
3) How will different application names to be referenced from outside?
3) How will different application names to be loaded from outside?
I believe, the only way is to have a module for each application copy.
so you've got:
conf/gsoc.py
class App():
option1 = 'value1'
modules = 'apps.gsoc'
etc.
conf/taiwan.py:
import gsoc
class App(gsoc.App):
option1 = override
--
Best regards, Yuri V. Baburov, ICQ# 99934676, Skype: yuri.baburov,
MSN: bu...@live.com
On Thu, Apr 8, 2010 at 3:15 PM, bur...@gmail.com <bur...@gmail.com> wrote:
>
> May I have few questions.
> 1) And what if foo.gsoc has taiwan submodule already?
There will be certain conventions on which names not to use as an
instance name such as, views, models, etc. Plus, Django can check if a
module with the same name exists during deployment. And also, new
instances can be stored in a special module called 'clone' for
instance, hence, 'foo.gsoc.clone.taiwan'.
> 2) How will module know what name(s) it has got?
Can be stored in dict in AppCache
> 3) How will different application names to be referenced from outside?
> 3) How will different application names to be loaded from outside?
The apps and its modules will be referenced by its namespace (path - virtual).
--
Dagvadorj GALBADRAKH
>> 2) How will module know what name(s) it has got?
>
> Can be stored in dict in AppCache
>
>> 3) How will different application names to be referenced from outside?
>> 3) How will different application names to be loaded from outside?
>
> The apps and its modules will be referenced by its namespace (path - virtual).
I believe you don't quite understand all the problems,
so i'll add more details here.
I repeat fragments of Flo's post nobody has answered yet:
Assume an app1 which requires another app2 (gsoc in your case), and has some
ForeignKeys to it. Currently that's easy; just import the model and
ForeignKey it. How would those imports look like in your case (eg to
which models would app1 link)?!
Also, will app2copy (taiwan in you case) have different models than app2 (gsoc)?
(The same for views working with these models etc)
We don't have currently a way application's view knows about what
instance they work with.
This is a critical issue, and nobody yet suggested proper solution for that.
All that both of you can suggest us now is "I am suitable to make a
patch in an hour that will make multiple app copies work sometimes"
approach.
You need to question yourself about all possible problems.
And write your solutions to them.
Not wait when we will ask you those questions.
Because all those questions are already in this google group (not only
this thread).
Read all related topics, write questions, answer them.
And then come to us with a proposal.
I'm sure both of you can qualify if you do this.
Agreed. Starting down the path of requiring imports in the settings
file isn't something I'd like to encourage.
> That's why I think INSTALLED_APPS should be kept as an iterable of dotted paths which is converted to an app registry during the start-up (which already happens for wildcard entries like "django.contrib.*"). Each entry of the list would be a string with one of the following values:
>
> - Dotted path to an app module (current default, e.g. 'django.contrib.auth'). During the start-up an anonymous app instance would be initialized, using the models module of the loaded app module.
>
> - Dotted path to an app class (e.g. 'django.contrib.auth.AuthApp'). During the start-up a named app instance would be created, either with the models module of the module the app class is located in, the model attribute of the class or none (model-less app).
>
> - Dotted path to an app instance (e.g. 'django.contrib.admin.site'). During the start-up an existing app instance would be handled like it has been loaded in one of the former two cases.
I like this; although I think it has some potential to cause a whole
different bunch of headaches. At the moment, "for app in
settings.INSTALLED_APPS" is guaranteed to give you a list of app
names; identifying the difference between an app module, and app class
and an app instance isn't going to be trivial from the point of view
of an end developer -- since, at the end of the day, they're all just
strings.
Yours,
Russ Magee %-)