I have two django model, User and Follow.
In the Follow table, I have two attribute a and b which means a following b.
User table is just the django.contrib.auth.User
Let say I am in user A homepage, and A is following B, C and not following D.
I want to list all the username in A's homepage and highlighting those A is following.
In this case B, C should be highlighted and D should not be highlighted.
I was thinking about (pseudocode)
for user in users :
for follow in Following:
if user.username == follow.username:
flag=true
break
if flag:
#print color <p>user.username</p>
else
#print normal..
But I dun think django template allow me to do this.
Is there any other ways to do this?
Here is my code in django template
{% for user in all_user %}
{% for follower in followers %}
{% ifequal user.username follower.follow.username %}
<p class="following">{{user.username}}</p>
{% endifequal %}
{% endfor %}
<p>{{ user.username }}</p>
{% endfor %}
This will duplicate the user that 'A' is following.
Thank you so much
Hm, I would approach this by doing what you have done here, and by passing the variable "flag" to your template, as well as the rest of the objects.
{% if flag == True %}
<do whatever>
{% endif %}
You can also add an attribute to the user in your for loop, then retrieve that in the template.
for user in users :
for follow in Following:
if user.username == follow.username:
user.followed = True
break
Then in your template
{% for user in users %}
{% if user.followed %}
....
{% else %}
....
{% endif %}
{% endfor %}
Related
I have a for loop in Django template. After that, I check for coincidences. But in some cases, there are might be 3 coincidences. I need to show only the first coincidence. Now, my code returns the name for 3 times, because, there are 3 coincidences
{% for ip in ips %}
{% if d.name == ip.name %}
<strong>{{ d.name}} </strong>
{% endif %}
{% endfor %}
SOLUTION
It is impossible to break forloop in django template, so I decided to change in views.py through queryset distinction of similar names
ips = Point.objects.defer('point').order_by('name').distinct('name')
I don't recommend doing this in Django Template , but in views itself. But if you can't then you can use {{ forloop|break }}.
Something like this :
{% for ip in ips %}
{% if d.name == ip.name %}
{{ forloop|break }}
<strong>{{ d.name}} </strong>
{% endif %}
{% endfor %}
Check the small snippet example here...
{% for cred in allcreds %}
{% if cred.datasource.name == '...' %}
<h4>{{ cred.datasource }}</h4>
{% endif %}
{% endfor %}
In this case I check the datasource name in the conditional. Then it prints out the datasource. I want to have the datasource in the conditional.
I assume if you print out {{ cred.protocoldatasource }} it will output nothing, because your "relation" protocoldatasource does not exist.
The available foreign-keys that your model ProtocolUserCredentials has are: protocol, data_source, user, protocol_user.
So if you do
{% if cred.data_source.name == 'Demonstration Protocol, ...' %}
or any other of the mentioned relations you can access your related models.
Also note that {% if foo = 'bar' %} is invalid, you'll need to have == in the if-statement.
I'm working on a Django web app and have the following query:
I have a model called 'AppQoSList' which lists the applications available to all users.
I have then another model called 'BasicAppSDWANProfiles' which has a ManyToMany relationship with 'AppQoSList' .
In short, it means a user can have multiple 'BasicAppSDWANProfiles' associated to his account and multiple AppQoS can be within a particular BasicAppSDWANProfiles:
class AppQoSList(models.Model):
app_qos_name = models.CharField(max_length=50, blank=None, null=True)
app_qos_description = models.CharField(max_length=500)
def __str__(self):
return u'%s' % self.app_qos_name
class BasicAppSDWANProfiles(models.Model):
profile_name = models.CharField(max_length=30)
profile_basic_app_qos = models.ManyToManyField(AppQoSList)
tenant_id = models.ForeignKey(Tenant, default=3)
I'm facing issue in my template when I try to display the list of apps available and the associated BasicAppSDWANProfile:
{% for app in apps %}
{% for profile_app in sdwan_prof %}
{% for specific_app in profile_app.profile_basic_app_qos.all %}
{% ifchanged specific_app.pk %}
{% if app.pk == specific_app.pk %}
<td><h4><span class="label label-primary">{{ profile_app.profile_name }}</span></h4></td>
{% else %}
<td><h4><span class="label label-warning">Not Assigned</span></h4></td>
{% endif %}
{% endifchanged %}
{% endfor %}
{% endfor %}
{% endfor %}
Issue with this code is that 'Not Assigned' is displayed 6 times on each row (which corresponds to the number of Apps found in BasicAppSDWANProfiles associated with this user) whereas I would like to display it only once:
Would you have any solution for this ?
Thanks in advance.
I was able to address this issue.
First I did clean up my view code to remove duplicate 'Not Assigned' values.
I pass to my template context a dictionary with only apps that have a profile assigned such as below:
{'citrix-static': 'DPS-BLACKLIST',
'exchange': 'DPS-BLACKLIST',
'ms-lync-audio': 'DPS-WHITELIST',
'ms-update': 'DPS-GREYLIST',
'rtp': 'DPS-WHITELIST',
'share-point': 'DPS-WHITELIST'}
In my template, I only loop through this dictionary:
{% for k,v in app_prof_assign.items %}
{% if app.app_qos_name == k %}
<td><h4><span class="label label-primary">{{ v }}</span></h4></td>
{% endif %}
{% endfor %}
I then simply check if the app is not in the profile dictionary, outside the loop:
{% if app.app_qos_name not in app_prof_assign %}
<td><h4><span class="label label-warning">Not Assigned</span></h4></td>
{% endif %}
Finally, I can get the table populated as expected:
I have a template which will display all the likes and the person liked for a particular forum. In the template it can display numbers of likes and all the person's username that liked that forum. But I want the full name and not the username (here it is the email). How do I get the full name in the template or if possible from the view itself. Thank you.
forums.html:
{% extends "base.html" %}
{% load forum_tags %}
{% block content %}
<h2>Logged in as -- {{request.user}}</h2>
<h1>Forums:</h1>
{% if forums.count > 0 %}
{% for forum in forums %}
<h2>{{forum.question}}</h2>
<p>{{forum.body | truncatewords:"30"}}</p>
{% if user in forum.likes.all and forum.likes.count > 1 %}
<p>Unlike You and {{forum.likes.count | substract:1}} others liked</p>
{% elif user in forum.likes.all %}
<p>You liked it</p>
{% else %}
<p>Like</p>
{% endif %}
{% for likes in forum.likes.all %}
<li>{{likes}}</li>
{% endfor %}
{% endfor %}
{% else %}
<p>Sorry! No forum to display.</p>
{% endif %}
{% endblock %}
snippet of views.py:
def forums(request):
forums = Forum.objects.all()
c = {'forums': forums}
return render(request, 'forums.html', c)
If you're using the default User model from django.contrib.auth.models, it has a get_full_name method that you can use in your template:
{{ user.get_full_name }}
Otherwise, you can implement that method in your own User model too. Any method that accepts no arguments can be called from templates (unless they have a alters_data attribute set to True).
My coding is:
views
def showThread(request, thread_id)
post_list = Post.objects.filter(id = thread_id)
post_likes = PostLikes.objects.all()
return render_to_response('show.html',locals(),context_instance=RequestContext(request))
models:
class Post(models.Model):
subject = models.CharField(max_length = 250)
body = models.TextField()
thread = models.ForeignKey('self', null = True, editable = False )
Show.html:
{% for post in post_list %}
{{post.id}}{{post.subject}}
{% endfor %}
{% for post_like in post_likes %}
{% if post_like.post_id == post.id and post_like.user_id == user.id %}
U like this post{{post}}
{% else %}
{{post}}
{% endif %}
{% endfor %}
In the show.html, else part, it displays the values again and again. But i need only one time.How can i break the for loop when i enter into else condition.Please help me..
Django's for tag doesn't provide you with any means to break out of the loop. You'll simply have to filter the collection in your own view and slice it after the point your condition fails and supply that to your template.
You can use the django custom template tag found in this django snippets page. If you have doubts on using it, go to this page to learn about custom template tags.
Then load the template tag in your template using {% load loop_break %}. Then you can break the for loop as given below:
{% for post_like in post_likes %}
{% if post_like.post_id == post.id and post_like.user_id == user.id %}
U like this post{{post}}
{% else %}
{{post}}
{{ forloop|break }}
{% endif %}
{% endfor %}
Here the for loop will break when it enters the else part.
you could probably use ifchanged tag:
https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs#ifchanged
However, you probably should consider moving this logic to view.
If you can structure your if statement to detect when you want to output nothing, you can simply put nothing inside your else clause:
{% for post_like in post_likes %}
{% if post_like.post_id == post.id and post_like.user_id == user.id %}
U like this post{{post}}
{% else %}
{% if forloop.first %}
{{post}}
{%else%}{%endif%}
{% endif %}
{% endfor %}
The above might not do quite what you want - you will have to tweak it yourself. The only thing you can't do is set a flag that this is the first entry into the else clause.