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