django view/template redirection for mobile browsers - django

Not sure if anyone has had experience with a good solution to rendering templates specifically for mobile devices using django.
I wrote a middleware request processor that uses regex to detect whether it is a mobile browser or not. I am currently setting a boolean attribute on the request so that I can use it further down the pipe. But really my business logic is the same I just want to use a different set of templates.
Is there a way for me to add a new template directory to settings.TEMPLATE_DIRS in the middleware processor, so that a mobile user would get the views I choose to rewrite, but everything else would fall back to the default template directories. But I need to make sure it doesn't persist between requests.
If i added a directory, would settings continue to hold onto it between requests?
..and if so, is this the right solution (checking the browser agent, adding an additional template folder, and then removing it at the end of each request)?

Dynamically modifying the template search path is a great way to handle this. It's not hard to define your own template loader and add it to the TEMPLATE_LOADERS in settings.py. The tricky part of this is handling the fact you may be running in a multi-threaded environment, and you don't have a way to pass your request directly to the template loader.
The way around it is to store the request, a flag, or simply the directories to add to the path in a thread local variable, and reference that thread local variable from a custom template loader. Here's a blog post about creating template loaders, I can vouch for the fact it's pretty easy and works. Here's an even better one about doing exactly what you need.
I guess i didn't specifically point out that you probably do not want to try to change settings.TEMPLATE_DIRS per request, you will get wierd results at best.

Related

Determine which templates are used by which views/ URLs in django

I have a fairly large django project consisting of several individual apps. I am farming out some of the front-end work (CSS, HTML tweaks) to people who aren't over-familiar with django. To that end I'd like to generate a list of templates for each URL pattern any given engineer is working on. This will save much time that would otherwise be spent manually tracking down the templates used during a view's render phase.
For example, if Bob is working on URLs beginning with /accounts/ then I'd like to generate a list of all the templates used by any view that handles requests to those URLs.
My initial thought is to use something in the test framework since that has access to the templates rendered during a request. However, I can't guarantee that all URLs or views will be exercised (sadly I don't have 100% test coverage), and a missed template is unlikely to be noticed. I don't mind writing a set of tests that simply exercise each view, but don't want to duplicate existing efforts. Also certain views require POSTed data or authentication to function correctly - although I suspect that's an issue I'll have to face no matter what approach is used.
Are there any utilities or snippets that will do what I need?
django-debug-toolbar is a must for developing with Django, It includes a panel detailing all templates used during a request.
I've found the SQL panel is the most helpful for improving page load times as it details slow and duplicate queries.
It can slow down requests when enabled, disabling all panels but those that you use helps.

Django project applications division

I'm currently writing django project and got confused when it came to separation into apps. Project consists of posts and categories which are kept in one app, also there is a 'main' app which handles user profile view, login, logout and registration. Now I'm trying to implement user-to-user messages and I'm wondering if it should be kept as separate app.
If Message model is kept in application 'messages' how do I realize show_messages view?
1) It seems that it should be stored in 'main' app since it's linked by my_profile view. It would just get all Message instances form 'messages' app and render template extending profile.html or including from 'messages' app a partial template responsible only for messages listing. But why would I then need separate application just to hold one model there with some helper functions?
2) Secondly I wonder about placing show_messages view in 'messages' app but then I would need to use template which extends template from other application which again seems to be violation of self-containment rule. Also all "accounts/" urls are currently kept in main.urls so I feel wrong about adding "accounts/profile/messages" rule to messages.url.
3) Finally I think about moving Message model with all helpers and templates to 'main' app since messages are designed to work with User models and views therefore forcing additional separation seems useless.
Thanks for reading my thoughts, I'll appreciate all clues and explanations.
When I first started working with Django, I found the answers on this SO question to be particularly helpful, regarding app/project layout: Projects vs Apps
Many of the answers are useful, but this one is particularly pithy:
Try to answer question: "What does my application do?". If you cannot answer in single sentence, then maybe you can split it to several apps with cleaner logic?
I've read this thought somewhere soon after I've stared to work with django and I find that I ask this question my self quite often and it helps me.
Your apps don't have to be reusable, they can depend on each other, but they should do one thing.
Interdependence of apps isn't always problematic. For example, in a lot of my projects I have a separate app that is used solely for creating dynamic menus. In order to work properly, I need to import the specific models of that site into that app -- so I couldn't just drop it into another site, unaltered, and expected it to work. Nonetheless, the other 90% of the code in that app is completely reusable, and it's easier for me to move the relevant code to a new project if its already spun out into a separate app -- even though that app only holds a templatetag and a template.
Ultimately, a django site would technically run just fine with ALL models/views/etc in one big, unwieldy app. But by breaking your project down into "this app performs this specific function" you're probably going make managing your code a lot easier for yourself.
Regarding the 'url' point in 2, there's no reason not to subspace URLs. You are already doing this in a django project already -- mostly likely your main urls.py has an include() to another app, such as your main.urls. There's no reason your main.urls can't also have an include() to your messages app.

getting the template name and the time it takes to render in a middleware based on a url

I want to write a middleware that would tell me the name of the template being rendered and the time it took, for the database queries for that particular view.
Django Debug Toolbar does the same, but due to custom request and response object written i am not able to get that working.
So i thought of writing a custom middleware that would do the same for me on a url appended with some get request variable.
Say 127.0.0.1/index/polls gives me all the polls.
If i try 127.0.0.1/index/polls/?my_tool it would invoke a url, and i would get the data.
Any suggestions on how to implement it? Is there a working example?
I could infer that you need some debug tool for development, in that case I would suggest django-debug-toolbar, otherwise, if you really need the middleware you always can look at the code of django-debug-toolbar. :)
If I´ve got to write that by myself, I would write a couple of classes (in debug toolbar are called panels) that inherits from template and timer, and override the method process_response for log or print the info that I need.
Even you can look into the middleware of debug-toolbar and picture an idea of how it works

Alternate URL router for Django

How would you go about using django models and templates, but not the URL routing system? I'd like to swap out the urls.py system for something like PHP where the URL tells you exactly where the code is that's running. Or maybe something more automagic like rails uses -- where the URL always includes the same components like app name, model name and view name.
I just disagree with the line from the django philosophy statement that "Tying URLs to Python function names is a Bad And Ugly Thing." Pretty URLs just aren't all that important to me, and IMVHO not worth the complexity of climbing through a maze of indirection in multiple urls.py files and dozens of regexes to find out what code runs behind a particular URL. It's a personal choice, right? Django is generally pretty modular allowing you to swap out the major components for other ones. So, how would I swap out the part which takes the request URL and decides which view to run?
Are there any alternate URL routers for django out there?
All you need is one line in your urls.py that matches everything, and then just write your handler/dispatcher as a view. That handler does whatever you want based on the parts of the URL....
I've never heard of anyone successfully swapping out Django's URL routing system. There's certainly no hook for it - core.handlers.base.BaseHandler.get_response calls urlresolvers.RegexURLResolver directly. Conceivably, you could add a middleware at the bottom of the stack that dispatches to your own URL resolution system and returns the response, thus bypassing the Django system, but it's a bit kludgy.
If you're after something more like Rails, you might want to try one of the other frameworks - Pyramid, for example, uses a system of Routes very similar to Rails'. Pyramid is much more pluggable than Django, so you should be able to plug in the Jinja2 templating system, which is based on Django's. However, there's no way to use Django's ORM seperately, so you'd need to use SQLAlchemy (which can be used in a way that's not massively different).

Using the Coldbox framework, is there a way to intercept a renderView call and execute a different template?

I am trying to learn Coldbox to perhaps replace the current framework I am using. One of the features that I currently use is the ability to override any of the template inclusions by convention.
Essentially, lets say I have a view, "views/home.cfm"
<h1>I am the default theme</h1>
and that is all well and good. But lets say that I have a different view, "themes/[theme-name]/views/home.cfm"
<h1>I am the user chosen theme</h1>
that I want to include conditionally (say there is a cookie to determine what theme is in use). Also, if the file does not exist, the default/fallback view should be rendered.
Is there any way of doing this overriding the system functions?
I looked at interceptors, and the preViewRender and postViewRender interceptors seem like the place to do something like this, but there doesn't seem to be any way of manipulating the actual workflow. If seems to be mainly pre/post processing of the content. For instance, there doesn't seem to be a way to "return false" to tell the renderView method to not actually render the view. Or any way to affect the location in which the view is to be found.
Any ideas?
Tyler,
The ColdBox Framework is quite flexible. It is possible to do what you desire but I don't think modifying renderView() is the best way to resolve this--although, you most definitely can.
I would encourage you to create a User Defined Function in the /includes/helpers/ApplicationHelper.cfm file that contains the logic you require. The functions that are added to this helper file are accessible from anywhere in the framework. This would allow you to create a function called "renderSkin()" that contains the logic you need. RenderSkin() would ultimitly call "renderView()" when you finally figured out which template you wanted to render for that user.
Respectfully,
Aaron Greenlee
I would suggest you go with the interceptor route, but change the layout instead of the view.
From the postEvent interceptor you can get the processedEvent key from the interceptData to change the layout.
Otherwise you could just make the check part of the layout page. The layout can the be a switch statement (or a more OO approach) $including the themed layout files as needed. This has the advantage of giving you a chance to emit custom interception points and having common functionality (css, js)