Django PREFETCH_RELATED - only first element shown in template - django

I use prefetch_related to get reverse relation rows. Everything works fine with the only exception that I get only one of many relations. Better explained by example.
Model:
class Tasks(models.Model):
#...
class TaskResponsiblePeople(models.Model):
task = models.ForeignKey('Tasks', related_name='task_responsible_people')
View:
def showTasks(request):
tasks = Tasks.objects.prefetch_related('task_responsible_people').all()
return render_to_response('task_management/task_list.html',
{'responsible_people_form':responsible_people_form,
'tasks':tasks},
context_instance=RequestContext(request))
{% for task in tasks %}
<tr>
<td>
<ul>
{% for resp in task.task_responsible_people.all %}
<li>{{resp.auth_user.first_name}}</li>
{% endfor %}
</ul>
</td>
</tr>
{% endfor %}
The problem here is that for one of the tasks I have several responsible people, but still get only on of them. Is it because I have to use the prefix "_set" somewhere in the code? If I do, I end up with an error message

Related

Django build tables dynamically with filters

SOLVED
Explanation here: Performing a getattr() style lookup in a django template
I am looking to build tables on our business website dynamically. At the moment we have multiple pages with tables and filters that allow for search but I have to go in and construct a table for each of them based on the data that should be displayed. I was hoping to find a way to use one main template file that can encompass most instances for creating a new page. The difficulty I am having is trying to loop through the data and place it in the correct cell.
(Some code has been removed for readability.)
View:
def newDynamicView(request):
jobs = Jobstable.objects.all().order_by('-index')
filter = NewFilter(data, queryset = jobs)
fields_model = filter._meta.fields
fields_text = []
for field in fields_model:
fields_text.append(FIELD_NAME_TEXT[field])
return render(request, 'MYSQLViewer/olivia.html', {'filter': filter, 'fields_model': fields_model, 'fields_display': fields_text})
Current Template (Relevant info):
<div class="table-responsive">
<table id="data_table" class="table table-dark table-bordered table-responsive">
<thead class="thead-light">
{% for field in fields_display %}
<th>{{field}}</th>
{% endfor %}
</thead>
<tbody>
{% for job in filter.qs %}
<tr>
{% for model_field in fields_model %}
<td class="pt-3-half edit {{model_field}}" contenteditable="true" id="{{model_field}}-{{job.index}}">{{job.model_field}}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
From what I understand, the problem (and possible solution?) lies in this tag:
{{job.model_field}}
My idea was to grab the job attribute using model_field but obviously, that doesn't work.
In its current state, all data is passed from view to template correctly.
Any help is greatly appreciated.

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

How to create two columns from a QuerySet in a Django template [duplicate]

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.

Pre-process model childeren from a template in Django

I've got a DetailView to display a Menu (restaurant), with the following structure:
Menu > Courses > Course_Categories > Dishes
i.e. (Theather Menu) > (Starters, Entrees, Desserts) > (Fish Soup, Ribs, etc.)
I want to prefetch the course_categories and dishes, in addition to that I want to set a property on each dish to be used in the template. This property (the price) is dependent on time of day, therefore it's not simple stored as a value on the Dish.
I tried the following:
class MenuView(generic.DetailView):
template_name = "cms/detail/menu.html"
model = Menu
def get_object(self, queryset=None):
pkValue = pk = self.kwargs.get(self.pk_url_kwarg, None)
menu = Menu.objects.get(id=pkValue)
courses = menu.courses.all().prefetch_related('course_categories').prefetch_related('dishes')
for course in courses.all().iterator():
for course_category in course.course_categories.all().iterator():
for dish in course_category.dishes.all().iterator():
dish.price = "0.00"
return menu
When I iterate the data in my template, it shows everything, but no value for the dish.price property. What I think happens is that the related sets are re-retrieved, and therefore my custom set property doesn't show.
Template:
{% for course in menu.courses.iterator %}
<tr>
<td><strong>{{ course.name }}</strong></td>
</tr>
{% for course_category in course.course_categories.iterator %}
<tr>
<td><em> {{ course_category.name }}</em></td>
</tr>
{% for dish in course_category.dishes.iterator %}
<tr>
<td> {{ dish.name }} {{ dish.price}}</td>
</tr>
{% endfor %}
{% endfor %}
{% endfor %}
Any suggestions?
You are using iterator() which explicitly does not cache the results. When you do {% for course in menu.courses.iterator %}, the results are fetched from the database again.
Use simply .all() in your view instead of .all().iterator(), and stop using .iterator in your template, and you shouldn't have the problem.

Django only shows 15 objects...?

I have a very simple little Django 1.2 site, used to keep track of WEP keys cracked by students as a part of a lab, but I have run into a problem I can not figure out where it is: I have a template that lists solutions from the database, but it only lists 15 objects, even when there are many more (over 60) in the database table.
The view:
def index(request, message=None):
cracks_list = Crack.objects.all().order_by('-time')
return render_to_response('wifi/templates/index.html', {'cracks_list': cracks_list}, context_instance=RequestContext(request))
And the associated template:
{% if message %}<p><strong>{{ message }}</strong></p>{% endif %}
{% if cracks_list %}
<ul>
<table border="1">
<tr>
<td>Time</td>
<td>Student</td>
<td>Key</td>
</tr>
{% for crack in cracks_list %}
<tr>
<td>{{crack.time}}</td>
<td>{{crack.name}}</td>
<td>{{crack.key}}</td>
</tr>
{% endfor %}
</table>
</ul>
{% else %}
<p>No solution posted yet.</p>
{% endif %}
It seems very strange to me if I can not pass more than 15 objects to the template. And as far as I can tell there is nothing strange in the database. Any ideas? I assume it is something small and silly...
Check your template input before !
If this is cracks_list print it. It will help debug !
def index(request, message=None):
cracks_list = Crack.objects.all().order_by('-time')
for i in cracks_list:
print i
return render_to_response('wifi/templates/index.html', {'cracks_list': cracks_list}, context_instance=RequestContext(request))