Getting M2M field data in template Django - html

I want to get m2m data in my template through the views but failing to do so. The thing is that I'm able to show the data of m2m field looping it from template itself but it does slow down the website.
My Team apps Model looks like this:
class Team(models.Model):
title = models.CharField(max_length=255)
team_country = CountryField(max_length=200, blank=True, null=True)
members = models.ManyToManyField(User, related_name='teams')
created_by = models.ForeignKey(User, related_name='created_teams', on_delete=models.CASCADE)
Now in my tournament app I'm trying to get "members" of the team.
My Tournamet Views look like this:
def tournament_page(request, slug):
page = 'tournament_page'
user = request.user
tournament = Tournament.objects.get(slug=slug)
players = tournament.participants.select_related('user')
all_players = Profile.objects.select_related('user')
side_tourneys_ongoing = Tournament.objects.filter(state='Ongoing')[:10]
side_tourneys_upcoming = Tournament.objects.filter(state='Upcoming')[:10]
side_tourneys_completed = Tournament.objects.filter(state='Completed')[:10]
teams = Team.objects.select_related('created_by')
context = {
'page': page,
'tournament': tournament,
'side_tourneys_ongoing': side_tourneys_ongoing,
'side_tourneys_upcoming': side_tourneys_upcoming,
'side_tourneys_completed': side_tourneys_completed,
'teams': teams,
'players':players,
'all_players':all_players
}
Now I'm able to show the teams with their members in the template using for loop inside the template itself as:
Html template
<div class="grid-x">
{% for team in teams %}
{% for player in players %}
{% if team.id == player.active_team_id and team.game == tournament.game %}
<div class="wf-card event-team">
<div> {{team.title}} </div>
<div class="event-team-players">
{% for member in team.members.all %}
{{ member.username }}
{% endfor %}
</div>
</div>
{% endif %}
{% endfor %}
{% endfor %}
</div>
What I want is to use this piece of code
{% for member in team.members.all %}
{{ member.username }}
{% endfor %}
in my views since it causes the website to slow down and idk why.
What I tried in my views is:
all_teams = Team.objects.all()
members = all_teams.members.all()
and
members = Team.objects.all().prefetch_related('members')
First one throws an error:
'QuerySet' object has no attribute 'members'
Second one shows lots of blank records
Tried almost everything with search but none of them helped except using the code that I provided directly in the template itself.

Edited based on comments below. You should be able to do this more simply by prefetching team members.
views.py
def tournament_page(request, slug):
page = 'tournament_page'
user = request.user
tournament = Tournament.objects.get(slug=slug)
all_players = Profile.objects.select_related('user')
side_tourneys_ongoing = Tournament.objects.filter(state='Ongoing')[:10]
side_tourneys_upcoming = Tournament.objects.filter(state='Upcoming')[:10]
side_tourneys_completed = Tournament.objects.filter(state='Completed')[:10]
teams = Team.objects.select_related('created_by').prefetch_related('members')
template.html
<div class="grid-x">
{% for team in teams %}
{% if team.game == tournament.game %}
<div class="wf-card event-team">
<div> {{team.title}} </div>
<div class="event-team-players">
{% for member in team.members.all %}
{{ member.username }}
{% endfor %}
</div>
</div>
{% endif %}
{% endfor %}
</div>

Related

How to store and display datetime field of a Model according to the end user's location in django?

models.py
class PostModel(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
date_time = models.DateTimeField(auto_now_add=True)
title = models.TextField(null=True)
body = models.TextField(null=True)
def __str__(self):
return str(self.user)
.html
{% extends 'base.html' %}
{% block content %}
{% for post in posts %}
{{post.date_time}}
<br>
{{post.title}}
<br>
{{post.body}}
<br>
{% for image in post.imagespostmodel_set.all %}
<img src="{{image.images.url}}" alt="postimage" style="width: 300px;">
<br>
{% endfor %}
<hr>
<hr>
{% endfor %}
{% endblock %}
I have to specifically set the timezone in setting.py, but I want to display the time according the user location.
Django has inbuilt functionality for handling timezones. Reading the documentation at Django Timezone Documentation should help you out. An example is provided there.

Trouble rendering results from searchbar in Django

I have been working on a search bar in django and I am close but having some issues rendering the results to the page.
Views.py
class SearchResultsView(ListView):
model = Project
template_name = 'search_results.html'
def get_queryset(self):
proj=self.request.GET.get('proj')
proj_list=Project.objects.filter(
Q(name__icontains=proj) | Q(projectTag__icontains=proj)
)
proj_list1=Project.objects.filter(
Q(department__icontains=proj)
)
proj_list2 = list(set(proj_list) & set(proj_list1))
return proj_list2
class SearchPageView(TemplateView):
template_name = 'searchbar.html'
search_results.html
{% extends 'main/base.html' %}
<html>
{%block content%}
<h1> Search Results </h1>
{% if proj %}
<ul>
{% for project in proj_list2%}
<li>
{{project.name}}, {{project.department}}, {{project.projectTag}}
</li>
{% endfor %}
</ul>
{% else %}
<h2>sorry, no results</h2>
{% endif %}
{%endblock%}
</html>
Whenever I search something that should definitely yield results, I get "sorry, no results."
Thank you. Please help me to understand my disconnect. The bigger aim for this is to then add different models to query from (i.e. not just search in projects, but also search by user).
You are checking the wrong variable. The collection of elements is object_list, not proj or proj_list2:
{% if object_list %}
<ul>
{% for project in object_list %}
<li>
{{project.name}}, {{project.department}}, {{project.projectTag}}
</li>
{% endfor %}
</ul>
{% else %}
<h2>sorry, no results</h2>
{% endif %}
The search is also quite odd, you only retrieve items if both the department and the name or the tag matches. We can simplify this to:
class SearchResultsView(ListView):
model = Project
template_name = 'search_results.html'
def get_queryset(self):
proj = self.request.GET.get('proj')
return =Project.objects.filter(
Q(name__icontains=proj) | Q(projectTag__icontains=proj),
department__icontains=proj
)
but it is odd that the department and the name for example should match. If you want to match any of the three, we can work with:
class SearchResultsView(ListView):
model = Project
template_name = 'search_results.html'
def get_queryset(self):
proj = self.request.GET.get('proj')
return =Project.objects.filter(
Q(name__icontains=proj) |
Q(projectTag__icontains=proj) |
Q(department__icontains=proj)
)

Django-How do i get the HTML template to show data from the two models?

So i'm creating a to-do app. How do I get the html view to show the tasks? I tried to show the name of the tasks but it's blank. So far, it only shows the board name and the user who created it.
Here is my code so far:
Models.py
class Board(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
admin = models.ForeignKey(User, on_delete=models.CASCADE, related_name="Board")
name = models.CharField(max_length=200)
class Task(models.Model):
board = models.ForeignKey(Board, on_delete=models.CASCADE)
admin = models.ForeignKey(User, on_delete=models.CASCADE)
text = models.CharField(max_length=300)
complete = models.BooleanField(default=False)
assigned_to = models.CharField(max_length=30)
views.py
def board_post_detail(request, board_id):
obj = get_object_or_404(Board, id=board_id)
taskobj= Task.objects.filter(board=obj)
context = {"object": obj, "tasks": taskobj}
return render(request, 'boards/board_post_detail.html', context)
board_post_detail.html
{% block content %}
<h1>{{ object.name}}</h1>
<p> {{tasks.text}}<p>
<p>Created by {{object.admin.username }}</p>
{% endblock %}
I realise that I needed to use a for loop to iterate throught the tasks.
{% block content %}
<h1>{{ object.name}}</h>
<ul>
{% for task in tasks %}
<li>{{ task.text }} is assigned to {{ task.assigned_to }}</li>
{% endfor %}
</ul>
<p>Created by {{object.admin.username }}</p>
{% endblock %}

How to display multiple images for django model

Here is my image model, that I tied to the model Product
class Image(models.Model):
name = models.CharField(blank=True,max_length=20)
product = models.ForeignKey(Product)
image = models.ImageField(blank=True,null=True)
def __str__(self):
return self.name
Here is the view that I am using to try and display the images
def category(request, category_id):
categories = Category.objects.all()
images = Image.objects.all()
products = Product.objects.all()
try:
category = Category.objects.get(id=category_id)
except Category.DoesNotExist:
category = None;
template = loader.get_template('index.html')
context = {
'category': category,
'categories': categories,
'images': images,
'products': products
}
return HttpResponse(template.render(context,request))
and here is the html
{% for image in images %}
<img src="{{ image.url }}">
{% endfor %}
I know this definitely wouldn't work,but atleast this code displays the page instead of an error so i have been using it, can anyone please point me in the right direction to dipslay each image associated with each product.
Thank you!
You can try this:
{% for product in products%}
<p> {{product.name}} </p>
{% for simage in product.image_set.all %}
{% if simage.image%}
<img src="{{ simage.image.url }}">
{% endif %}
{% endfor %}
{% endfor %}

Django HTML for loop not showing corresponding values

I am using a for loop in an HTML Template, it recognizes the fact that they are there but it does not show them in the page like it should.
my views:
person = []
x = people.objects.filter(deal='q')
for person in x:
print(person.name)
if person.paid_status == True:
person.append(lender)
return render(request, '.html', {'person': person})
my template:
<div>
{% if person %}
There are {{ person|length }} persons.
{% for p in person %}
<p> {{ p.name }} </p>
{% endfor %}
{% else %}
<p> As of now no persons have appeared. </p>
{% endif %}
</div>
in the console it prints the persons name correctly so I am confused why it does not work in the HTML
All I see is that there are 2 persons(which is correct) but then it does not list them.
Thanks in advance.
You are overwriting the variable person inside your loop.
Change the list person to persons and it should work fine.
Your view:
persons = []
x = people.objects.filter(deal='q')
for person in x:
if person.paid_status == True:
persons.append(person)
return render(request, '.html', {'persons': persons})
Your template:
<div>
{% if persons %}
There are {{ persons|length }} persons.
{% for p in persons %}
<p> {{ p.name }} </p>
{% endfor %}
{% else %}
<p> As of now no persons have appeared. </p>
{% endif %}
</div>