I am trying to call a method in a model from a template and I have come to the conclusion that this cannot be done.
This is my code
{% if request.user.is_authenticated %}
{% if a_story.is_story_liked(request.user.id) %}
<a class="story_like" data-id="{{ a_story.id }}" href="#">Like</a>
{% endif %}
{% else %}
<a class="story_like_login" data-id="{{ a_story.id }}" href="#">Like</a>
{% endif %}
The error happens on the second line. "is_story_liked" checks if the user has "liked" a story or not. If not, then I would write the same anchor tag but with a different class.
I am kinda stumped with this one. I am trying to output different class names: if the user is logged in, if the user is not logged in and if the user has "liked" or not "liked" an article/story.
Method calls in django templates work only if they don't have an argument (eg. {% if request.user.is_authenticated %}). You will either need to put that functionality in the view that renders this template or put this functionality in a custom template tag.
Related
So I have this template context processor:
from cases.models import CasePage
def random_case(request):
case = CasePage.objects.live().order_by('?')
return {'random_case': case}
And in the template I do this:
{% for entry in random_case %}
{% if request.get_full_path != entry.get_url %}
{% if forloop.first %}
<a class="ajax-link project-next" href="{{ entry.get_url }}">
<div class="nav-project-title">{{ entry.title }}</div>
<div class="nav-title">next</div>
</a>
{% endif %}
{% endif %}
{% endfor %}
And this works but the problem is sometimes the object is the same as the page so nothing is displayed. It would be great if that one would be skipped in favour of the next entry. And it's also too much logic in the template for me. What would be the best way to move this logic into the context processor and make it work?
Make random_case a method of CasePage, and filter out the case with an ID equal to self.
class CasePage(Page):
# ...
def random_case(self):
return CasePage.objects.live().exclude(id=self.id).order_by('?').first()
You can then refer to this method within your template as page.random_case - bear in mind that a new random choice will be made on each call, so you probably want something like {% with page.random_case as case %}.
I need the search result to be validated together with the statement that it is a query inside the template.
So if the user is searching for another user and this user does not exist, it returns nothing. otherwise it returns the username of the user.
If request.user just checks the user that is logged in.
something like this
{% if request.GET.q and request.GET.q.is_authenticated %}
but this does not work :D Thank you
Can I use is_authenticated or is there a better way?
<li class="dropdown-hover">
<form class="form-inline">
{% include "tweets/search_form.html" %}
</form>
{% if user in request.GET.q.is_authenticated %}
<div class="dropdown-content x-card-4 x-bar-block" style="width:300px">
<a href='{{ request.GET.q }}'>{{ request.GET.q }}</a><br/>
{% else %}
<div class="dropdown-content x-card-4 x-bar-block" style="width:300px">
<a href='#'>No users found</a><br/>
{% endif %}
</li>
Thank you for any help
There is a better way, just do {% if request.user.is_authenticated %}.
you need to add loginRequiredMixin in your class so it allow to perform tasks only if user is logged in otherwise it redirect to login page.
#andre If you want to show/hide html tags in a template to the guest/logged-in user, you can use this {% if user.is_authenticated %} or you want to show some pages to the logged-in user #tabish-manzoor's solution is great.
Doing this works
{% for comment in comments %}
{{ comment.user }}
{% endfor %}
However, I want to get all the comment.user values in the dictionary without using a for loop. Is this possible?
I ask because I need to do this check
{% if name in comment.user %} # check if name is in any one of the comments
# do something
{% endif %}
Basically, you need to get all the distinct users from comments. You have to do it in the view and pass users queryset back into the template:
users = User.objects.filter(comment__in=comments).distinct()
I am pretty new to Flask/Flask-Admin.
I have followed the tutorial on flask admin and managed to get the admin panel working but slightly lost on how to get the below things implemented.
https://github.com/flask-admin/flask-admin/tree/master/examples/auth
When logged in as a normal user I can only see "home" page.
How can I expose other views to "normal user" and restrict actions such as read only etc.
I have created a "baseview" which is not associated with any other models as below:
class SitesView(MyBaseView):
#expose('/')
def index(self):
return self.render('views/testviews.html')
admin.add_view(SitesView(name='Test views', endpoint='test views'))
and html as below:
{% extends 'admin/master.html' %}
{% block body %}
{{ super() }}
{% if current_user.has_role('view1') %}
Site1
{% endif %}
{% if current_user.has_role('view2') %}
<a>Site2</a>
{% endif %}
{% if current_user.has_role('view3') %}
<a>Site3</a>
{% endif %}
{% if current_user.has_role('view4') %}
<a>Site4</a>
{% endif %}
{% endblock %}
This gives me a new tab with different views with works as expected.
What I am trying to achieve here is when user click the Site1 link they go to Site1 page within flask-admin interface but I am not sure how to do that. I could create a new route for this but the problem is I can't(don't know how to) extend flask admin template.
For example this works but it redirect the page outside flask-admin template:
#app.route('/views/')
def views():
return render_template('views/views1.html')
and modified the templates>admin>index.html page with below:
<ul class="lead text-center list-group">
{% if current_user.has_role('view1') %}
<li class="list-group-item">View1</li>
{% endif %}
{% if current_user.has_role('view2') %}
<li class="list-group-item">View2</li>
{% endif %}
{% if current_user.has_role('view3') %}
<li class="list-group-item">View3</li>
{% endif %}
{% if current_user.has_role('view4') %}
<li class="list-group-item">View4</li>
{% endif %}
</ul
I want to build the whole web site using flask admin so that I can keep user experience consistence. Am I doing this the wrong way?
Thanks for your time.
Please do let me know if you want me to provide more information on this issue.
Kind Regards.
So after going through documentations and tutorials I have found the solution to my issue.
For my first question:
When logged in as a normal user I can only see "home" page. How can I
expose other views to "normal user" and restrict actions such as read
only etc.
We can do this by overwriting our view functions is_accessible method as below:
def is_accessible(self):
if not current_user.is_active or not current_user.is_authenticated:
return False
if current_user.has_role('superuser') or current_user.has_role('user') or current_user.has_role('view1'):
return True
return False
For my second question we just need to give the endpoint as for our BaseView as below:
class MyView(BaseView):
#expose('/')
def index(self):
return self.render('views.html')
admin.add_view(MyView(name='Custom Views', endpoint='customviews'))
And then in your jinja template you need to call it:
href="{{ url_for('customviews.index') }}
Just one thing to note, doing this:
current_user.has_role('superuser') or current_user.has_role('user') or current_user.has_role('view1')
could get quite messy if we have so many roles, not sure how we would approach this but hoping this will help someone.
Thanks all.
I know this is an old question, but for the following code
current_user.has_role('superuser') or current_user.has_role('user') or current_user.has_role('view1')
What I like to do is having a hybrid_property (available on both Peewee and SQLAlchemy) inside my User class that consolidates these properties. So it'd look something like this:
#hybrid_property
def user_has_administrative_rights(self):
return self.has_role('superuser') or self.has_role('user')
I am having trouble implementing django_breadcrumbs in a DRY fashion using block.super.
I have a template "editions" that the user can reach in one of two ways: either from home, in which case the user sees all the editions, or from the template "surveys", in which case the user sees only the editions for that survey.
The breadcrumbs for the editions template look like this and they work fine:
{% extends 'base.html' %}
{% load django_bootstrap_breadcrumbs %}
{% block breadcrumbs %}
{{ block.super }}
{% if slug %}
{% breadcrumb "Surveys" "surveys:index" %}
{% breadcrumb "Editions" "editions:index" slug=slug %}
{% else %}
{% breadcrumb "Editions" "editions:index" %}
{% endif %}
{% endblock %}
Disappoinment ensues for pages that hang off the editions template. I had hoped that by extending that page and using block.super, I would inherit the proper breadcrumbs depending on where the edition came from. But I only ever get the Editions breadcrumb even when I hoped for the Surveys / Editions breadcrumbs.
Here is the template "create" which hangs off "edition":
{% extends 'editions/index.html' %}
{% load bootstrap3 %}
{% load django_bootstrap_breadcrumbs %}
{% block breadcrumbs %}
{{ block.super }}
{% breadcrumb "Create" "editions:create" %}
{% endblock %}
I could always put another if: else: in that template, but I would rather just inherit the if: else: from the previous template. What is it I don't understand? Do I need to pass the slug back up to the super:block or something? How would I do that without repeating the same if: else: in the child template? Indeed, how would I do that at even with a new if: else:?
thanks
John
My best guess is that you render the second template without passing the slug variable. Your inheritance is correct, but as the parent (or super) template uses the slug variable, what it renders depends on the variable's contents. Therefore, if no variable called slug is passed, you will always get the else-part of your if statement.
So, the solution seems quite simple: add the slug variable to the context parameter when triggering the template render.