Django database data not showing in Templete - html

I have a class HardBook that inherits from Book:
class Book(models.Model):
title = models.CharField('Book Title', max_length=200)
image = models.ImageField('Book Cover', upload_to='covers')
description = models.CharField('Description', max_length= 350)
class HardBook(Book):
quantity = models.IntegerField('Quantity')
views.py
class BookCreateView(CreateView):
def get_context_data(self,**kwargs):
context = super(BookCreateView, self).get_context_data(**kwargs)
context['softbooks'] = SoftBook.objects.all()
context['hardbooks'] = SoftBook.objects.all()
return context
I want to display the field data in a table, I want to show title, image and quantity. Everthing is displayed except quantity.
{% for hardbook in hardbooks %}
<tr>
<td>
<div class="cover-image" style="background-image:url({{hardbook.image.url}});"></div>
</td>
<td>{{hardbook.title}}</td>
<td>{{hardbook.quantity}}</td>
</tr>
{% endfor %}

Related

Django: How to display specific object to specific user

I am new to django and working on a project where admin have to assign a team to manager and when ever admin assign a team to manager then it will be shown to that specific manager only.I have no idea how can i do this. Please if someone can help please help me.
here is my .html file for admin from where admin can assign team to manager.
<thead>
<tr>
<th>S No.</th>
<th>COMPANY NAME</th>
<th>TEAM MEMBER</th>
<th>EMAIL</th>
<th>ASSIGN TEAM</th>
</tr>
</thead>
<tbody>
{%for team in object%}
<tr>
<form id="form_id" method="POST" action = "{% url 'accept' %}">
{% csrf_token %}
<th scope="row"> {{ forloop.counter }}</th>
<td>{{team.company_name}}</td>
<td>{{team.team_member}}</td>
<td>{{team.email}}</td>
<td>
<select name="manager_{{manager.id}}">
{% for manager in managers %}
<option value ="{{manager.id}}">{{manager.name}}</option>
{% endfor %}
</select>
</td>
<td>
<input class="btn btn-raised btn-primary btn-round waves-effect" type="submit" value="Assign">
</td>
</tr>
{% endfor %}
here is my model for the team and manager:
class Create_Team(models.Model):
first_name = models.CharField(max_length= 50)
last_name = models.CharField(max_length= 50)
company_name = models.CharField(max_length= 100)
address = models.CharField(max_length= 1000)
state = models.CharField(max_length= 100)
city = models.CharField(max_length= 100)
status = models.CharField(max_length= 30)
class manager(models.Model):
name = models.CharField(max_length= 500)
designation = models.CharField(max_length= 500)
here is my views.py file for manager and from where the admin is accepting the request:
def accept(request):
obj= Create_Team.objects.filter(status='Accept')
managers = manager.objects.all()
if request.method == 'POST':
acc = manager()
manager_id = int(request.POST.get('manager', 1))
acc.manager = manager.objects.get(pk=manager_id)
return render(request, "admin/accept.html", {"object": obj, "managers": managers})
def superior(request):
return render(request, 'manager/index-3.html')
I want that whenever the admin will click on the assign button then that team will be displayed to that manager.Please help me.
There are several issues with your code.
There is no relation from the Create_Team to the manager model.
The name attribute on your <select> tags do not match the key you using to read from request.POST. manager_{{manager.id}} renders as manager_, so int(request.POST.get('manager', 1)) will always return 1.
The forms in your template do not contain the information which team you want to update.
You do not set the attribute selected on any <option>. As a consequence, the first choice will always be selected.
You are not updating any team in your view.
Let's address these issues.
1 - We fix the models by adding a ForeignKey from CreateTeam to Manager. Note that I've renamed the models, which is optional. If you decide to keep your names, adapt it accordingly.
# models.py
from django.db import models
class CreateTeam(models.Model):
first_name = models.CharField(max_length= 50)
last_name = models.CharField(max_length= 50)
company_name = models.CharField(max_length= 100)
address = models.CharField(max_length= 1000)
state = models.CharField(max_length= 100)
city = models.CharField(max_length= 100)
status = models.CharField(max_length= 30)
manager = models.ForeignKey('Manager', on_delete=models.SET_NULL, null=True, blank=True)
class Manager(models.Model):
name = models.CharField(max_length= 500)
designation = models.CharField(max_length= 500)
You have to pass two bits of information to the assign view: the id of the CreateTeam you want to assign and the id of the Manager you want to assign it to.
Note that the name attribute of form fields is the key in request.POST. These can be any string, just make sure it matches between form and view. It obviously makes life to give them an expressive name.
2 - Sending the id of the Manager is handled by the <select>. Just make sure the name attribute matching the key you use in your view.
3 - To send the id of the team, you could use a <button type="submit"> with a name and a value instead of the <input type="submit">.
<button class="btn btn-raised btn-primary btn-round waves-effect" type="submit" name="team" value="{{ team.id }}">Assign</button>
</td>
Alternatively, you could use a hidden field.
4 - Finally, you have to have to set the attribute selected on the correct <option> in your <select>. You can do that like this:
<option value="{{manager.id}}" {% if team.manager.id == manager.id %}selected{% endif %}
Here is the complete template:
<html>
<head></head>
<body>
<table>
<thead>
<tr>
<th>S No.</th>
<th>COMPANY NAME</th>
<th>TEAM MEMBER</th>
<th>EMAIL</th>
<th>ASSIGN TEAM</th>
</tr>
</thead>
<tbody>
{%for team in teams%}
<tr>
<form id="form_id" method="POST" action="{% url 'accept' %}">
{% csrf_token %}
<th scope="row"> {{ forloop.counter }}</th>
<td>{{team.company_name}}</td>
<td>{{team.team_member}}</td>
<td>{{team.email}}</td>
<td>
<select name="manager">
{% for manager in managers %}
<option value="{{manager.id}}" {% if team.manager.id == manager.id %}selected{% endif %}>{{manager.name}}</option>
{% endfor %}
</select>
</td>
<td>
<button class="btn btn-raised btn-primary btn-round waves-effect" type="submit" name="team" value="{{ team.id }}">Assign</button>
</td>
</form>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
5 - When receiving a POST request, you can assign the manager to the team.
That means you have to use the id values to get a CreateTeam instance and a Manager instance. Then you assign the Manager to createteam.manager and save the createteam object.
from django.shortcuts import get_object_or_404, redirect, render
from .models import CreateTeam, Manager
def accept(request):
teams = CreateTeam.objects.filter(status='Accept')
managers = Manager.objects.all()
if request.method == 'POST':
createteam_id = int(request.POST.get('team', 1))
manager_id = int(request.POST.get('manager', 1))
createteam = get_object_or_404(teams, pk=createteam_id)
createteam.manager = get_object_or_404(Manager, pk=manager_id)
createteam.save()
redirect('accept')
return render(request, "admin/accept.html", {"teams": teams, "managers": managers})
There are three things worth highlighting:
We use get_object_or_404 instead of Model.objects.get. As the name implies, it returns a 404 if no model can be found. This serves as a simple error handling for edge cases like a user manipulating the form or a manager being deleted while the user has the page open. This error handling could be improved to be more user-friendly, but it's a start.
get_object_or_404 can take a model or a queryset. We load the team instance from the filtered queryset teams. Otherwise, a user could manipulate a form and assign a manager to a team that has a status other than Accept.
After saving the team, we redirect to the accept page. This is good practice and ensures that a user can reload the page without seeing the do you want to resubmit this form dialog.
Finally, make sure that this view is really only accessible by the admin, e.g. by adding an appropriate user_passes_test decorator.

Table appears empty without any value (Django)

My data are like this :
13.2610136284,20.8676059554,11.6376896892,0.51203356592,167,20154.4815106,
395,766,56,55047.3477967,-26818.1766435,3072.97868784,12.5402166873,-1443.
74556748,-4.0
I need to display it as a table in html
This is the function used in python to transform the data suitable for a table
import string
from datetime import datetime, date
def ratio_fil():
ratioFil = open('sergRatiosOut20170426','r')
rat = ratioFil.read().split(',')
ratioFil.close()
return rat
Rat is similar to this :
['13.2610136284', '20.8676059554', '11.6376896892', '0.51203356592',
'167', '20154.4815106', '395', '766', '56', '55047.3477967',
'-26818.1766435', '3072.97868784', '12.5402166873', '-1443.74556748',
'-4.0\r\n']
I need to put it in a table, So i create a data_table tags :
<tr><td>X</td>
<td>{{data_table.0|floatformat:1}} %</td></tr>
<tr><td>y</td>
<td>{{data_table.1|floatformat:1}} %</td></tr>
<tr><td>y1 </td>
<td>{{data_table.2|floatformat:1}} </td></tr>
<tr><td>y2</td>
<td>{{data_table.3|floatformat:1}} </td></tr>
In Html :
<div> {% with rat as data_table %}
{% include 'tags/data_table.html' %}
{% endwith %}
</div>
The table appears empty, i think it should be a method to import rat ? Please i need your help
You can use builtin for loop template tag to loop through and render the data in HTML table
<table>
<tr>
<th>Column Name</th>
</tr>
{% for data in data_table %}
<td>
<td>{{ data }} </td>
</td>
{% endfor %}
</table>
Remember to return the data from your view
def ratio_fil():
ratioFil = open('sergRatiosOut20170426','r')
rat = ratioFil.read().split(',')
ratioFil.close()
return render(request, 'template_name.html', {'data_table': rat})

New line in html table

My model:
class Affiliation(models.Model):
name = models.CharField(max_length=32)
slug = models.SlugField(unique=True)
descrizione = models.CharField(max_length=500, blank=True, null=True)
class Reg_Affiliation(models.Model):
reg = ...
affiliazione = models.ForeignKey(Affiliation, null=True,
on_delete=models.CASCADE, related_name='affiliation_conoscenza')
My descrizione field (for example):
descrizione = 'line1 <br> line2'
edit: added something about this field, see below /edit
I tried too:
descrizione = "line1 '<br>' line2"
descrizione = 'line1 "<br>" line2'
descrizione = 'line1 \n line2'
descrizione = 'line1 \r\n line2'
My template:
<div class="panel panel-default">
<table class="table table-striped table table-bordered table table-hover table table-condensed">
<thead>
<tr>
<th>Nome</th>
<th>Descrizione</th>
</tr>
</thead>
<tbody>
{% for aff in lista %}
<tr>
<td>
<b>{{ aff.affiliazione }}</b>
</td>
<td>
{{ aff.affiliazione.descrizione }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
I expect:
line1
line2
in the same field of my table, instead I obtain:
line1 <br> line2
My views:
#login_required
def affiliation_list(request):
lista_a=[]
for a in Affiliation.objects.all():
ra=Reg_Affiliation(affiliazione=a,
conoscenza=c,
rapporto=r)
lista_a.append(ra)
context_dict['lista'] = lista_a
return render(request, 'core/affiliation_list.html', context_dict)
I'm using bootstrap, firefox, windows7
Thank you for your help
edit:
maybe it make difference how I add the descrizione field, so:
My populate script:
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'sitoposs.settings')
import django
django.setup()
def populate():
affiliation1 = add_affiliation('name affiliation1', '''long line1 <br> long line2''')
affiliation2 =
...
def add_affiliation(name, descrizione):
a = Affiliation.objects.get_or_create(name=name)[0]
a.descrizione=descrizione
a.save()
return a
if __name__ == '__main__':
populate()
In my database I read
long line1 <br> long line2
In source page (on the browser right click on the page, view source page or something like that, I don't use english version) I read:
long line1 <br> long line2
In my populate script I tried also:
affiliation1 = add_affiliation('name affiliation1', 'long line1 and <br> long line2 in the same line, so unreadable')
use descrizione = models.TextField(max_length=500, blank=True, null=True) instead of descrizione = models.CharField(max_length=500, blank=True, null=True)
and
use {% autoescape off %}{{ aff.affiliazione.descrizione }}{% endautoescape %} instead of {{ aff.affiliazione.descrizione }}
Generally django escape all html tag and render as raw text, to render actual html you can also use {{ aff.affiliazione.descrizione|safe }}

Django: can "double" 'render_to_response' be unified into only one view?

I have defined two functions in views.py to obtain first prova.html with certain elementimenu and then, after clicking over one of them, I obtain again the page with elementimenu and elementi associated to elementimenu with the same id i.e.:
another_app.model.py
...
class ElementiTab(models.Model):
author = models.ForeignKey('auth.User', null=True, blank=False)
des = models.CharField(max_length=30)
x = models.FloatField()
y = models.FloatField()
res = models.FloatField(default=0)
created_date = models.DateTimeField(default=timezone.now)
...
And here the code that I like to get better:
views.py
from another_app.model import ElementiTab
def show_elementi(request):
elementimenu = ElementiTab.objects.all()
return render_to_response('homepage/prova.html',{'elementimenu': elementimenu, 'user.username': request}, context_instance = RequestContext(request))
def show_detail(request,id):
elementimenu = ElementiTab.objects.all()
detail = get_object_or_404(ElementiTab, pk=id)
return render_to_response('homepage/prova.html',{'elementimenu': elementimenu, 'detail': detail, 'user.username': request}, context_instance = RequestContext(request))
urls.py
...
url(r'^homepage/prova/$', views.show_elementi),
url(r'^show_detail/(?P<id>\d+)/$', views.show_detail),
...
prova.html
...
<div class="elementi">
{% for elementi in elementimenu %}
{{elementi.des}}
{% endfor %}
</div>
<div class="table-responsive">
<table class="table table-bordered">
<tr class="info">
<td width="35%" align="center"> NOME</td>
<td width="35%" align="center"> DATA CREAZIONE </td>
<td width="30%" align="center"> AUTORE </td>
</tr>
{% if detail %}
<div class="dettagli">
<tr>
<td>{{detail.des}}</td>
<td>{{detail.created_date}}</td>
<td>{{detail.author}}</td>
</tr>
{% endif %}
</div>
</table>
</div>
...
I had used this "trick" in show_detail view so that I can see elementimenu even after calling this function.
Is there a more elegant way to do this?
Yes, you can use the single view. Add the default None value for the id (or pk) argument:
def show_elementi(request, pk=None):
elementimenu = ElementiTab.objects.all()
detail = get_object_or_404(ElementiTab, pk=pk) if pk else None
return render(request, 'homepage/prova.html',
{'elementimenu': elementimenu, 'detail': detail})
And then map both urls to this view:
url(r'^homepage/prova/$', views.show_elementi),
url(r'^show_detail/(?P<pk>\d+)/$', views.show_elementi),

Django more than 2 items in a table, template

I have been searching for a way to make a django template which can show more than 2 values per row in a table,
Let's say I have an class with 5 attributes, and I want these attribute values presented in a table on my HTML page. at first I tried with a dictionary but just 2 of the 5 attributes is not enough.
Lets say my object is like:
class ModelA(models.Model):
ID = models.IntegerField(primary_key=True, db_column='ID')
name = models.CharField(max_length=60, db_column='name')
yesorno = models.CharField(max_length=9, db_column='yes/no')
text = models.TextField(db_column='text')
description = models.TextField(db_column='description')
Now in a view I call for all these model attributes, in what datastructure should I save everything and how can I put all these 5 attributes in one row per object in a table.
(sometimes hundreds of objects may need to be shown in table (so, 100 rows))
Grab all the objects (filter accordingly).
As #init3 points out the ID is not required as Django adds that automatically, and yesorno should be a Bool.
# view.py
model_as = []
for id in ids:
try:
model_a = ModelA.objects.get(ID=id)
except ModelD.DoesNotExist:
# No model found
pass
else:
model_as.append(model_a)
return render_to_response('template.html',
{'model_as': model_as},
context_instance=RequestContext(request))
Loop over the objects in the template and print each variable in whichever column you want.
# template.html
<table>
{% for model_a in model_as %}
<tr>
<td>
{{ model_a.ID }}
{{ model_a.name }}
{{ model_a.yesorno }}
{{ model_a.text }}
{{ model_a.description }}
</td>
<tr>
{% empty %}
<tr>
<td>No ModelAs to see here</td>
<tr>
{% endfor %}
</table>