List in a Template

24 views
Skip to first unread message

Timothy W. Cook

unread,
Nov 9, 2013, 1:55:07 PM11/9/13
to django...@googlegroups.com
I have a view that creates a list of managers in the context. I want
to test if a logged in user is in the list before displaying a link to
the manager dashboard.

class IndexView(TemplateView):

template_name = 'index.html'

def get_context_data(self, **kwargs):
context = super(IndexView, self).get_context_data(**kwargs)
context['mgr_list'] = Manager.objects.all() # TODO: filter for
expired status
return context

The test in the template:
{% if user.is_authenticated %}
<li><a href="{% url 'logout' %}">logout</a></li>
{% if user.email in mgr_list %}
<li><a href="{% url 'mgr_dashboard' %}">Manager Dashboard</a></li>
{% endif %}
{% else %}
<li><a href="{% url 'register' %}">register</a></li>
<li><a href="{% url 'login' %}">login</a></li>
{% endif %}

The correct items are displayed for the user.is_authenticated test.


Just for testing I put {{mgr_list}} in my template and it displays this:

[<Manager: j...@mlhim.org>, <Manager: t...@mlhim.org>]

which is correct as far as the emails are concerned but I do not
understand where the 'Manager:' comes from and why are they wrapped in
angle brackets? This seems to be why my 'if' doesn't test correctly
but I do not know what to change.

Thoughts?

Thanks,
Tim




--
MLHIM VIP Signup: http://goo.gl/22B0U
============================================
Timothy Cook, MSc +55 21 94711995
MLHIM http://www.mlhim.org
Like Us on FB: https://www.facebook.com/mlhim2
Circle us on G+: http://goo.gl/44EV5
Google Scholar: http://goo.gl/MMZ1o
LinkedIn Profile:http://www.linkedin.com/in/timothywaynecook

donarb

unread,
Nov 9, 2013, 4:56:31 PM11/9/13
to django...@googlegroups.com
The problem is that you are trying to compare the email property of a user with a list of Managers. The angle bracket notation you show is Python's way of displaying object instances. It's showing there are two Manager objects in the list, the emails addresses you see are just the string representation of the object, a sort of shorthand to be able to identify different instances

If the user is a manager, you should be able to just test for membership in the list:

{% if user in mgr_list %}

Another option would be to have a property such as "is_manager' and test for that in the template.


Timothy W. Cook

unread,
Nov 9, 2013, 5:28:01 PM11/9/13
to django...@googlegroups.com
SOLVED (sort of).

On Sat, Nov 9, 2013 at 2:56 PM, donarb <don...@nwlink.com> wrote:

> If the user is a manager, you should be able to just test for membership in
> the list:
>
> {% if user in mgr_list %}

This made perfect sense after I realized that I was looking at a list
of objects and not just the email string returned from the model. But,
it didn't work.

> Another option would be to have a property such as "is_manager' and test for
> that in the template.
>

I thought about this but I also need to see if the manager status has
expired. So I solved it in this way, though it may not be the most
efficient.

The view now creates an actual list of email addresses of users with
active manager status.

class IndexView(TemplateView):

template_name = 'index.html'

def get_context_data(self, **kwargs):
context = super(IndexView, self).get_context_data(**kwargs)
mlist = []
for x in Manager.objects.all():
if x.expires >= now():
print(x.expires)
mlist.append(x.user.email)
context['mgr_list'] = mlist
return context


Is there a better way? Will this be particularly slow if I have 1,000 managers?

Thanks,
Tim

donarb

unread,
Nov 10, 2013, 1:37:19 AM11/10/13
to django...@googlegroups.com
The better way is to use the database to find the values, rather than doing it in Python. Off the top of my head, I'd do something like this:

def get_context_data(self, **kwargs):
    context = super(IndexView, self).get_context_data(**kwargs)
    
    # Get all active managers from the database
    q = Manager.objects.filter(expires__gte=now())
    
    # Create a list of all of their email addresses, the values() and values_list() methods
    # can pull out just the fields you want - 'flat' creates a list rather than a dict or tuple
    mlist = q.values_list('user__email', flat=True)
    context['mgr_list'] = mlist
    return context

As I said, I haven't tested this and I may be buggy, but you should be able to get the idea.


donarb

unread,
Nov 10, 2013, 1:40:00 AM11/10/13
to django...@googlegroups.com


On Saturday, November 9, 2013 5:37:19 PM UTC-8, donarb wrote:

As I said, I haven't tested this and I may be buggy, but you should be able to get the idea.


Um, I'm definitely not buggy, but my sample may be...

Timothy W. Cook

unread,
Nov 10, 2013, 8:23:50 AM11/10/13
to django...@googlegroups.com
On Sat, Nov 9, 2013 at 11:37 PM, donarb <don...@nwlink.com> wrote:
>
> The better way is to use the database to find the values, rather than doing
> it in Python.

Okay, this is good information to know.

Off the top of my head, I'd do something like this:
>
> def get_context_data(self, **kwargs):
> context = super(IndexView, self).get_context_data(**kwargs)
>
> # Get all active managers from the database
> q = Manager.objects.filter(expires__gte=now())
>
> # Create a list of all of their email addresses, the values() and
> values_list() methods
> # can pull out just the fields you want - 'flat' creates a list rather
> than a dict or tuple
> mlist = q.values_list('user__email', flat=True)
> context['mgr_list'] = mlist
> return context
>

More good info there. Thanks.


> As I said, I haven't tested this and I may be buggy, but you should be able
> to get the idea.
>

...

> Um, I'm definitely not buggy, but my sample may be...

LOL! Are you sure you aren't?

I have quite buggy (thinking) at times. But it makes life more interesting. :-)

Thanks again.

Cheers,
Tim

Timothy W. Cook

unread,
Nov 10, 2013, 9:10:15 AM11/10/13
to django...@googlegroups.com
BTW: The code worked without editing. :-)

Thanks.
Reply all
Reply to author
Forward
0 new messages