I have two Django models that record time. Model one records time during the morning and Model two records time during the evening. I want to present both of these times along with the difference between the times within an HTML table but am confused about how to do it. I am new to Django and would really appreciate some advice.
This is what I have so far:
models.py:
class Alltime(models.Model):
id= models.ForeignKey(User, on_delete = models.CASCADE)
mtime = models.DateTimeField()
etime = models.DateTimeField()
views.py:
def panel(request):
time_data = User.objects.filter(pk__gt=1) #I need all data except for the default Super User account
get_time = Alltime.objects.all()
return render(request, 'users/interface.html', {'data': time_data, "get_time": get_time})
panel.html:
<form>
{% csrf_token %}
<table>
<tr>
<th>Name</th>
<th>Morning timeE</th>
<th>Evening time</th>
<th>Difference in hours</th>
</tr>
{% for data in data %}
<tr>
<td>{{data.username}}</td>
{% endfor %}
{% if get_time %}
{% for m in get_time %}
<td>{{m.mtime}}</td>
<td>{{m.etime}}</td>
{% endfor %}
{% else %}
<td> Not available </td>
{% endif %}
</tr>
</table>
</form>
How can I get the difference between the times and place them within the HTML table?
If I understand correctly what you want to do, then you can/need to structure your data differently. An easy way is to prepare the data in your view:
def panel(request):
time_data = User.objects.filter(pk__gt=1)
time_table=[]
for user in time_data:
morning_time = Morning.objects.filter(user=user)
evening_time = Evening.objects.filter(user=user)
diff = morning_time - evening_time
time_table.append((user.name, morning_time, evening_time, diff))
return render(request, 'users/interface.html', {'data': time_table})
And in the template:
<table>
<tr>
<th>Name</th>
<th>Morning timeE</th>
<th>Evening time</th>
<th>Difference in hours</th>
</tr>
{% for line in data %}
<tr>
<td>{{line.0}}</td>
<td>{{line.1}}</td>
<td>{{line.2}}</td>
<td>{{line.3}}</td>
</tr>
{% endfor %}
</table>
You need to add the handling of not existing data in the view code.
Some remarks:
The whole thing does not really make sense to me. I guess you will need to filter for dates too. But you should get the idea from this. And why is it in a form?
You can add a property to the Alltime model that returns the difference between the morning and evening time
#property
def diff(self):
return self.etime - self.mtime
Then in your template you can use this property
{% for m in get_time %}
<td>{{m.mtime}}</td>
<td>{{m.etime}}</td>
<td>{{m.diff}}</td>
{% endfor %}
Related
I have a model that is referenced by a generic ListView, and feeds into a template. Attempts to create a table in the template give me a TypeError: not iterable - what am I doing wrong?
Sample code
Class bookmodel(models.Model):
Book = models.CharField(max_length=255)
Author = models.CharField(max_length=255)
Views
Class bookview(generic.ListView):
model = bookmodel
template = “books.html”
Which generates an object_list something like:
<Queryset [<bookmodel: Grapes of Wrath >, <bookmodel: I, Robot>]>
The template is laid out as follows:
{% extends ‘base.html’ %}
{% block content %}
<table>
<thead>
<tr>
<th> book </th>
<th> author </th>
</tr>
</thead>
<tbody>
{% for object in object_list %}
<tr>
{% for field in object %}
<td> {{ field }} </td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
But this fails with the aforementioned error.
The linked question kindly suggested by #Karioki in his comment proposed the following code:
def attrs(self):
for field in self._meta.fields:
yield field.name, getattr(self, field.name)
The yield function inexplicably didn't work for me in my template either from a view or a template tag:
The following derivative code did:
def get_values(self):
value_set = [getattr(self, field.name) for field in self._meta.fields]
return value_set
While this still feels clunky to me, I'm marking it as a straw man answer but am hopeful that there will be another answer that provides a more efficient way to investigate a database record in the template in Django.
I'm new to Django, so maybe my attempts are pure heresy ;)
I'm trying to make a view which lists disponible conference rooms with its attributs, availability included.
I have 2 models: Room and Reservation. I'd like in the view to have a column saying if the room is available the day the page is displayed.
My models.py:
from django.utils import timezone
from django.db import models
class Room(models.Model):
name = models.CharField(max_length=255, unique=True)
capacity = models.IntegerField()
projector = models.BooleanField()
class Reservation(models.Model):
room = models.ForeignKey(Room, on_delete=models.CASCADE)
date = models.DateField()
comment = models.CharField(max_length=255)
class Meta:
unique_together = ('room', 'date',)
my views.py:
class ShowRoom(View):
def get(self, request):
rooms = Room.objects.all()
time_now = timezone.now().date()
context = {
'rooms': rooms,
'time_now': time_now
}
return render(request, 'rooms/list_rooms.html', context)
My template:
{% extends 'rooms/base.html' %}
{% block block_title %} Home {% endblock %}
{% block block_content %}
{% if rooms %}
<table class="table">
<thead>
<td> Name </td>
<td> Capacity </td>
<td> Available </td>
<td> Projector </td>
</thead>
<tbody>
{% for room in rooms|dictsort:'capacity' %}
<tr>
<td> {{ room.name }} </td>
<td> {{ room.capacity }} </td>
<td> Available? </td>
<td> {{ room.projector|yesno:'yes,no' }} </td>
</tbody>
{% endfor %}
</table>
{% else %}
<h1> You have no registered rooms yet. </h1>
{% endif %}
{% endblock %}
Everything works fine, I need just to replace this <td> Available? </td> line with a code, which would display "free" or "occupied" according to existing room reservations.
I've found out that maybe I should write a custom filter.
Here is my filter:
from django import template
from rooms.models import Room, Reservation
register = template.Library()
#register.filter
def check_reservation(queryset, now):
return queryset.filter(date=now)
(I wanted first to make it working, and after make it display this "free" or "occupied".)
I've added to the template {% load my_extras %} and replaced the line I want to change with
<td> {{ room.reservation_set.all|check_reservation:'time_now' }} </td>
The output is:
ValidationError at /room/ ["'time_now' value has an invalid date
format. It must be in YYYY-MM-DD format."]
Before adding the filter, I was trying this solution in the shell and it was working.
I don't know if there is something wrong with the filter, or I try to approach the issue from wrong side.
Thanks in advance for any tips.
Try adding another field to the the Room class:
occupied = model.BooleanField(default=False)
In the views you can check the date associated with the reservation and today's date.
if reservation.date == time_now:
room.occupied = true
You can then filter with rooms that are available and which are not.
rooms_occupied = room.objects.filter(occupied=True)
rooms_available = room.object.filter(occupied=False)
In the template:
{% if rooms_occupied %}
Available
{% endif %}
I am new to Python and Django and I am trying to count the number items(documents) in my SQLite database base on the status of the document, (canceled or not canceled). I have tried multiple ways to do this but, I cannot find one that works correctly for me. I have tried forloop.counter, .count(), and a few other ways that i found online. All I want to do is go through the database and have it tell me how many canceled procedures I have in the database. I am trying to display the results on a html page. Thanks.
models.py
class posts(models.Model):
OPMnumber = models.CharField(max_length = 30)
title = models.TextField()
contacts = models.CharField(max_length = 50)
dateLastReviewed = models.DateTimeField()
reviewDue = models.DateTimeField()
status = models.CharField(max_length = 20)
assignedTo = models.CharField(max_length = 30)
comments = models.TextField()
views.py
def opmStatistics(request):
"""
Return opmStatus page
"""
entries = posts.objects.all()#[:10] limits the number of entries
displayed
#opm_count = posts.objects.filter(posts.status=='Canceled').count()
#return render_to_response('opmStatistics.html', {'posts' :
opm_count})
return render_to_response('opmStatistics.html', {'posts' : entries})
My html code:
<tr><td>Current Number of Active Accelerator Operations OPMs: </td>
<td>
{% for post in posts %}
{% if post.status != "Canceled" %}
{% with OPM_count=forloop.counter %} <!-- how to save final number
as variable. -->
{{OPM_count}}
{% endwith %}
{% endif %}
{% endfor %}
</td>
</tr>
<br><br>
<tr><td>Current Number of Canceled Accelerator Operations OPMs: </td>
<td>
{% for post in posts %}
{% if post.status == "Canceled" %}
{% with OPM_count=forloop.counter %} <!-- how to save final
number as variable. this one does not reset to 1, starts where
it left off. -->
{{OPM_count}}
{% endwith %}
{% endif %}
{% endfor %}
</td>
</tr>
</table>
If you want to count a single value, then you should do that in the view. This is not at all something you should be attempting to do in the template.
You were almost there with your original attempt. It should be:
def opmStatistics(request):
"""
Return opmStatus page
"""
opm_count = posts.objects.filter(status='Canceled').count()
return render(request, 'opmStatistics.html', {'count': opm_count})
and then the template is just:
<tr>
<td>Current Number of Active Accelerator Operations OPMs: </td>
<td>{{ count }}</td>
</tr>
Here i put my code file so you can get idea about my code
In my index.html
{% load tag %}
<body>
<select name="select_year">
<option>2017</option>
<option>2018</option>
<option>2019</option>
<option>2020</option>
</select>
</br>
</br>
<table border="1">
<tr>
<td>No</td>
<td>Name</td>
<td>DOB</td>
<td>Year</td>
</tr>
{% for Manvi_User in ordering %}
<tr>
<td>{{forloop.counter}}</td>
<td>{{ Manvi_User.first_name }}</td>
<td>{{ Manvi_User.dob}}</td>
<td>{{year|calculate_year:forloop.counter0}}</td>
</tr>
{% endfor %}
</table>
</body>
in vies.py
def index(request):
all_user = Manvi_User.objects.all()
ordering = all_user.order_by('dob')
return render(request, 'index.html', {'ordering': ordering})
in tag.py
#register.filter
def calculate_year(year, loop_counter):
try:
year = int(2017)
except ValueError:
return None
else:
return str(year + (loop_counter // 2))
in year i put static year using tag.py
if user select 2019 i want to display only data who have year 2019
As far as I understand what you're trying to do here, which is to filter the queryset depending on the year selected - the way you started is not really the way to do it.
You should look into django-filter app which makes it pretty easy to accomplish what you're trying here.
For this specific situation, you'd have to define your custom filter within filters.py, and then use that filter in your view.
I am trying to split a list from my model across two columns, using this html code in the template:
< div class ="col-md-6" >
{%for value in object_list %}
<ul>< ahref="/sites/{{value.url}}/">{{value.Site}}</a></ul>
{% endfor %}
I was planning to achieve this with the slice tag to filter the list, e.g.:
{%for value in object_list|slice:"10:20" %}
It does not work however, and I think it might be because I have context data i.e. {{value.Site}}, instead of just {{Site}} for example. This is the corresponding view:
class homeview(ListView):
template_name = 'annual_means/home.html'
def get_queryset(self):
return AnnualMean.objects.values("Site", "url").distinct()
What do I need to do to get the slice to work?
I think, what you need is this:
<table>
<tr>
<th>URL</th>
<th>SITE</th>
</tr>
{% for value in object_list %}
<tr>
<td>{{value.url}}</td>
<td>{{value.Site}}</td>
</tr>
{% endfor %}
</table>
URLs and Sites will be displayed as a table.