On Fri, Apr 9, 2010 at 3:41 AM, burc...@gmail.com <burc...@gmail.com> wrote: > > Hi Nick, > > I don't like your application creation syntax (why using dict-based > DSL instead of class-based?), but > I like how you approach the overall problem. > More than that, you have shown you do understand all the problems > you're going to solve, and that you have design skills required for > solution. > But I believe you can do even further with your proposal. > > You said: > >Model classes will get a ``_meta.app`` attribute, which will be an instance > of the model's ``Application`` class. Models should only be associated with > one > application. > This is very nice idea, and I think, it allows to come with further > design of how should multiple app copies work. > I don't want to push on you, or suggest a working solution, so I'd > like to see your ideas.
Multiple app copies is quite a bit more difficult, unless you assume (like the admin) that they use the same database table. Then I guess you could store multiple application instances in Model._meta.app and use url namespacing to differentiate applications/views. > > I've got questions that might help: > * how will views know about their current application? Views implemented in views.py wouldn't necessarily need to know about their current application, but if they did, you could use get_app("my_app") in the view itself. Views implemented on the Application itself wouldn't have this problem. > * how will views get their app settings after your changes? For settings still in settings.py, just the same as always. For settings implemented in an Application itself maybe something like: # views.py def view(request): api_key = get_app("my_app").options.api_key # do stuff and for views in an Application: def view(self, request): api_key = self.options.api_key # do stuff > * is it a good idea to make urls properties (namespace, app_name) > correspond with the same application properties? That would help for the case of multiple application instances, but for the time being isn't strictly necessary. Probably not a bad idea to promote. > > Currently options are either "from django.conf import settings", and > those settings are singleton with configuration options, or put into > urls. > > Should we say "go away" to view-as-a-function and go to rails-like > controllers like your Application class? I don't think I necessarily want to force people to do that, but rather make things easier to be done like that. View-as-a-function still works well for simple setups. > > (I'm for this option actually, all views other than "hello world" > always take such a bloat of configuration options right now that needs > to be put into controllers anyway -- look at django.contrib.auth.views > for example!) > > (Completely unrelated note, but I'd rather see a url routing right > near those views definition after update. because, 98% of times, you > won't need urls at all!) That would be pretty nice, you could do something like: # urls.py from django.conf.urls.defaults import * from django.core.apps import get_app urlpatterns = patterns('', (r'^blog/', include(get_app("blog").urls)), ) > > Please also see the thread > http://groups.google.com/group/django-developers/browse_thread/thread/4cca2086dd485879?hl=en, > there's a question you avoided delicately, about what to do with > ForeignKey. It might also help. As far as I see that, it's more about what to do when you have two instances of the same application, which I won't be attempting to solve. With just a single instance, models work just the same as they always have (save for the _meta.app) stuff. Thanks for the feedback. > > On Thu, Apr 8, 2010 at 7:33 PM, Nick Sandford <nick.sandf...@gmail.com> wrote: > > An App Loading mechanism for Django > > ==================================== > > > > About Me > > ---------- > > Hi everyone, > > > > My name is Nick Sandford, I'm an electrical engineering student at the > > University of Western Australia. > > > > Background > > ----------- > > > > I haven't been a particularly active contributor to any open source project > > - > > here is where I hope to change that. In my current work at Christ > > Church Grammar School we use Django heavily for most of our internal > > projects. I've > > followed django-dev closely for a couple of years and I have poked around > > with > > its internals on various occasions. > > > > Plan > > ----- > > > > Implement an improved application loading mechanism into Django. > > > > Rationale > > --------- > > > > Django current application loading code is inflexible in many cases. There > > exists a need for a number of extra features to be added to the way > > applications are handled such as: > > > > * The ability to internationalise application names. > > * The ability to customise application names similar to ``verbose_name`` in > > ``model._meta`` > > * Deploy the same application multiple times in a single project. > > * Deploy two different applications with the same name. > > * Manage settings within applications. > > > > Method > > ------- > > > > I don't intend to solve the third dot point of the previous list - it seems > > like a difficult problem, possibly to be tackled post-GSoC. What I do intend > > to do is to move towards 'application classes' more akin to > > ``django.contrib.admin``. > > > > New syntax in ``settings.INSTALLED_APPS`` will be introduced to address the > > previous issues. Some examples of accepted syntax: > > > > .. sourcecode:: python > > > > INSTALLED_APPS = ( > > 'django.contrib.auth', > > app('blog.BlogApplication', 'blog_1', 'My blog', 'app1_'), > > app('blog.BlogApplication', 'blog_2', 'Some other blog', 'app2_'), > > app(path='tagging.Tagging', verbose_name='My tagging application'), > > app('categories', db_prefix='cat_'), > > app({'path': 'django.contrib.admin.AdminApplication', > > 'label': 'admin', > > 'verbose_name': 'Secret Admin'}), > > ) > > > > The ``app`` function will take four arguments, three of which are optional. > > These are ``path``, ``label``, ``verbose_name``, and ``db_prefix``. It will > > return an instance of an ``Application`` object, which will contain all of > > an > > installed application's information. ``path`` will be the dotted path to a > > subclass of ``Application``. The downside is that ``settings.py`` requires > > an import, which may be against style rules. > > > > .. sourcecode:: python > > > > def app(path, label=None, verbose_name=None, db_prefix='') > > if not path or not isinstance(path, basestring): > > raise ImproperlyConfigured('Application path must be string.') > > application_class = import_module(path) > > return application_class(path, label, verbose_name, db_prefix) > > > > ``INSTALLED_APPS`` will then be a tuple containing strings or > > ``Application`` > > instances. The application loading code will iterate over ``INSTALLED_APPS`` > > and construct an internal cache of ``Application`` instances to be used with > > ``get_models``, etc. For backwards compatibility, if an element of the > > tuple is > > a string, an instance of a base ``Application`` class will be created with > > sane > > defaults (similar to ``app_label`` at the moment). > > > > The ``Application`` class will be very similar to ``django.contrib.admin``'s > > ``AdminSite`` and will hopefully simplify application settings. If you write > > views and urls directly on the ``Application`` class itself, instead of an > > ``from django.conf import settings`` and subsequent ``settings.API_KEY``, > > you > > could just reference ``self.api_key`` for instance. This wouldn't be the > > required, just an optional extra. > > > > Model classes will get a ``_meta.app`` attribute, which will be an instance > > of the model's ``Application`` class. Models should only be associated with > > one > > application. > > > > I agree with moving ``django.db.models.loading`` to ``core.apps``, since > > we'll > > no longer require applications to have a ``models.py``. A reference to the > > new functions in ``core.apps`` will still live in > > ``django.db.models.loading`` > > for backwards compatibility. > > > > A subclass of ``Application`` might look like: > > > > .. sourcecode:: python > > > > from django.views.simple import direct_to_template > > from djang.core.apps import Application > > from blog.models import Entry, Category > > > > class BlogApplication(Application): > > models = [Entry, Category] > > api_key = 'default' > > > > def entry_detail(self, slug, request, > > template_name='blog/entry_detail.html'): > > entry = get_object_or_404(Entry, slug=slug) > > context = { > > 'entry': entry, > > 'api_key': self.api_key, > > } > > return direct_to_template(request, template_name, context) > > > > Hurdles > > -------- > > > > There are a list of possible technical issues: > > > > * Introducing the new ``app`` function requires an import in settings.py > > which might not be acceptable behaviour. > > * Two applications with the same label. > > * Worrying amounts of things that may affect backwards compatibility would > > probably need addressing. > > > > Solutions > > ---------- > > > > We could alternatively introduce a new file into the project, > > ``applications.py`` which contains purely application-related setup. This > > might > > be handy to manage application settings and to ensure ``settings.py`` > > doesn't > > get too full of application-specific settings. This could allow us do > > something > > like: > > > > .. sourcecode:: python > > > > from django.core import apps > > from blog import BlogApplication > > > > class MyBlogApplication(BlogApplication): > > api_key = 'testing' > > > > another_blog = BlogApplication(label='blog2', > > verbose_name=_('Another blog'), > > api_key='anothertest') > > > > apps.register(MyBlogApplication, label='blog', verbose_name=_('My blog')) > > apps.register(another_blog) > > > > depending on what people would like more. This could allow us not to touch > > ``settings.INSTALLED_APPS`` at all. > > > > To solve the 'two applications named auth' problem, the ``AppCache`` keeps > > track of application instances, not ``app_label``. For the case of two > > applications with the same name, ``get_app`` should return a tuple > > containing > > both application instances with that name. To ensure a single application > > instance is returned with ``get_app``, another argument - ``path`` should be > > added. ``get_models`` and ``get_model`` would take an application instance > > and return models on that instance. This might affect the admin's handling > > of > > applications. > > > > > > Timeline > > --------- > > > > 1) Implement the ``Application`` class. -- 2 weeks > > 2) Move ``django.db.models.loading`` to ``django.core.apps`` and refactor > > ``get_app``, ``get_model``, etc. -- 1 week > > 3) Modify the admin, management, translation, templatetags, templateloaders > > to use ``app.path`` -- 1 week > > 4) Testing and documentation -- 3 weeks > > 5) Bug fixes and backwards incompatibility problems -- 1 week > > 6) Time permitting possibly tackle the multiple instances of the same app > > problem. (about 2 weeks). > > > > Any feedback would be greatly appreciated, sorry for the late application > > and > > good luck to all the other applicants :) > > > > Thanks, > > Nick > > > > -- > > You received this message because you are subscribed to the Google Groups > > "Django developers" group. > > To post to this group, send email to django-develop...@googlegroups.com. > > To unsubscribe from this group, send email to > > django-developers+unsubscr...@googlegroups.com. > > For more options, visit this group at > > http://groups.google.com/group/django-developers?hl=en. > > > > > > > > -- > Best regards, Yuri V. Baburov, ICQ# 99934676, Skype: yuri.baburov, > MSN: bu...@live.com > > -- > You received this message because you are subscribed to the Google Groups > "Django developers" group. > To post to this group, send email to django-develop...@googlegroups.com. > To unsubscribe from this group, send email to > django-developers+unsubscr...@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/django-developers?hl=en. > -- You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to django-develop...@googlegroups.com. To unsubscribe from this group, send email to django-developers+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-developers?hl=en.