i want to display only selected year data in Django - django

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.

Related

Adding rows and columns to HTML table with Django

I have a problem. Consider an HTML table and it has rows and columns. I want to add a new row or column when I want it and I want it to be a record in the database. And I want to do this with django. What should I do?
I think I need to use django_table2 but I don't know how. I would be glad if you write a code sample. Thank you)
Say you have a model, you could get a list of objects like so;
def my_view(request):
context = {'object_list':MyModel.objects.all()}
return render(request, 'mypage.html', context)
Then in the template, you could do a few things to create tables:
Either, fully generate the table with Django, like so:
{% for object in object_list %}
<tr>
<td>{{object.data}}</td>
<td>{{object.data}}</td>
<td>{{object.data}}</td>
</tr>
{% endfor %}
This would create a new row for every object.
Another solution is:
{% for object in object_list %}
//Create row for every object
<tr>
{% for data in object.get_field_data %}
// Create column for every field in object
<td>{{data}}</td>
{% endfor %}
</tr>
{% endfor %}
Where get_field_data would be defined as a method on the model like so:
def get_field_data(self):
datalist = []
for field in self._meta.get_fields():
datalist.append(getattr(self, field.name))
return datalist
You could then even implement some checks on the get_field_data, for example, you could exclude fields.
def get_field_data(self):
datalist = []
for field in self._meta.get_fields():
if field.name != 'id':
datalist.append(getattr(self, field.name))
return datalist
You don't need to use any external package, you can do this easily by using the Django Template Language
Here is a code example using a ListView
# views.py
from django.views.generic import ListView
class ItemListView(ListView):
template_name = 'mytable.html'
model = MyModel
context_object_name = 'item_list'
<!-- mytable.html -->
...
<table>
<thead>
<tr>
<th>Name</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
{% for item in item_list %}
<tr>
<td>{{ item.name }}</td>
<td>{{ item.amount }}</td>
</tr>
{% endfor %}
</tbody>
</table>
...
In this way your template will have access to a list of objects called item_list which corresponds exactly to the records in the database table. You can cycle that list/queryset using a for loop that will automatically wrap that content in the html needed to make it part of the table.

Display Django model data to table in HTML

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 %}

Django Simple History - History Diffing

So I'm using django-simple-history for one of my projects. I'm using it on one of the models called "Address" to show the history of the records.
I've created a DetailView to show the information about the address and added context['history'] to show changes of the record. This works all fine.
I would be interested in what field changed, and I read the following; History Diffing
So I somehow need to loop through all the fields from the last two records and find the field which has changed...
I couldn't find any examples on how to achieve this so I tried adding the context to the view
#views.py
class Address(DetailView):
'''
Show details about the address
'''
model = Address
'''
Add history context to the view and show latest changed field
'''
def get_context_data(self, **kwargs):
context = super(Address, self).get_context_data(**kwargs)
qry = Address.history.filter(id=self.kwargs['pk'])
new_record = qry.first()
old_record = qry.first().prev_record
context['history'] = qry
context['history_delta'] = new_record.diff_against(old_record)
return context
And a simple model
#models.py
class Address(models.Model)
name = models.CharField(max_length=200)
street = models.CharField(max_length=200)
street_number = models.CharField(max_length=4)
city = models.CharField(max_length=200)
Template
#address_detail.html
<table>
<thead>
<tr>
<th scope="col">Timestamp</th>
<th scope="col">Note</th>
<th scope="col">Edited by</th>
</tr>
</thead>
<tbody>
{% for history in history %}
<tr>
<td>{{ history.history_date }}</td>
<td>{{ history.history_type }}</td>
<td>{{ history.history_user.first_name }}</td>
</tr>
{% endfor %}
</tbody>
</table>
Somehow this doesn't feel right, there should be a way to iterate over the changes and only add the changed fields to the context...
Any ideas would be appreciated!
I have recently worked on this. I think you are missing a trick you have changes stored in history_delta. You can use this to show the changed fields.
Following will display tabulated result like which field was changed and what was the old and the new value of that field.
{% if history_delta %}
<h3>Following changes occurred:</h3>
<table>
<tr>
<th>Field</th>
<th>New</th>
<th>Old</th>
</tr>
{% for change in delta.changes %}
<tr>
<td>
<b>{{ change.field }}</b>
</td>
<td>
<b>{{ change.new }}</b>
</td>
<td>
<b>{{ change.old }}</b>
</td>
</tr>
{% endfor %}
</table>
{% else %}
<p>No recent changes found.</p>
{% endif %}

Django : Access model data in template using Class-based generic views

I'm trying to display the model data in the template.
When I don't have any filtering, it works fine!
class UserLogList(ListView):
context_object_name = 'data'
queryset = UserLog.objects.all().values('user_id__username','event_id','time')
But if I want to have some filtering, example if I want to get the details based on the user_id where user_id = 1. I can get the user id from the request object or self.request object.
So to achieve this, I did the following in my views.py
class DisplayUserActivity(ListView):
template_name = 'user_activity.html'
uid = self.request.user.id
def get_object(self):
uid = self.request.user.id
object = super(DisplayUserActivity,self).get_object()
object.data = UserLog.objects.filter(user_id = uid).values('user_id__username','event_id','time')
return object
and my template file:
{% block content %}
<h2> Logs </h2>
<table border="1" style="width:50%">
<tr>
<th> User Name </th>
<th> Description </th>
<th> Time </th>
</tr>
{% for user in data %}
<tr>
<td> {{user.user_id__username}}</td>
<td> {{user.event_id}}</td>
<td> {{user.time}} </td>
{% endfor %}
</tr>
</table>
{% endblock %}
What am I missing?
I think you need a method called get_queryset instead of get_object when extending the generic ListView.
EDIT:
Regarding your edit, theres an issue with your template
{% for user in data %}
should be
{% for user in object_list %}
But I suspect there are deeper problems here which are hard to decipher. My advice is to look through your code and the Django documentation more carefully, and possibly switch to a custom written view until you are more comfortable. :)

model object not iterable

template.html
{% extends "base.html" %}
<body>
{% block content %}
<form action="." method="post">
{% csrf_token %}
<table align="center" style="margin-left:60px";>
<p>{{KEBReading_form.as_table}}</p>
<tr><td colspan="2" align="right"><input name="KEBsubmit" type="submit" value="Submit Reading" id="_KEBsubmit1"/> </td></tr>
<tr><td colspan="2" >{{KEBMessage}} </td></tr>
</table>
</form>
<table border="1">
<p> KEB Reading as on Month jan and year 2012</p>
<tr>
<th>Date </th>
<th>Time</th>
<th>True Power Reading</th>
<th>Apparent Power Reading</th>
<th>True Power consumed</th>
<th>Voltage Reading</th>
<th>Power Factor</th>
</tr>
{% for item in q2 %}
<tr>
<td>{{item.date}}</td>
<td>{{item.time}}</td>
<td>{{item.truepower_reading}}</td>
<td>{{item.apparentpower_reading}}</td>
<td>{{item.truepower_consumed}}</td>
<td>{{item.voltage_reading}}</td>
<td> {{item.powerfactor}}</td>
</tr>
{% endfor %}
</table>
{% endblock content %}
views.py
def KEBReading1(request):
#form2 = KEBReading.objects.all()
if request.method == "POST":
form = KEBReading_form(request.POST)
if form.is_valid():
prevdate=KEBReading.objects.latest("date")
# Model.objects.latest('field')
print prevdate.date
print prevdate.time
# q1 = KEBReading.objects.get(datetime.date.today()-datetime.timedelta(0))
kr_truepower_reading = form.cleaned_data["truepower_reading"]
kr_apparentpower_reading = form.cleaned_data["apparentpower_reading"]
truepower_consumed1=kr_truepower_reading-prevdate.truepower_reading
powerfactor1=((kr_truepower_reading-prevdate.truepower_reading)/(kr_apparentpower_reading-prevdate.apparentpower_reading))
#instance=truepower_consumed,powerfactor
## replace form.save() with following lines
form1=form.save(commit=False)
#form1.calculate(truepower_consumed1,powerfactor1)
form1.truepower_consumed=truepower_consumed1
form1.powerfactor=powerfactor1
print form1.powerfactor
form1.save()
q2=KEBReading.objects.latest("date")
context={'KEBReading_form':form,'q2':q2}
return render_to_response('keb.html',context,context_instance=RequestContext(request))
else:
form = KEBReading_form()
return render_to_response('keb.html',{'KEBReading_form':form},context_instance=RequestContext(request))
i want to display all readings in a table whic i calculated through the views in the template. i get model object not iterable while using for loop to iterate..
A few issues:
First, as Aidan correctly noted KEBReading.objects.latest("date") this will return an object, not a collection or iterable.
Secondly, you aren't assigning any of the fields that you are calculating in view. truepower_consumed1=kr_truepower_reading-prevdate.truepower_reading doesn't assign it to your object that you retrieved (your q2). I'm not sure if this is intentional. However, I suspect you want to return to your template the instance of the form, not another record from the table. You need to update your question.
To fix these problems immediately:
<tr>
<td>{{q2.date}}</td>
<td>{{q2.time}}</td>
<td>{{q2.truepower_reading}}</td>
<td>{{q2.apparentpower_reading}}</td>
<td>{{q2.truepower_consumed}}</td>
<td>{{q2.voltage_reading}}</td>
<td> {{q2.powerfactor}}</td>
</tr>
latest() returns the latest object in the table, not a set of objects. Instead of that, you should use KEBReading.objects.all().order_by('date')
Your q2 variable is just an object not a set.
The following line returns a single object -
KEBReading.objects.latest("date")
But your template is expecting a set that it can iterate over -
{% for item in q2 %}
<tr>
<td>{{item.date}}</td>
<td>{{item.time}}</td>
<td>{{item.truepower_reading}}</td>
<td>{{item.apparentpower_reading}}</td>
<td>{{item.truepower_consumed}}</td>
<td>{{item.voltage_reading}}</td>
<td> {{item.powerfactor}}</td>
</tr>
{% endfor %}
Check the docs for the latest() function.