Django: calling DB queries from a template - django

I've got a Django site that has a sidebar with a variety of different boxes that could go in it depending on the page. For example, "Most recent comments" or "Latest tweets" or "Featured story." These boxes all require database queries to run.
I could simply add a most_recent_comments and whatever other variable are needed to the View for each page. But this feels brittle. I'd like to be able to move and change boxes just by editing the templates.
So my other thought was I could add all the variables that all the boxes might need to every page with a Context Processor, but is the ORM smart enough to only run the queries for pages that actually use those variables? Or is it going to hit the database even if I have no boxes on a page?
So what I think I want is some kind of custom tag where I could just say {% most_recent_comments_box %} and it would be smart enough to load whatever variables it needs from the database and then call a little template file. Is this the right approach? How do I accomplish that?

This is the use case for custom template tags. Read this article (written by one of the people behind Django).
One addition to Django since that article was written is the inclusion tag shortcut, which implements the "call a little template file" approach you mention.

So my other thought was I could add all the variables that all the boxes might need to every page with a Context Processor, but is the ORM smart enough to only run the queries for pages that actually use those variables? Or is it going to hit the database even if I have no boxes on a page?
Yes, the ORM will be smart enough to do that. Django QuerySets are lazy: https://docs.djangoproject.com/en/dev/topics/db/queries/#querysets-are-lazy

Related

Dynamic templates with Django and Ajax

My question is a bit generic in that my problem is a broad one. I have been working with django for some time, and I really want to move more into doing very dynamic web pages where actual page reloads aren't common.
I have read about the different popular javascript frameworks available, and I always feel like I am missing part of the puzzle, particularly in templating.
What are some of the best practices for keeping my templating code as non redundant as possible. I get the impression that a lot of templating logic will make it's way into the JS in addition to my django templates. I want to avoid situations where I am writing templating code in two different places.
For a very basic example, let's say I am writing some template code inside Django for an input field that has a set number of attributes. I have then also written in JS that when I click on a button, another input field of the same type is generated with all the appropriate attributes. In practice this could be a form that takes an arbitrary amount of e-mail addresses. The problem I see is that when I want to change something about that input field, I need to do it in two places.
Is there a particular development paradigm or work flow that I am unaware of? How are issues like this generally avoided?
Recommendations on frameworks would be amazing too!
as you mentioned above:
Use Django Template language. Pass the data from view to template dynamically.
Read Django Template Language documentation.
For JS :
its better to write your js in home.html.... use {% include %} tag for other html

Writing translatable static web pages using Django

I am a bit confused on the best way to handle this problem:
My web site needs read-only static web pages (typically the About part of a web site) with 2 simple constraints:
they need to be translated
they need to have flexible layout: to incorporate base headers/footers, floating images and/or tables, and non-interactive elements (like a bootstrap carousel).
Several solutions that I have thought about:
I can of course directly write HTML files but the translation part will be awkward (a lot of <h1>, <ul>, <li> and <p> which are of no interest to the translator).
I can use Django flatpages with some markup languages but I lose a lot of flexibility (for instance template tags are not recognized)
Use generators like Hyde, but it seems quite overkill for my needs and internationalization seems a bit difficult
Does someone have other propositions that I can look into ?
Thanks !
Use django-cms, it has a Page model that can be translated and has a very smart plugin system to add many content-types into every page.
I use it a lot and it's very easy and yet powerful
For completeness and fairness, here's a full list of available CMS packages for Django.
for a much simpler solution, I would create a model called "Page" with lets say title and text fields.
The title and the text fields I would register to django-modeltranslation which will handle the translation issue.
For the text field i would use TinyMCE which let you insert basically any HTML you want so you can do whatever you need.

Django - Static content display based on URL

I'm working on a Django site with a basic three column design. Left column navigation, center column content and right column URL specific content blocks.
My question is about the best method of controlling the URL specific content blocks in the right column.
I am thinking of something along the lines of the Flatpages app that will make the content available to the template context if the URL matches a pre-determined pattern (perhaps regex?).
Does anyone know if such an app already exists?
If not, I am looking for some advice about the best way to implement it. Particularly in relation to the matching of patterns to the current URL. Is there any good way to re-use parts of the Django URL dispatcher for this use?
Django CMS is a good suggestion, it depends on how deep you want to go. If this is just the beginning of different sorts of dynamic content you want then you should go that way for sure.
A simple one-off solution would be something like this:
You would just need to write a view and add some variables on the end of the URL that would define what showed up there. Depending on how fancy you need to get, you could just create a simple models, and just map the view to the model key
www.example.com/content/sidecontent/jokes/
so if "jokes" was your block of variable sidecontent (one of many in your sides model instances) the urls.py entry for that would be
(r'^content/sidecontent/(?P<side>)/$,sides.views.showsides),
and then in your sides app you have a view with a
def showsides(request, side):
Sides.objects.get(pk=side)
etc...
For something like this I personally would use Django CMS. It's like flatpages on steroids.
Django CMS has a concept of Pages, Templates, and Plugins. Each page has an associated template. Templates have placeholders where you can insert different plugins. Plugins are like mini-applications that can have dynamic model-based content.
Although Django-CMS is an interesting suggestion, there are quite a few projects that do specifically what you've requested - render blocks of content based on a URL. The main one that I know about is django-flatblocks.

Controller logic and template logic, where do you draw the line with pagination?

The whole point of an MVC framework is to separate design (templates) from logic (controllers). However, template languages often afford a limited degree of "design logic" to occur. This includes basic if statements, loops, filtering, etc.
I've created a Django template tag that can take any list or QuerySet and "pagify" it. It splits the list up into pages based on a specified page size then adds the pages into the Context. The usage is as follows:
{% pagify articles by 20 as pages %}
I can then call a separate include to iterate over the pages and produce a nice list of pages wherever I needed it.
This seemed like an optimal way to do it because it allowed me to page any list in the context; I didn't have to rely on the controller to return paged results. But a colleague argued that this seemed like too much logic for the template. I thought this still fell within the realm of design-based logic since the page would still function even without paging, and determining page size feels like a template responsibility.
My question, is this too much logic for the template? or is this a clean way to be handling this?
It's always been my understanding that the view isn't supposed to be devoid of logic. It's just supposed to be devoid of any controller logic. Paging just has to do with how the data is displayed which is exactly what the view logic is supposed to contain.
Put it this way; what if you were using your data model in another medium, say, not on the web but via some kind of console-based application or background task? Wouldn't it be nice to be able to get "pages" of data through a controller (or manager) rather than having to somehow rely on a template to do this work for you?
While I'd certainly agree that the "look" of the paged data should be handled by your template, the "act" of paging should be left up to a controller (Django view) or even through some kind of custom manager (models.Manager) method.
The view should not contain business logic or navigation logic. What you are describing is presentation functionality (carefully avoiding the l-word here), which can be placed in the view layer.
You may want to check out django-pagination, which provides a similar template tag.
I agree with your colleague; the template should be fed paginated data rather than performing the pagination. The key question, I think, is whether determining page size is a template duty, and I don't think so; I'd say it should be handled at a higher level.

What's the best way to "embed" a page number in a URL?

I'm developing a blog application using Django. Currently, the URL /blog/ displays the front page of the blog (the first five posts). Visitors can then browse or "page through" the blog entries. This portion is mapped to /blog/browse/{page}/, where page, of course, is an integer that specifies which "page" of blog entries should be displayed.
It's occurred to me, though, that perhaps the "page number" should be an attribute of the querystring instead (e.g., /blog/browse/?page=2), since the content of the browse pages is not static (i.e., as soon as I add another post, /blog/browse/2/ will have different contents than it had before the post was added). This seems to be the way sites like Stack Overflow and Reddit do things. For example, when paging through questions on Stack Overflow, a "page" attribute is used; likewise, Reddit uses a "count" attribute.
Extending this thinking, I realize that I use the same template to render the contents of both /blog/ and /blog/browse/, so it might even make sense to just use a URL like /blog/?page=2 to page through the contents of the blog.
Any suggestions? Is there a "standard" way of doing this, or at least a "best practice" method to use?
For my money, the best general purpose approach to this issue is to use the django-pagination utility. It's incredibly easy to use and your URLs should have the format you desire.
I prefer to use the GET URL parameter, as in URL?pg=#. It's very common and provides a standard visual clue to users about what is going on. If, for instance, I want to bookmark one of those pages or make an external link, I know without thinking that I can drop the pg parameter to point at the "latest" front-page index. With an embedded #, this isn't as obvious... do I leave off the parameter? Do I always have to set it to 1? Is it a different base URL entirely? To me, having pagination through the GET parameter makes for a slightly more sensible URL, since there's an acceptable default if the parameter is omitted and the parameter doesn't affect the base URL.
Also, while I can't prove it, it gives me the warm fuzzy feeling that Google has a better chance at figuring out the nature of that page's content (i.e. that it is a paginated index into further data, and will potentially update frequently) versus a page # embedded inside the URL, which will be more opaque.
That said, I'd say this is 99% personal preference and I highly doubt there's any real functional difference, so go with whatever is easier for and fits in better with your current way of doing things.
EDIT: Forgot to mention that my opinion is Django specific... I have a few Django apps so I'm relatively familiar with the way they build their URLs, and I still use a "pg" GET parameter with those apps rather than embedding it in the URL directly.
It seems like there are two things going on. A static page, that won't change and can be used for permalinking, like an article, as well as a dynamic page that will update frequently. There is no reason you cannot use both. URL rewriting should allow this to work quite nicely. There's no reason to let the implementation control the interface, there is always at least one way to skin every cat.