How do properly make an if statement in html - python

Im supposed to write an if statement in a detail.html template that states "if project has tasks" display a table otherwise display "no tasks in project.
I've tried
{% if task in project %}
{% if task in projects_list %}
{% if tasks in project %}
"displays table"
{% else %}
<p>no tasks for this project</p>
{% endif %}
here is my task model
class Task(models.Model):
name = models.CharField(max_length=200)
start_date = models.DateTimeField()
due_date = models.DateTimeField()
is_completed = models.BooleanField(default=False)
project = models.ForeignKey(
"projects.Project",
related_name="tasks",
on_delete=models.CASCADE,
)
assignee = models.ForeignKey(
settings.AUTH_USER_MODEL,
null=True,
related_name="tasks",
on_delete=models.SET_NULL,
)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse("show_my_tasks")
here is the view for projects
class ProjectListView(LoginRequiredMixin, ListView):
model = Project
template_name = "projects/list.html"
context_object_name = "projects_list"

If project is a list you probably want:
{% if project|length > 0 %}
Similar question Check if an array is not empty in Jinja2

If I'm understanding correctly, you want to check if a project has any relationship with a task. If this is so, you can refer to the project attribute on the Task model by using the related_name which is tasks in the template. For example:
# using project.tasks to check for an existing relationship with project and task;
# calling the count method as well to count how many tasks are connected to a project within the loop.
{% if project.tasks.count > 0 %}
# Displaying the table in here with the project's task info...
{% else %}
<p> no tasks for this project </p>
{% endif %}
Ideally, your for loop would look something like:
{% for project in projects_list %}
...
{% if project.tasks.count > 0 %}
# Displaying the table in here with the project's task info...
{% else %}
<p> no tasks for this project </p>
{% endif %}
...
{% endfor %}
That should work.

Partial answer, too long to add as a comment. You often don't need to handle the case of an empty list or set outside of the for loop. Instead:
{% for task in project.tasks %}
{% if forloop.first %}
<table> ... and table header
{% endif %}
<tr>
... stuff involving display of {{task.field}}s
</tr>
{% if forloop.last %}
</table> ... and any other table footer stuff
{% endif %}
{% empty %} ... optional
stuff to show if there are no tasks
{% endfor %}

Related

Render relationship model in template

I am trying to render a model with a relationship but I am not able to do so.
class LogBook(models.Model):
name = models.CharField(max_length=50, verbose_name="Nom du registre de maintenance")
members = models.ManyToManyField(User)
class LogMessages(models.Model):
logbook = models.ForeignKey(LogBook)
message = models.CharField(max_length=200, verbose_name="Détail du problème")
class LogDone(models.Model):
logmessage = models.ForeignKey(LogMessages)
message = models.CharField(max_length=200)
My view:
log = get_object_or_404(LogBook, pk=log_id)
logmessages = LogMessages.objects.filter(logbook=log_id)
My template
{% for logmessage in logmessages.all %}
{{logmessage.logdone.message}}
{{% endfor %}}
But the logdone object is not showing, any idea ?
Since your LogMessage model has a foreign key to log done, it's not a One to One relation and you have to access the related LogDone objects using the _set notation. There's also a slight typo, I believe. It should logmessages and not logmessages.all
{% for logmessage in logmessages %}
{% for done in logmessage.logdone_set.all %}
{{ done.message }}
{% endfor %}
{% endfor %}
I forgot that I added a related_name equal to "logdones" so I did the following :
{% for logmessage in logmessages %}
{% for done in logmessage.logdones.all %}
{{ done.message }}
{% endfor %}
{% endfor %}
And now it is working, thanks to #Vishal

Django: How to display author of query of posts?

I'm trying to make individual pages for each author showing their name and posts. I can't seem to get the username displayed.
views.py
class UserProfileView(generic.ListView):
template_name = 'howl/user-profile.html'
context_object_name = 'user_howls'
def get_queryset(self):
author = self.request.user
u = User.objects.get(username=author)
return Howl.objects.filter(author=u)
models.py
class Howl(models.Model):
author = models.ForeignKey(User, null=True)
content = models.CharField(max_length=150)
Here is where I'm stuck.
user-profile.html
{% extends 'howl/base.html' %}
{% block content %}
<h1>User: {{user_howl.author}}</h1>
{% for user_howl in user_howls %}
<ul>
<li>{{user_howl.content}}</li>
</ul>
{% endfor %}
{% endblock %}
The content is displayed just fine, but the heading just says "User: ", how do I give it a context without using a for loop?
I've tried:
{% for author in user_howls.author %}
<h1>User: {{author}}</h1>
{% endfor %}
and
{% if user_howls.author %}
<h1>User: {{user_howl.author}}</h1>
{% endif %}
Still the same outcome, displaying "User: "
user_howls is a queryset so it won't have an author attribute, you need to get the author of the iterated object
{% for howl in user_howls %}
<h1>User: {{ howl.author}}</h1>
{% endfor %}
More to the point though, it doesn't make sense to start from a Howl list, when you are just returning the results for the user_profile, nor does it make sense to use a ListView. so instead, start from the user and then look up its howls
user_obj.howl_set.all()
Since your queryset is based on the posts belonging to the current user, you can shortcut all of this and just show the user directly:
User: {{ user }}

Custom template tags

I have a model name "Attendee". In that there are foreignkeys as user and model named "Event".
Now I have to get the users of Attendee who are going for event.
{% get_event_attendee event as attending_event %}
it works for me. But I need this step with "for",
I mean
{% get_event_attendee for event as attending_event %}
Please help.
Thanks
Here you go.
https://djangosnippets.org/snippets/1919/
Previous I had a damn thing to do. Go through with that you will definitely crack that :)
If your models look like this
from django.db import models
class User(models.Model):
...
class Event(models.Model):
...
class Attendee(models.Model):
user = models.ForeignKey(User)
event = models.ForeignKey(Event)
you can access the attendees in the template like this:
{% for attendee in event.attendee_set.all %}
{{ attendee.user }}
{% endfor %}
Is this your question?
If you have multiple events you can use two forloops:
{% for event in event_list %}
{% for attendee in event.attendee_set.all %}
{{ attendee.user }}
{% endfor %}
{% endfor %}

Foreign Key - how to solve this in template - django

i have 3 models:
Book, Topiccenter and EntryBook.
these are model definitions:
class Book(models.Model):
title = models.TextField()
language = models.TextField()
class Topiccenter(models.Model):
title = models.TextField():
description = models.TextField()
class EntryBook(models.Model):
book = models.ForeignKey(Book,related_name="b_entries")
topiccenter = models.ForeignKey(Topiccenter,related_name="tc_books")
Now I am in Topiccenter T. and i search for books and get all books in DB. As you see, each book can be in multiple topiccenters.
What i want to do is, in the search result, i want to show whether each book is contained in current Topiccenter or not:
I will take all books books = Book.objects.all() and the current topiccenter as tc and render them to template and in template,
{% for book in books %}
{% for entry in book.b_entries.all %}
{% if entry.topiccenter.id == tc.id %}
already in this Topiccenter
{% else %}
add to this topiccenter
{% endif %}
{% endfor %}
{% endfor %}
but the problem is that one book is in two topiccenters and in template i am getting both already in this Topiccenter and add to this topiccenter which is nonesense. How can i repair my logic so that I can check if the book in this current topiccenter, and if not, show them add button
thanks
See how you can move it to the view. In this case, get all books associated with the tc and send that in the context.
Now, the template logic would be:
{% for book in books %}
{% if book in tc_books %}
already in this Topiccenter
{% else %}
add to this topiccenter
{% endif %}
{% endfor %}
Where (in the view)
tc_books = Books.objects.filter(b_entries__topiccenter = tc)
and send that in the context

django regroup templatetag does not group properly

I have following template
{% regroup product.hotel.facilities.all by facilitytype as facilities %}
{% for facility in facilities %}
<h5>{{ facility.grouper }}</h5>
<p class="tab-content-title bld">
{% for i in facility.list %}
<li>{{ i }}</li>
{% endfor %}
{% endfor %}
And following model structure:
class Hotel(TranslatableModel):
code = models.CharField(max_length=255)
facilities = models.ManyToManyField('hotels.Facility',null=True)
class Facility(TranslatableModel):
code = models.CharField(max_length=255, unique=True)
facilitytype = models.ForeignKey(FacilityType, null=True, blank=True)
translations = TranslatedFields(
name=models.CharField(max_length=255, blank=True),
)
But when I run the page i see below. Instead I want to see the list grouped and distinct by facility_types:
Any ideas?
You have to sort your data by the grouper field first.

Categories

Resources