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.
Related
{% if "Anonymous" == i.verifiedUser %} doesnt seem to work despite i.verifiedUser being valid. I can write anything else where "i.verifiedUser" is, and it will still show the same. How can i fix this?
index.html:
<div class="comments">
{% for i in comment %}
{% if "Anonymous" == i.verifiedUser %}
<small>{{i.verifiedUser}}</small>
{% else %}
<small class="verifiedUser">{{i.verifiedUser}}</small>
{% endif %}
{% endfor %}
</div>
views.py:
def question(request, questionId):
question = Qna.objects.get(id=questionId)
comment = Comment.objects.filter(questionId=questionId).order_by('-timestamp')
otherQuestions = Qna.objects.all()[:10]
return render(request, 'index/question.html', {'question':question, 'comment':comment, 'otherQuestions':otherQuestions})
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'm looping through a result set and when a certain condition is met I want to run through a conditional statement. After that condition has been met I want to continue looping through the result set without running through that condition.
Does anyone have any ideas on how I could go about this?
Edit:
Here is what I'm trying to achieve.
{% flag = false %}
{% for row in results %}
{{ row.field }}
{% if row.is_active and !flag %}
<br />
{% flag = true %}
{% endif %}
{% endfor %}
It seems that you want to do one thing with the first part of the QuerySet, and other thing with the rest. Split it in the view.
views.py
def split_list(list, condition):
list1, list2 = [], []
condition_satisfied = False
for element in list:
if not condition_satisfied and condition(element):
condition_satisfied = True
if not condition_satisfied:
list1.append(element)
else:
list2.append(element)
return list1, list2
def your_view(request):
results = YourModel.objects.all()
results1, results2 = split_list(results, condition)
return render(request, 'template.html', {
'results1': results1,
'results2': results2
})
template.html
{% for result in results1 %}
{% if result == whatever %}
<p>Condition satisfied</p>
{% else %}
<p>Condition not satisfied</p>
{% endif %}
{% endfor %}
{% for result in results2 %}
{{ result }}
{% endfor %}
Django doesn't have this feature, and for good reason. Templates should not contain this kind of logic. It should be done within the View.
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 %}
I am trying to run two tests:
{% if profile.id != 100 or profile.location == NULL %}
however it seems to not work. I couldn't find in the docs why this isn't working. Any ideas?
EDIT:
In the SQL db, the value for profile.location is NULL. The rendered result is None.
EDIT 2:
Here is the full chain. There are 4 ways to grab a user's location. It is a giant mess as you can see...
{% if profile.city.id != 104 or profile.city %}
{{profile.city}}
{% else %}
{% if profile.mylocation != '' %}
{{ profile.mylocation }}
{% else %}
{% if profile.fbconnect == 1 and profile.location != '' and profile.location != "None" %}
{{profile.location}}
{% else %}
{% if profile.sglocation.city %}{{profile.sglocation.city}}{% else %}{{profile.sglocation.country}}{% endif %}
{% endif %}
{% endif %}
{% endif %}
There's no NULL. Try:
{% if profile.id != 100 or not profile.location %}
If I were you, I would throw all that logic back into Python, for example:
class Profile(models.Model):
[your model fields and stuff]
def get_location(self):
[your location logic]
Then in the template you can just do:
{{ profile.get_location }}