Not able to display the Content of Table - django

models.py has
class Question(models.Model):
Question_Id = models.AutoField(primary_key=True)
Question_Text = models.TextField(max_length=1000)
def __str__(self):
return self.Question_Text
def __int__(self):
return self.Question_Id
class QuestionChoices(models.Model):
Choice_Id = models.AutoField(primary_key=True)
Question_Choices_Question_Id = models.ForeignKey("Question", on_delete=models.CASCADE)
Choice = models.TextField(max_length=500)
Is_Right_Choice = models.BooleanField(default=False)
views.py file has the below
def QuestionDisplay(request):
retrieved_questions_id = Question.objects.values("Question_Id")
retrieved_questions = Question.objects.filter(Question_Id = retrieved_questions_id)
display_content = {retrieved_questions_id: retrieved_questions}
return render(request, 'cgkapp/Question_page.html', context=display_content)
templates folder Question_page.html has
{% block body_block %}
<table>
<thead>
<th>Questions</th>
</thead>
{% for quest in display_content %}
<tr>
<td>{{quest.Question_Text}</td>
</tr>
{% endfor %}
</table>
{% endblock %}
The page displays the Questions as the Table header but not the actual questions from the models. What could be the reason?

You have a typo, you have missed } after Question_Text}
<td>{{quest.Question_Text}}</td>
Update After Comment
Do like below, don't know why but you are getting very much confused I think. It will solve your problem
models.py
class Question(models.Model):
# `id` primary key is already present no need to define.
question_text = models.TextField(max_length=1000)
def __str__(self):
return self.question_text
views.py
def question_display(request):
# There is no need of 2 queries, you can get that in single query.
questions = Question.objects.all();
# If you want only question ids
question_ids = Question.objects.values('id')
# You can send multiple variables to the template using context dictionary and directly access them there.
context = {'questions': questions, 'question_ids':question_ids}
return render(request, 'cgkapp/Question_page.html', context)
In template
#Show questions with only question texts
<table>
<thead>
<th>Questions</th>
</thead>
{% for quest in questions %}
<tr>
<td>{{quest.question_text}}</td>
</tr>
{% endfor %}
</table>
# If you also want to show question text with ids.
<table>
<thead>
<th>Question ID</th>
<th>Question Text</th>
</thead>
{% for quest in questions %}
<tr>
<td>{{quest.id}}</td>
<td>{{quest.question_text}}</td>
</tr>
{% endfor %}
</table>
# If you want to show only Question IDs
<table>
<thead>
<th>Question ID</th>
</thead>
{% for quest in question_ids %}
<tr>
<td>{{quest}}</td>
</tr>
{% endfor %}
</table>
#This same thing can be done this way also.
<table>
<thead>
<th>Question ID</th>
</thead>
{% for quest in questions %}
<tr>
<td>{{quest.id}}</td>
</tr>
{% endfor %}
</table>

If it was just the typo, you'll see the string {{quest.Question_Text} being rendered. The problem is with your context. You're sending a dictionary there where keys are supposed to be strings,
display_content = {'retrieved_questions_id': retrieved_questions}
And then, in your template, you would iterate over retrieved_questions_id and not display_content. display_content is just the name of the dictionary where you're storing the values.

Related

How can I dynamically reference the fields in a Django query set object in a template?

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.

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:The QuerySet value for an exact lookup must be limited to one result using slicing

I am working on a project where admin can assign team to manager. But it is not working and i have no idea how it will work. Because it is raising an error saying "The QuerySet value for an exact lookup must be limited to one result using slicing."
Here is my model.py
class manager(models.Model):
name = models.CharField(max_length= 500)
designation = models.CharField(max_length= 500)
user = models.ForeignKey(User,on_delete=models.CASCADE)
class Meta:
permissions = [
("edit_task", "can edit the task"),
]
here is my views.py file for the teams of manager
#login_required (login_url= 'have the url where it will go')
#permission_required('have the permission that is assigned by me')
def supervisor(request):
return render(request, 'manager/index-3.html')
def supervisor_team(request):
print(request.user.email)
email=request.user.email
obj= Create_Team.objects.filter(status='Accept',
managers=manager.objects.filter(user__email=email))
return render(request, "manager/accept_team.html", {"object": obj})
here is my template
<div class="body table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>S No.</th>
<th>COMPANY NAME</th>
<th>TEAM MEMBER</th>
<th>EMAIL</th>
</tr>
</thead>
<tbody>
{%for object in team%}
<tr>
<form id="form_id" method="POST" action = "#">
{% csrf_token %}
<th scope="row"> {{ forloop.counter }}</th>
<td>{{object.company_name}}</td>
<td>{{object.team_member}}</td>
<td>{{object.email}}</td>
<td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
I have no idea where i am wrong.
I think this is the problem:
obj= Create_Team.objects.filter(status='Accept',
managers=manager.objects.filter(user__email=email))
if you want to filter by one manager you have to use get instead of filter:
obj= Create_Team.objects.filter(status='Accept',
managers=manager.objects.get(user__email=email))
But if you want to filter by several managers you need to use __in:
obj= Create_Team.objects.filter(status='Accept',
managers__in=manager.objects.filter(user__email=email))
Also you are passing {"object": obj}) to template but in templare you are trying to iterate over team. So change it to pass team variable:
return render(request, "manager/accept_team.html", {"team": obj})

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: How to sort a table presented in the front end by one particular column

I have a data model like this:
class Task(models.Model):
task_id = models.IntegerField(null=True)
uptime = models.DateTimeField(auto_now=True)
The template is:
<table cellpadding="0" cellspacing="0" border="0" class="display dataTable" id="list">
<thead>
<tr>
<th>Id</th>
<th>Uptime</th>
</tr>
</thead>
<tbody>
{% for task in tasks|dictsortreversed:"uptime" %}
<tr>
<td>{{task.id}}</td>
<td>{{task.uptime}}</td>
</tr>
{% endfor %}
</tbody>
And I wish the table presented in the front end to be sorted by the uptime.
I have tried dictsort. But it didn't work. Now, if I click on the title of Uptime, it seems that the table treated data in this column as string and sorted the rows in alphabetical order
Question is: How to sort this table by the time in the Uptime field
I know about two variants:
Provide your_view where sorting content base on "uptime" or "-uptime":
class TaskListView(ListView):
model = Task
paginate_by = 10
def get_queryset(self):
queryset = super(TaskListView, self).get_queryset()
if self.kwargs.get('sort'):
sort_by = self.kwargs.get('sort')
return queryset.order_by(sort_by)
return queryset
Then in Html in your header table:
<th>
{% if view.kwargs.sort == "uptime" %}
href="{% url "task_sort" 'uptime' %}">Uptime</a>
{% else %}
Uptime
{% endif %}
</th>
In the urls.py:
path('task_list/<str:sort>/', TaskListView.as_view(), name='task_sort')
If you need something massive and sort through many columns it's better to use additional packages https://pypi.org/project/django-datatables-view/