I am trying to achieve something in Django Templating Language without knowing whether it is possible (without resorting to JS or something like that).
I have the following code (from Django-Oscar) which renders 3 blocks of promotions on the main page:
{# Render promotions #}
<div id="promotions">
{% for promotion in promotions_page %}
{% render_promotion promotion %}
{% endfor %}
</div>
These three blocks are Single Item, Products and New Arrivals. The code above appears in the layout.html which is essentially responsible for rendering the entire layout of the main page.
The problem is that as soon as soon as Django encounters this code, it renders all of the promotions there one after another. I, however, would like to chose where on the page I place them. What's more, I do not believe that I have much flexibility in how I render them, read - I do not want to change the Oscar e-commerce and rendering code unless absolutely necessary.
Since I have access to individual templates for Single Item, Products and New Arrivals promotions, I tried creating DTL blocks there and then calling those blocks at proper places on the layout.html. However, that does not work.
What is a proper and most efficient way of achieving what I am trying to do?
Django templating system provides features that let you add your custom templates in place of the ones that come with the apps. You don't need to patch django-oscar for this.
Start here: https://docs.djangoproject.com/fr/1.11/howto/overriding-templates/
Hope I added enlightenment.
Related
I have a homepage, which I want to display a login form when user is not logged in or display a list of items belong to that user if he/she already logged in.
So far I came up with 2 methods:
Check whether user is authenticated in views.py and render corresponding view (in my views.py):
if request.user.is_authenticated():
return render(request, 'items.html')
else
return render(request, 'login.html')
Check directly in template and generate corresponding HTML for each case (in my index.html):
{% if user.is_authenticated %}
HTML for my items list
{% else %}
HTML for my login form
{% endif %}
Question
So which method is better for handling this? Are those methods differ much in performance? Is there any standard that we should handling these in views.py or in template itself?
I don't think there is a big performance difference. What's most important is how much you should stick to MVC pattern.
A template is meant to just display some sort of data that the view provides. Any kind of logic like deciding what kind of data to show based on requester's state should always be implemented by the view. Thus, you should move your logic into view function for the cleanness of your design.
TL;DR
Logic should be in your python code, not your template as much as possible. Due to maintenance and future-proof reasons.
Elaborate
Code quality: you can test your business logic when it's in your python not when it's in templates. The former improve your code quality and your value as a developer ;
Future-proof: you don't know which technology your application is going to use in the future, so avoiding tech-mingling will help you when upgrading it (you will be able to upgrade at different pace).
Separation of concerns principles: do you want a code that is a spaghetti plate, where you can't refactor a thing without impacting ten others?
Code legacy: you don't know who is going to work on your code neither which code you're going to work on. Don't make it hard for them (it would probably be your future self) ;
Clean code: that express itself in a single dialect is always better that mixing languages ;
Knowledge scope: front-end is often the responsibility of people with low programming skills (HTML/CSS are declarative) and you don't want them to mess with your business logic.
It depends on your html. If you want to change only a little part of your code based on the condition, check inside a template:
{% if user.is_authenticated %}
<h3>Welcome</h3>
{% else %}
Login
{% endif %}
But if items.html and login.html are different and big templates, you should definitely do the login inside your view.
I'm developing a web application with Django and we have met a dilemma about the design.
We were making one template for every screen, but right now we have detected that some parts of of the screen with the information are repeated all over the different screens. For example, when coming to show personal data of a person, you can show also another data concerning that person, but not personal data (financial data, for instance).
My intuition told me that we should look for a solution in which we could make small templates that we could compose, combine and concatenate and that we should also make different views or functions which would return its own associated template each one.
Thus, person_data() would return the rendered template showing the name, surname, address, etc... and financial_data() would return the rendered template showing the salary, bank account, etc... After that, the desirable thing would be concatenating both or inserting them in a wider template for showing all this together.
<html>
...
{# Html code here #}
...
{# person_data template #}
...
...
{# financial_data template #}
...
{# Html code here #}
...
</html>
So as always I made some research on the net and I found:
https://docs.djangoproject.com/en/dev/ref/templates/builtins/#include
a link which describes how to use include for inserting a template file in another template:
{% include "foo/bar.html" %}
And you can also use a variable from the python function with the path name or an object with render method:
{% include template_name %}
So we could use all this in this way for combining, concatenating, composing and operating on templates. We could choose the one which includes the others and passing it the context for all templates (I suppose, I didn't test anything). But I don't know if I'm well directed or if this is the best way to go. I would appreciate some advice.
I also found another interesting thread in stackoverflow talking about this:
How do you insert a template into another template?
My idea is to have small templates which are used repeatedly in different spots of the web and composing them in Unix-like style, so I would have small visual pieces that would be used once and again saving a lot of hours of writing of code.
Please some advice.
Thanks in advance
Yes, that is a correct approach. I think the best solution is to combine {% include %} and {% extend %}, which will allow you to inherit from a base template (via extend), and include parts you want from other templates (via include).
You'd end up having a base template, a template for the header, the footer, parts of the body etc.
You might also want to read more about it here and here
I have a block of XML that is returned from an API call.
It contains lots of results - person elements like below.
<root><person><name>mark</name><age>18</age></person><person><name>alan</name><age>10</age></person></root>
I want to pass this data structure (or some iterable version if it) to a django template to iterate over.
In my template I want to say
{% for r in results %}
{{ r.name }}
{{ r.age }}
{% endfor %}
I thought this would have been straight forward but its posing problems.
Django templates cannot handle it out-of-the-box. And it doesn't actually sound correct - to pass an XML structure into HTML template to process.
Making custom template tags or filters that would help to iterate over the XML structure could be a possible solution, but in this case you may find yourself overcomplicating things, template layer was made for presentation, don't put too much logic into it:
We see a template system as a tool that controls presentation and
presentation-related logic – and that’s it. The template system
shouldn’t support functionality that goes beyond this basic goal.
Parse the XML in the view, make a list of dictionaries and pass it to the template inside the context.
For example, use xmltodict tool:
persons = xmltodict.parse(data)['root']['person']
where data is your XML structure.
I've started using a rendered field in my django-haystack indexing to avoid database hits when a search is rendered. This is working well for the most part, but I have some runtime information (such as an edit button for staff) in the results as well that I'd like to splice in. A simplified example:
{{object.name}}<br/>
{% if user.is_staff %}
Edit
{% endif %}
{{ object.description}}
The user logic obviously can't be applied at indexing time so doesn't occur. Without using javascript hacks is there a way to splice some runtime output in amongst the pre-rendered text? I'm thinking it can be done by passing the rendered text with some formatting placeholders to a custom template tag, but I wonder if there's another way.
Edit: Perhaps multiple rendered, stored fields might be possible, covering the main fragments of the search result surrounding the logic parts, and then assembled at run time in the main results template. Would this work?
A designer recently handed me designs for a site I'm building for a client. They're great designs but I'm really scratching my head as to how I'm going to implement it on the site.
The content can very easily be broken down into blocks or chunks of data where I could allocate a textarea for text input, a couple of charfields for link-buttons, etc and sequentially render them out to the page.
The problem (eg why I'm not just pulling in Django-CMS et al) is the blocks are quite unique from each other. There are perhaps 20 different models that I would build for each block type. Rather than hack around a pre-fab CMS, I'd like to build a Page model and then just have an M2M that links to an ordered list of subclasses of my abstract Block class. I hope I'm not losing you.
I don't understand how I can do this. These questions spring to mind:
Is there a simple CMS that does all of this already? Am I wasting my time trying to figure out the physics?
My Blocks subclasses will technically be different type. Do I need generics for a M2M-through class to link to them? Is so, how do I do that?
How do I render x different forms in an inline admin context? (I'd like to have the page form with a list of the Blocks underneath)
How can the user specify the type of Block in the inline control?
Edit: Or, alternatively, what about a templatetag-based CMS?
I'm thinking of something like plonking this in my template:
{% editable 'unique_id' 'content-type' %}
A further example:
{% editable 'home-intro' 'text' %}
Then I could just stick these around the templates I want to be editable, in the way I want them to be editable and when logged in the client would see "Edit text", "Edit link", "Edit image" links which simply popped up the right field.
This would make things more locked down but the layout needs to remain solid (and the client knows nothing about HTML/CSS) so it's one or other of these methods IMO.
Couldn't you implement your 'Blocks' as Django CMS Plugins? Then each page is just constructed from a number of plugins.
Each plugin has an admin form which gets the specifics for itself, and then the page template renders the plugin as you want it.
If you look at the first page of the django-cms demo:
https://www.django-cms.org/en/tour-demo/
you'll see in (1) a highlighted plugin block - in this case a formatted text block that is edited with TinyMCE or similar. You can define your own plugins and add them to pages.
last month I published an article (for review) on how tho build a basic CMS for Jinja. This's templating language does not dffer very much from Django, which I have been using before.
You can find it here. It uses template inheritance to fill the content blocks.
https://codereview.stackexchange.com/questions/5965/review-request-jinja-cms-for-energiekantoor-nl-on-google-app-engine
Or type in Google : Jinja CMS