Outputting a table to a template - django

I recently began to study Django and cannot understand how to correctly implement the template (table)
I have a model:
She has ties to Company and bank.
class BankAccount(models.Model):
company = models.ForeignKey('Company.Company', null=True, on_delete=models.CASCADE, verbose_name='Фирма',
related_name='company')
bank = models.ForeignKey('Bank', null=True, on_delete=models.CASCADE, verbose_name='Банк', related_name='bank')
login_bank = models.CharField(max_length=255, verbose_name='Логин', null=False)
password_bank = models.CharField(max_length=255, verbose_name='Пароль', null=False)
date_created = models.DateTimeField(auto_now=True)
date_updated = models.DateTimeField(auto_now_add=True)
balance = models.DecimalField(max_digits=15, decimal_places=2, blank=True, null=True)
In the template I want to display a table where all firms / banks will be displayed at the intersection of these columns and rows, a value from this model will appear.
I've been looking for an answer for 5 days and
Company1
Company2
Company3
Company4
Bank1
Balance(Company1/Bank1)
Balance(Company2/Bank1)
Balance(Company/Bank1)
Balance(Company4/Bank1)
Bank2
Balance(Company1/Bank2)
....
....
....
Bank3
Balance(Company1/Bank3)
....
....
....
I tried the example template below, thanks
#Linh Nguyen
<table class="table table-bordered">
<tr>
<th> </th>
{% for company in companies %}
<th>{{ company.name }}</th>
{% endfor %}
</tr>
{% for bank in banks %}
<tr>
<td>{{bank.name}} </td>
{% for company in companies %}
{% for account in bank_accounts %}
{% if account.company_id == company.id and bank.id == account.bank_id %}
<td>{{account}}</td>
{% endif %}
{% endfor %}
{% endfor %}
</tr>
{% endfor %}
</table>
context = {
'companies': Company.objects.all().order_by('id'),
'banks': Bank.objects.all().order_by('id'),
'bank_accounts': BankAccount.objects.all()
}
But the result is still not desired. One firm can have 2 and 4 accounts in the table of accounts (bank_account).
and if the company does not have all 4 accounts, the data no longer match.If you add {% else%}, then the table breaks completely.
screen
<div class="col-md-12">
<div class="row">
<table class="table table-bordered">
<tr>
<th> </th>
{% for company in companies %}
<th>{{ company.name }}</th>
{% endfor %}
</tr>
{% for bank in banks %}
<tr>
<td>{{bank.name}} </td>
{% for company in companies %}
<td>
{% for account in bank_accounts %}
{% if account.company_id == company.id and bank.id == account.bank_id%}
{{account}}
{% endif %}
{% endfor %}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>
</div>
</div>
Finally it worked out!

I think it only come down to how you handle the logic in the looping:
in your view you have the querysets for all the banks, companies and bank accounts
view.py:
context = {
'companies': Company.objects.all(),
'banks': Bank.objects.all(),
'bank_accounts': BankAccount.objects.all()
}
template.html:
<table style="width:100%">
<tr>
{% for company in companies %}
<th>{{ company.name }}</th>
{% endfor %}
</tr>
{% for bank in banks %}
<tr>
{% for company in companies %}
{% for bank_account in bank_accounts %}
<td>
{% if bank_account.company == company %}
Balance({{ company.name }}/{{ bank.name }})
{% endif %}
</td>
{% endfor %}
{% endfor %}
</tr>
{% endfor %}
</table>

First, you should implement your view function like this:
from django.shortcuts import render
from models import BackAccount
def get_bank_accounts(request):
accounts = BankAccount.objects.all()
context = {
'accounts': accounts,
}
return render(request, 'accounts.html', context)
So, that way you send all accounts to the template. And the way you use them in accounts.html like this:
{% for account in accounts %}
{{ account.bank }}
{{ account.company }}
{% endfor %}

Related

Custom format an inline formset

I'm create a template in Django, adding a form and formset to the template, but I don't like how it's formatting the formset by default. I've tried .as_table and .as_ul, but it's not formatting it to my liking. I'd like to see the following from the formset:
Ingredient Percentage Delete
ingredient1 .55
ingredient2 .22
ingredient3 .33
I've tried the code in "https://stackoverflow.com/questions/17492374/how-to-render-formset-in-template-django-and-create-vertical-table" but when I implement it, I'm getting two extra column, "ID" and "Recipe Name". I don't know where those columns are coming from and I don't know how to get rid of them.
Example:
models.py
class Recipe(models.Model):
name = models.CharField(max_length=200, null=True)
description = models.CharField(max_length=200, null=True, blank=True)
def __str__(self):
return self.name
class Recipe_Ingredient(models.Model):
recipe_name = models.ForeignKey(Recipe, null=True, on_delete = models.SET_NULL)
ingredient = models.ForeignKey(Product, null=True, on_delete= models.SET_NULL)
recipe_percent = models.DecimalField(max_digits=8, decimal_places=5, blank=True)
views.py
def recipeUpdate(request, recipe_id):
RecipeIngredientFormSet2 = inlineformset_factory(Recipe, Recipe_Ingredient, extra=10, fields=('ingredient', 'recipe_percent'))
recipe = Recipe.objects.get(pk=recipe_id)
formset = RecipeIngredientFormSet2(instance=recipe)
context = {'formset' : formset}
return render(request, 'accounts/recipe_form.html', context)
recipe_form.html
{% extends 'accounts/main.html' %}
{% load static %}
{% block content %}
<div class="row">
<div class="col-md-6">
<div class="card card-body">
<form action="" method="POST">
{{ form }}
<p></p>
<!--{{ formset.as_table }}-->
<p></p>
{{ formset.management_form}}
<!--{% for form in formset %}
{{ form }}
{% endfor %}-->
<table>
<thead>
{% for form in formset %}
{% if forloop.first %}
{% for field in form %}
<th>{{ field.label_tag }}</th>
{% endfor %}
{% endif %}
</thead>
<tbody>
<tr>
{% for field in form %}
<td>{{ field }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
<input type="submit" name="Submit">
</form>
</div>
</div>
</div>
{% endblock %}
Found the answer. You've got to add the formset with a .management_form tag, then in table, loop through each form in form set. If it's the first loop, add the headers to the tables. In all other loops, add each field from the form that you want in the table.
The updated HTML that I'm using is below.
{% extends 'accounts/main.html' %}
{% load static %}
{% block content %}
<div class="row">
<div class="col-md-6">
<div class="card card-body">
<form action="" method="POST">
{% csrf_token %}
{{ form }}
{{ formset.management_form }}
<table>
{{ form.id }}
{% for p in formset %}
<tr>
{% if forloop.first %}
<td>{{ p.DELETE.label_tag }}</td>
<td>{{ p.ingredient.label_tag }}</td>
<td>{{ p.recipe_percent.label_tag }}</td>
<p></p>
{% endif %}
</tr>
<!--{{ p.id }}
{{ p.ORDER }}-->
<tr></tr>
<td>{{ p.DELETE }}</td>
<td>{{ p.ingredient }}</td>
<td>{{ p.recipe_percent }}</td>
</tr>
{% endfor %}
</table>
<input type="submit" name="Submit">
</form>
</div>
</div>
</div>
{% endblock %}

Cant write correct queryset in Django

i have three models:subplan,subplanfeature and price.I wanna show gym price table,but it shows wrong result
class SubPlan(models.Model):
title = models.CharField(max_length=150)
def __str__(self):
return self.title
class SubPlanFeature(models.Model):
title = models.CharField(max_length=150)
def __str__(self):
return self.title
class Price(models.Model):
gym=models.ForeignKey(Gym,on_delete=CASCADE)
subplan=models.ForeignKey(SubPlan,on_delete=CASCADE,related_name='subplans')
feature=models.ForeignKey('SubPlanFeature',on_delete=CASCADE,related_name='features')
price = models.IntegerField()
highlight_status = models.BooleanField(default=False,null=True)
here is my view
def pricing(request,slug):
gym=models.Gym.objects.get(slug=slug)
price=models.Price.objects.all()
banners=models.Banners.objects.filter(gym=gym)
plans1= models.Price.objects.filter(gender='man',gym=gym)
dfeatures1=models.Price.objects.filter(gender='man',gym=gym)
return render(request, 'pricing.html',{'plans1':plans1,'dfeatures1':dfeatures1,'gym':gym})
and template here
<thead>
<tr>
<th style="width: 34%;"></th>
{% for plan in plans1 %}
<th style="width: 22%;">{{plan.subplan}}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for feature in dfeatures1 %}
<tr>
<th scope="row" class="text-start">{{feature.feature}}</th>
{% for plan in plans1 %}
<td>
{{plan.price}} Azn.
</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
it should display as this
enter image description here
but shows this
enter image description here
what should i change?
you can use "forloop" counter in template
...
{% for feature in dfeatures1 %}
<tr>
<th scope="row" class="text-start">{{feature.feature}}</th>
{% for plan in plans1 %}
<td>
# only print when counter in parent loop are the same
{% if forloop.parentloop.counter == forloop.counter %}
{{plan.price}} Azn.
{% endif %}
</td>
{% endfor %}
</tr>
{% endfor %}

Django - How to change dropdown form into table

I'm creating an application in Django and I'm having an issue with iterating through options in a dropdown from a form in Django. I was wondering if anyone could be of assistance.
detail.html
{% for subject in subject_list %}
<form action="" method="POST">
{% csrf_token %}
<table class='table table-borderless table-hover'>
<tbody>
<tr>
<td>{{ subject.subjectname }}
{% for field in form %}
{{ field.hidden }}
{% endfor %}
</td>
</tr>
</tbody>
</table>
<button type="submit" id="login-btn" class="btn">Create a new evaluation</button>
</form>
{% endfor %}
forms.py
class CreateEvalForm(forms.ModelForm):
subjectname = ModelChoiceField(queryset=Subject.objects, label='', empty_label="Choose subject..")
class Meta:
model = Evaluation
fields = ['subjectname', ]
models.py
class Subject(models.Model):
id = models.AutoField(primary_key=True)
subjectname = models.CharField(max_length=255, help_text="Type the name of the subject.")
slug = models.SlugField(max_length=200, unique=True)
Ideally we want it to look like on the picture below:
Note that the picture is in danish and Fag = Subject, Opret ny evaluering = Create new evaluation and Se evaluering = View evaluation
we want this
we don't want this
I solved this with the help from the comments by changing my for loop and table to this:
<form action="" method="POST">
{% csrf_token %}
<table class='table table-borderless table-hover'>
{% for option in form.fields.fagnavn.choices %}
{% if not forloop.first %}
<tbody>
<tr>
<td>{{ option.1 }}</td>
<td><button value="{{ option.0 }}" name="fagnavn">Opret ny evaluering</button></td>
</tr>
</tbody>
{% endif %}
{% endfor %}
</table>
</form>
I gained access to the choices in the dropdown with form.fields.fagnavn.choices and excluded the default value of "choose value" with an if statement of {% if not forloop.first %}
And that's pretty much it.

Django how to display list users with some data in template

I want to display the list of users with some objects in 2 modelapps created.
these are the models.
first model:
class UserProfile(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
indirizzo = models.CharField(max_length=50)
citta = models.CharField(max_length=50)
paese = models.CharField(max_length=50)
ecap = models.CharField(max_length=4)
descrizione = models.CharField(max_length=100, default='')
image = models.ImageField(upload_to='profile_image', blank=True,null=True)
second model:
class Ore(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="ore",null=True,)
data = models.DateField(default=timezone.now)
oret = models.CharField(max_length=3,)
contrattiok = models.PositiveSmallIntegerField()
contrattiko = models.PositiveSmallIntegerField(default=0,)
nomecognome = models.CharField(max_length=100,blank=True)
my view:
def inizio(request):
users = User.objects.all()
return render (request, "base.html", {"users":users})
my template:
{% for users in users %}
<tbody>
<tr>
<td>
<img src="{{ users.userprofile.image.url }}"class="thumbnail">
<h4 class="small font-weight-bold">{{users}}</h4>
</td>
<td><h4 class="small font-weight-bold">{{users.last_name}}</h4></td>
<td class="text-center">
<h4 class="small font-weight-bold" class="btn btn-primary btn-circle">{{ users.ore.contrattiok }}</h4> <<<<<(does not work)
</td>
</tr>
{% endfor %}
I saw several problems in your templates.
1. It would be better to make different variable of users loop to increase readability code.
don't do this: {% for users in users %}
but instead: {% for user in users %}
so then you can use it with user instead of users inside loop like:
{{ user.last_name }}
2. your <tbody> inside forloop users, but theres no </tbody> right before the {% endfor %}.
But I suggest you to do not include <tbody> inside forloop.
Do this instead:
<tbody>
{% for user in users %}
<tr><td></td></tr>
{% endfor %}
</tbody>
since your foreign key is inside Ore model instead
(one to many relationship which means 1 user has many ores),
so you need to loop every ore on each user.
{% for user in users %}
{% for ore in user.ore.all %}
{{ ore.contrattiok }}
{% endfor %}
{% endfor %}
so the final result will be like this:
<tbody>
{% for user in users %}
<tr>
<td>
<img src="{{ user.userprofile.image.url }}" class="thumbnail">
<h4 class="small font-weight-bold">{{ user }}</h4>
</td>
<td><h4 class="small font-weight-bold">{{user.last_name}}</h4></td>
<td class="text-center">
{% for ore in user.ore.all %}
<h4 class="small font-weight-bold" class="btn btn-primary btn-circle">
{{ ore.contrattiok }}
</h4>
{% endfor %}
</td>
</tr>
{% endfor %}
</tbody>
EDITED
based on your comment, so you want to sum the total of contrattiok field?
if that so, you need to change your view using annotate
from django.db.models import Sum
users = User.objects.annotate(total_contrattiok=Sum('ore__contrattiok'))
then in your template:
{% for user in users %}
<td class="text-center">
<h4 class="small font-weight-bold" class="btn btn-primary btn-circle">
{{ user.total_contrattiok }}
</h4>
</td>
{% endfor %}

Setting specific day to print specific message in the django template

Here is my model:
class Sitting(models.Model):
sit_date = models.DateField(blank=False)
cut_off_date = models.DateField(null=True, blank=True)
ballot_date = models.DateField(null=True, blank=True)
sess_no = models.ForeignKey(Session,
on_delete=models.CASCADE)
genre = TreeForeignKey('Genre', null=True, blank=True, db_index=True)
here is my view:
def sitting_list(request):
sitting=Sitting.objects.select_related('genre')
return render(
request,
'genre/sitting_list.html',
{'sittings':sitting, }, )
Here is my template:
{% block content %}
<table>
<tr>
<th>Sitting Day & Date</th>
<th>Ministry/Division</th>
<th>Ballot Date</th>
</tr>
{% for sitting in sittings %}
<tr>
<td> {{ sitting.sit_date|date:"l, d F, Y" }}</td>
{% for genre in sitting.genre.get_descendants %}
<td> {{ genre }},</td>
{% endfor %}
<td>(Ballot: {{ sitting.ballot_date}})</td>
</tr>
<tr>
</tr>
{% endfor %}
</table>
{% endblock %}
It gave following output:
Edit :
But I want following output:
You can see from my desired output, Ministry's name only come when no division exists. Moreover numbering and last full stop also not coming.
I hope this can also be fixed with your help.
You just need to add an if statement to see if the weekday is 2 (0-6 mon-sun)
<td>
{% if sitting.sit_date.weekday == 2 %}
extra stuff
{% endif %}
{% for genre in sitting.genre.get_descendants %}
{{ genre }},
{% endfor %}
</td>
Note: Also moved the td so you get the formatting style you wanted.