How to call a verification function from views to templates? - python

I have a function to check if the user is a staff:
class VerificateUser():
def allowed_user(request):
if request.user.is_staff:
return True
In my template, I’m going to show this section only for staff users, but this is not working.
{% url if not allowed_user %}
<h1>
Welcome to the show
</h1>
If do something like it, works:
```html
{% if not request.user.is_staff %}
<h1>
Welcome to the show
</h1>
But I need to use a view function to clean my code because I’m probably going to add more conditionals.

Since you are using a class-based view then I would suggest updating the context dictionary which you could use in the html template to determine whether the user is allowed or not. For example, Within the views.py.
class VerificateUser():
# Update the context
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# Call the allowed_user() and return whatever value, passing that value it to the context variable
context['allowed_user'] = self.allowed_user()
return context
# Checking if the user is allowed here
def allowed_user():
if self.request.user.is_staff:
return True
return False
Now within the html file, you can reference that allowed_user from the context variable.
{% if allowed_user %}
<h1>Hi, you are allowed to see here...</h1>
{% endif %}
That should do the trick.

You can do this sort of thing in many ways, but simply you can do by the following way-
{% if request.user.is_authenticated %}
<p>Welcome,{{request.user.first_name}} </p>
{% endif %}
request object is by default available in all of your Django templates context.

Related

In Django, how do I restrict is_staff member to access a URL?

In my web, user and admin user both login from frontend. Now I want to do that some of URLs are accessed by public user only. Is_staff user not access that URL. How do I do that?
Updated:
Can I use any decorator for this?
If you want to use a decorator, you can use the user_passes_test. First define a test function that checks that the user is not a staff member.
def is_not_staff(user):
return not user.is_staff
You can change the function to check user.is_authenticated (user.is_authenticated() in Django <=1.9) as well, if you don't want anonymous users to be able to access the view.
Then use user_passes_test with your test function to decorate the view you wish to protect.
#user_passes_test(is_not_staff)
def non_staff_view(request):
...
You can simply inherit LoginRequiredMixin and create your own custom access mixin as below:
class AccessMixin(LoginRequiredMixin):
def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated or request.user.is_staff:
return self.handle_no_permission()
return super().dispatch(request, *args, **kwargs)
Now you just need to inherit AccessMixin in your view as below:
class HomePageView(AccessMixin, TemplateView):
login_url = <login-url>
...
...
So anonymous user and staff user won't be able to access the content of the page.
You can also mention the same in your base template html
Consider you have created a base.html which extends content block and you can add permission as below:
Ex.
base.html
{% if user.is_authenticated %}
{% if user.is_staff %}
<h3>Not allowed to access this page</h3>
{% else %}
{% block content %} {% endblock %}
{% endif %}
{% endif %}
this way when you extend base.html in your template all the content you write within {% block content %} {% endblock %} will only be rendered for non-staff logged in user.

Django templatetag without value and object to return True or False

I want to create a templatetag to check if multiple condition are true.
Here Is what I have tried:
from django import template
register = template.Library()
#register.simple_tag
def is_special():
if request.user.is_authenticated() and request.user.profile.status.slug == "special" and request.path in "/about/":
return True
else:
return False
But when I try to load and test "is_special" in the template. I don't get any thing.
{% if is_special %}
display something
{% else %}
display default
{% endif %}
Is this the right way to make a templatetag?
When you use {% if is_special %}, it isn't running your template tag, it is checking to see whether the variable is_special is True or False.
To assign the result of a template tag to a variable, you want an [assignment tag]. You also need to pass the request object to your tag.
#register.assignment_tag
def is_special(request):
if request.user.is_authenticated() and request.user.profile.status.slug == "special" and request.path in "/about/":
return True
else:
return False
Then in your template:
{# run the tag #}
{% is_special request as is_special_result %}
{# use the result #}
{% if is_special_result %}
display something
{% else %}
display default
{% endif %}
Finally, you need to make sure the request is in your template's context. The easiest way to do this is to make sure you have enabled the request template context processor. Then, the request will be available if you use generic class based views or the render shortcut.

How to set a variable from within a template

My layout template contains a header and I'd like to add a CSS class to the currently selected menu option.
class="active"
I thought I found the solution here but I'm still having issues. When I paste the following code into my template I get a server error.
{% rule = request.url_rule %}
Why didn't this work? How can I set a variable to control the menu in the templates?
{% rule = request.url_rule %} is not valid syntax in Jinja. If you want to set a context variable from a template, use set:
{% set rule = request.rule %}
request is already passed to each template context automatically, you don't need to pass it in render_template.
My best guess would be that the request object isn't getting passed to the template. If it isn't being passed you wouldn't be able to access it when rendering the template. You could pass it explicitly, which would look something like this:
from flask import request
from flask import render_template
#app.route('/hello/')
def hello():
return render_template('hello.html', request=request)
Someone commented that swankswashbucklers answer wouldn't fix my problem so I'm posting my solution which was inspired by his suggestion.
I simply manually set a variable called title when creating the view.
def home():
return render_template(
'index.html',
title='Home',
)
Within the template I referenced the variable to decide which menu item to highlight.
{% if title == "Home" %}
<li class="active">
{% else %}
<li>
{% endif %}
It turned out in my situation I didn't need to access the current url.

Adding start separate page in django app

I want to add a separate homepage in my Django app.
If a user is logged in to show him all the content.
If the user is not logged in to show him the starting page and a link to login.
The solution is based on the code below does not always pass the exam.
{% if user.is_authenticated %}
//Something
{% else %}
//Something
{% endif %}
My view:
class Start(TemplateView):
template_name = "dashboard/start.html"
You can override the get_template_names() method of the view and render different templates for anonymous and logged users:
class Start(TemplateView):
def get_template_names(self):
if self.request.user.is_authenticated():
return ['dashboard/dashboard.html']
return ['dashboard/start.html']

Pass a context variable through an inclusion tag

Performing a check to see whether or not a user is attending or not. How do I pass the context variable is_attending to the template without getting a syntax error on 'is_attending': context['is_attending']? The check is basically for styling divs and whatnot. What am I doing wrong?
template:
{% for event in upcoming %}
{% registration %}
{% if is_attending %}
Registered!
{% else %}
Register button
{% endif %}
yadda yadda divs...
{% endfor %}
filters.py
#register.inclusion_tag('events/list.html', takes_context=True)
def registration(context, event):
request = context['request']
profile = Profile.objects.get(user=request.user)
attendees = [a.profile for a in Attendee.objects.filter(event=event)]
if profile in attendees:
'is_attending': context['is_attending']
return is_attending
else:
return ''
Thank you!
'is_attending': context['is_attending'] is not valid python. Rather, it looks like a partial dictionary. Since .inclusion_tag() code is supposed to return a dict, perhaps you meant the following instead:
if profile in attendees:
return {'is_attending': context['is_attending']}
else:
return {'is_attending': ''}
Also note that takes_context means you'll only take the context as an argument. From the howto on custom tags:
If you specify takes_context in creating a template tag, the tag will have no required arguments, and the underlying Python function will have one argument -- the template context as of when the tag was called.
Thus your tag should be:
{% registration %}
and your full method can take the event argument directly from the context:
#register.inclusion_tag('events/list.html', takes_context=True)
def registration(context):
request = context['request']
event = context['event']
profile = Profile.objects.get(user=request.user)
attendees = [a.profile for a in Attendee.objects.filter(event=event)]
if profile in attendees:
return {'is_attending': context['is_attending']}
else:
return {'is_attending': ''}

Categories

Resources