how to use django authentication in "main" template - python

I've created a main HTML file where I have a template for all apps.
And in every other template file I am using :
{% extends "main.html" %}
To get the content.
But there are things I want to add to the main template but only if user is authenticated.
I know I can use
{% if user.is_authenticated %}
but it doesn't work in main.html file.
Do you know what am I doing wrong ?
What should I do to solve this problem?
Thanks in advance,

You can use
{% if request.user.is_authenticated %}
your code here
{% endif %}

1) Use {% debug %} template tag to understand User.
https://docs.djangoproject.com/en/dev/ref/templates/builtins/#debug
Or
2) Using {% request.user.is_authenticated %} should get the authenticated user information from the Http Request.

Related

Invalid block tag on line 5: 'else'. Did you forget to register or load this tag? [duplicate]

I would like to have a template that extends another conditionally. Basically, when a variable called "ajax" is true I DO NOT want to have the template extend another.
{% if not ajax %}
{% extends "/base.html" %}
{% endif %}
Any clues?
While you may not wrap extends in logic blocks, since it must be the first tag if used, it can still accept variables, including filters. This should fit your purpose nicely:
{% extends ajax|yesno:"base_ajax.html,base.html" %}
{# stuff #}
Note: the yesno filter also accepts null values (None) as the third choice, and if you do not specify one (as in this case), it will fallback to converting it to False (i.e. it will return the second choice). This allows you to not specify the ajax variable in your template without breaking it.
Suggested by user Rafael:
{% extends request.is_ajax|yesno:"base_ajax.html,base.html" %}
{# stuff #}
This will only work if you are using a RequestContext context instead of a plain Context object and you have the request context processor enabled, or alternatively, if you insert the request object in your template context.
You cannot do it like that. You can however set a variable and use that to choose the template to extend:
{% extends my_template %}
Then in python code you write something like:
if ajax:
template_values['my_template'] = 'base_ajax.html'
else:
template_values['my_template'] = 'base.html'
You may wish to refer to the documentation for more information.
I was looking for the solution of the same problem and came with a bit better workaround than suggested by Klaus Byskov Hoffmann. It is better because you don't have to have 2 separate base templates for ajax and non-ajax requests and, which is more important, you don't have to define if statement that will define which base template to use in EACH controller.
In your case the solution would be:
page.html
{% extends "/base.html" %}
{% block body %}
hello world
{% endblock body %}
base.html
{% if not ajax %}
<html>
<head></head>
<body>
LOGO and other stuff...
{% endif %}{% block body %}{% endblock body %}{% if not ajax %}
FOOTER
</body>
</html>
{% endif %}
So, base.html is always included but it prints its content only when not ajax.
UPDATE: This can be simplified by creating and adding a new ConextProcessor that will populate ajax context variable from the HttpRequest.is_ajax(), so you don't have to do anything extra in your controllers and templates at all.
If you don't want to "extend" a parent template, you can always create an empty file called null.html and extend that. Kind of hacky, but easy to understand.
I know this is an old thread but in case someone stumbles across this, I believe the best way to achieve your goal would be:
"views.py"
if ajax:
request.session['ajax'] = 'ajax'
"base.html"
{% if 'ajax' in request.session %}
{% include "ajax.html" %}
{% endif %}
and in "ajax.html" you wouldn't use any {% extends %} or {% block %} tags since you won't be calling anything for "ajax.html" to extend onto the base. That will be taken care of by "include".

Flask required form on home page

I am looking for some kind of example with flask using a required form on the home page of my site that requires the user to select an option before being allowed onto the rest of the site. The form is used for selecting a collection out of my mongo db database. I need to know what collection the user wants to use before going anywhere else on the site. Once this done I need to make sure I can use this information on my other route and views on my site.
What you want is to implement a login infrastructure.
using flask, you have a base template, where every other template is extending, what you can do is something like the following:
base.html:
{% if current_user.is_authenticated %}
<content>
{% block content %}
{% endblock %}
</content>
{% else %}
<login-form>
{% block content %}
{% endblock %}
</login-form>
{% endif %}
using this code, the content is shown only and only if the user is authenticated. in login-form HTML you should have a form to ask the credentials needed to authenticate the user and then allow them access to rest of the site.
in other template files, you continue to use the same practice:
dashboard.html:
{% extends 'base.html' %}
{% block content %}
<YOUR HTML CONTENT>
{% endblock %}
the content of dashboard.html is only shown to the user, if they are logged in(current_user.is_authenticated = True)
this is because dashboard.html is shown inside the content block of base.html witch is only shown or rendered if that condition is met.
you can use anything else instead of is_authenticated like the collection being selected or anything like that. the procedure to do it is the same.

Display all model data inside html page

I'm trying to build a website that has products and categories.
When you are on the page of a product, you can click a button to see a list of all the categories it falls under.
You can click another button, that appears on all pages, to see a list of all the categories overall.
In the html page see_all_categories, I wrote a simple block like this:
{% extends 'base.html' %}
{% load staticfiles %}
{% block content%}
{{Category.all}}
{% endblock content %}
I expect to see a messy printout of all the categories but I don't. It doesn't return an error, but it produces nothing, other than the base.html.
What am I doing wrong?
You want to display a list of the categories. I assume your Category model owns an attribute named "title" which is the representation of your Category.
If you're using Django template engine or Jinja2, you can make a for loop inside your template like this :
{% for cat in Category.objects.all %}
{{ cat.title }}
{% endfor %}
As a troubleshooting, I'd suggest you didn't pass your Category model to your template, that is not done automatically. You have to add your model to the context before rendering the template.
As mentionned in the comments, here is doc for template rendering with Django templates.
Django Template Guide
To add your model to the context you can follow this guide.
I don't intend to help you further because I lack of information and that may vary a LOT according to your settings. (Class Based views ? Function based views ? What kind of template are you using... And so on)
I figured out the solution after many long annoying hours of trying everything. I feel dumb but I want to spare the next guy the massive pain in the two-pack.
This is what I did:
In the Views.py, I changed the view function for this page FROM this:
def view_all_categories(request):
context = {'Category' : Category}
return render(request, 'store/see_all_categories.html', context)
TO this
def view_all_categories(request):
all_cats = Category.objects.all().order_by('id')
context = {'all_categories' : all_cats}
return render(request, 'store/see_all_categories.html', context)
and in the page see_all_categories.html itself, I changed it (from the question) TO this:
{% extends 'base.html' %}
{% load staticfiles %}
{% block content%}
{% for cat in all_categories %}
<p>{{ cat.name }}</p>
{% endfor %}
{% endblock content %}
And now it works!!

Is it possible to load a custom template tag in base and use it in extented templates

I loaded a custom template tag note_extras.py in base.html.
base.html
<div id="wrap">
{% load note_extras %}
{% block content %}
{% endblock %}
</div><!--wrap-->
but it is not accessible at templates which is an extend of base.html ie::
home.html
{% extends "base.html" %}
{% block content %}
<div class="container">
{% create_tagmenu request.user.pk %}
</div>
{% endblock %}
it is working fine if i load note_extras in home.html ie:
{% extends "base.html" %}
{% load note_extras %}
....
In Django template language, you must load all needed template libraries in each of the templates.
I personally think it is a good idea because it makes templates more explicit (which is better than implicit). Ill give an example. Prior to Django 1.5, the default behavior for a url tag was to provide the view name in plaintext as well as all the needed parameters:
{% url path.to.view ... %}
There however was no way to provide the path to the view via a context variable:
{% with var='path.to.view' %}
{% url var ... %}
{% endwith %}
To solve that, starting with 1.3, you could import the future version of the url tag (which became the default in 1.5) by doing:
{% load url from future %}
{% url var ... %}
or
{% url 'path.to.view' ... %}
Now imagine that you would need to create a template which would extend from a base template which you did not create (e.g. one of django admin base templates). Then imagine that within the base template it would have {% load url from future %}. As a result, {% url path.to.view ... %} within your template would become invalid without any explicit explanation.
Of course this example does not matter anymore (starting with 1.5) however hopefully it illustrates a point that being explicit in templates is better than implicit which is why the currently implementation is the way it is.
If you want that a template tag is loaded in every template you want to do it in the init file of your app:
from django.template.loader import add_to_builtins
add_to_builtins('my_app.templatetags.note_extras')
In case anyone was wondering, add_to_builtins has been deprecated but one could still load a tag for all of the templates in the project via settings.TEMPLATES - supported for Django 1.9 onwards as described here:
https://stackoverflow.com/a/59719364/2447803

Python / Django - If statement in template around extends

I would like to have a template that extends another conditionally. Basically, when a variable called "ajax" is true I DO NOT want to have the template extend another.
{% if not ajax %}
{% extends "/base.html" %}
{% endif %}
Any clues?
While you may not wrap extends in logic blocks, since it must be the first tag if used, it can still accept variables, including filters. This should fit your purpose nicely:
{% extends ajax|yesno:"base_ajax.html,base.html" %}
{# stuff #}
Note: the yesno filter also accepts null values (None) as the third choice, and if you do not specify one (as in this case), it will fallback to converting it to False (i.e. it will return the second choice). This allows you to not specify the ajax variable in your template without breaking it.
Suggested by user Rafael:
{% extends request.is_ajax|yesno:"base_ajax.html,base.html" %}
{# stuff #}
This will only work if you are using a RequestContext context instead of a plain Context object and you have the request context processor enabled, or alternatively, if you insert the request object in your template context.
You cannot do it like that. You can however set a variable and use that to choose the template to extend:
{% extends my_template %}
Then in python code you write something like:
if ajax:
template_values['my_template'] = 'base_ajax.html'
else:
template_values['my_template'] = 'base.html'
You may wish to refer to the documentation for more information.
I was looking for the solution of the same problem and came with a bit better workaround than suggested by Klaus Byskov Hoffmann. It is better because you don't have to have 2 separate base templates for ajax and non-ajax requests and, which is more important, you don't have to define if statement that will define which base template to use in EACH controller.
In your case the solution would be:
page.html
{% extends "/base.html" %}
{% block body %}
hello world
{% endblock body %}
base.html
{% if not ajax %}
<html>
<head></head>
<body>
LOGO and other stuff...
{% endif %}{% block body %}{% endblock body %}{% if not ajax %}
FOOTER
</body>
</html>
{% endif %}
So, base.html is always included but it prints its content only when not ajax.
UPDATE: This can be simplified by creating and adding a new ConextProcessor that will populate ajax context variable from the HttpRequest.is_ajax(), so you don't have to do anything extra in your controllers and templates at all.
If you don't want to "extend" a parent template, you can always create an empty file called null.html and extend that. Kind of hacky, but easy to understand.
I know this is an old thread but in case someone stumbles across this, I believe the best way to achieve your goal would be:
"views.py"
if ajax:
request.session['ajax'] = 'ajax'
"base.html"
{% if 'ajax' in request.session %}
{% include "ajax.html" %}
{% endif %}
and in "ajax.html" you wouldn't use any {% extends %} or {% block %} tags since you won't be calling anything for "ajax.html" to extend onto the base. That will be taken care of by "include".

Categories