I have created and object which contains a few students. I am trying to use each student to pull his data from another model as I iterate through my origianl student object known as student_list. I didn't post the view I made because I know that the object works fine.
I have the following models:
class StudentDetail(Base):
student = models.OneToOneField('Usr', limit_choices_to={'user_type': 'Student'})
klass = models.ForeignKey('Klass', related_name='kara_pore')
class Usr(AbstractUser, Base):
type_choices = (
('Student', 'Student'),
('Teacher', 'Teacher'),
)
user_type = models.CharField(max_length=10,
choices=type_choices,
default='Student')
class Score(Base):
student = models.ForeignKey(Usr, limit_choices_to={'user_type': 'Student'}, related_name='scored')
subject = models.ForeignKey(Subject)
teacher = models.ForeignKey(Usr, limit_choices_to={'user_type': 'Teacher'}, related_name='marked')
exam = models.CharField(max_length=50)
exam_date = models.DateField()
score = models.IntegerField()
out_of = models.IntegerField()
The template file:
{% for student in student_list %}
<tr>
<td> <a href=#>{{ student }}</a> </td>
<td> {{ student.student.scored.score }} </td> <-- this line doesn't work.
<td></td>
</tr>
{% endfor %}
The student_list object works and I can easily iterate through it. I am using that object to filter out data from the Score class. I have never used Zip in my view before. And I don't know whether this is an ideal situation for using that. As far as I know, using the dots to jump through classes should work and get me the value I need. I must be doing something wrong here. The template renders, but the score is not displayed.
Note: Here is my view.
def View(request, pk):
this_klass = Klass.objects.get(id=pk)
student_list = this_klass.kara_pore.all()
return render(request, "grades/view.html", {'this_klass': this_klass, 'student_list': student_list})
The following solved the problem:
{% for student in student_list %}
{% for score in student.student.scored.all %}
<tr>
<td> <a href=#>{{ student }}</a> </td>
<td> {{ score.score }} </td>
<td></td>
</tr>
{% endfor %}
{% endfor %}
Related
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>
I want to use like this
I'm making a bulltein board like the image.
I can show image in detail page. But i can't show image bulletin board list(index page).
How do I add images to the bulletin board list?
toy/models.py
class NewBornProduct(models.Model):
type = models.ForeignKey(Type,on_delete=models.PROTECT)
name = models.CharField(,max_length=30)
content = models.TextField()
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
price = models.IntegerField(null=False)
class NewBornProductImage(models.Model):
product = models.ForeignKey(NewBornProduct,on_delete=models.CASCADE)
image = models.ImageField(upload_to="newborn/%Y/%m/%d")
def delete(self, using=None, keep_parents=False):
self.image.delete()
return models.Model.delete(self, using=using, keep_parents=keep_parents)
toy/views.py
def newborn(request):
obj = NewBornProduct.objects.all()
return render(request,'toy/newborn.html',{'obj':obj})
toy/newborn.html
{% for post in obj %}
<tr>
<th>{{post.id}}</th>
<th> i want to show image here!</th> <-------- Here!
<th>
{{post.name}}
</th>
<th>{{post.price}}</th>
<th>{{post.amount}}</th>
<th>{{post.pub_date}}</th>
</tr>
{% endfor %}
I do not know how to call the image because the other is fine
Do you have any ideas?
If what yoy want is "the first image if there's one":
{% for post in obj %}
<tr>
<th>{{post.id}}</th>
<th>
{% with post.newbornproductimage_set.first as img %}
{% if img %}<img src="{{ img.image.url }}" />{% endif %}
{% endwith %}
</th>
<th>
{{post.name}}
</th>
<th>{{post.price}}</th>
<th>{{post.amount}}</th>
<th>{{post.pub_date}}</th>
</tr>
{% endfor %}
Also note that:
1/ your markup is wrong, you should be using td, not th (th is a table header)
2/ naming your products queryset obj and products instances post is not going to help wrt/ readabilty/maintainability. You should rename obj to products (plural, denotes a collection) and post to product.
Trying to render attributes of objects that are linked with another object via m2m field.
#models
class Arm(models.Model):
cmrs = models.ManyToManyField(CMR, null=True)
class CMR(models.Model):
client = models.ForeignKey('Client', on_delete=models.CASCADE,
null=True, default="", blank=True)
The view
if us.groups.filter(name__in = ['prime']):
query_set = Plan.objects.order_by('-pk')
query_ys = Arm.objects.filter(date=ys)
query_rn = Arm.objects.filter(date=rn)
query_tm = Arm.objects.filter(date=tm)
client_rn = query_rn.prefetch_related('cmrs')
args = {'query_rn': query_rn,
'cl_rn': client_rn,
'query_tm': query_tm,
'query_ys': query_ys,
'query_set': query_set
}
return render(request, 'personnel/schedule/test-schedule-full.html', args)
And the template
<tbody id="add">
{% for query in query_rn %}
<tr class="row100 body {{ query.status }}" data-href="/personnel/arm/{{ query.id }}">
<td class="cell100 column1">{{ query.driver }}</td>
<td class="cell100 column2">{% for idem in cl_rn.cmrs.all %} {{ idem.client }} {% endfor %}</td>
<td class="cell100 column3">{{ query.des_from}}</td>
<td class="cell100 columnarrow"><i class="fas fa-arrow-circle-right"></i></td>
<td class="cell100 column4">{{ query.des_to }}</td>
</tr>
{% endfor %}
</tbody>
What I am trying to do is to show all the values of the client field of an CMR objects that are linked with Arm in <td class="cell100 column2"></td> but it shows nothing instead.
It doesn't make sense to have separate querysets for the prefetch_related call. You're iterating through query_rn, you need to define the prefetch_related on that same queryset and then iterate through the related objects from there; you don't need client_rn at all. So:
query_rn = Arm.objects.filter(date=rn).prefetch_related('cmrs')
...
{% for query in query_rn %}
{% for idem in query.cmrs.all %} {{ idem.client }} {% endfor %}
{% endfor %}
Note also, the first line of your code is a bit off. You shouldn't use __in with a single-list element, just check for equality; and since you just want to check that the related group exists, you should use the exists() method, which is slightly more efficient:
if us.groups.filter(name='prime').exists():
well it's quiet simple.
2 models with ManyToMany relation:
class Artist(models.Model):
name = models.CharField(max_length=100, unique=True)
slug = models.SlugField(max_length=100, unique=True,
help_text='Uniq value for artist page URL, created from name')
birth_name = models.CharField(max_length=100, blank=True)
class Song(models.Model):
title = models.CharField(max_length=255)
slug = models.SlugField(max_length=255, unique=True,
help_text='Unique value for product page URL, create from name.')
youtube_link = models.URLField(blank=False)
artists = models.ManyToManyField(Artist)
my view suppose to display latest 5 songs:
def songs(request, template_name="artists/songs.html"):
song_list = Song.objects.all().order_by('-created_at')[:5]
return render_to_response(template_name, locals(),
context_instance=RequestContext(request))
and the problem is in the template... i want to display the artist name
but just dont realy know how to do it, i tried:
{% for song in song_list %}
{{ artists__name }} - {{ song.title }}
{% endfor %}
would appreciate any help !
Try changing your template code to:
{% for song in song_list %}
{% for artist in song.artists.all %}
{{ artist.name }} - {{ song.title }}
{% endfor %}
{% endfor %}
artists is another type of manager, so you have to iterate through artists.all and print the name attribute of each element.
Well, I worked on above solution of Mr #Dominic Rodger, but because am using Django version 3.2 it did not worked for me. Therefore, the problem may remain the same but according to how Django version changes, the way to solve them sometimes become different. If you're using Django 3.x use below solution.
In views.py
def songs(request):
song_list = Song.objects.all().order_by('-created_at')[:5]
song_list = {'song_list':song_list}
return render(request, 'artists/songs.html', song_list)
In your HTML Template use code below
<div class="table-responsive">
<table class="table table-bordered" id="dataTable" width="100%" cellspacing="0">
<thead>
<tr>
<th>Artist - Song Title</th>
</tr>
</thead>
<tbody>
{% for song in song_list %}
</tr>
<td>{{ song.artist.name }} - {{ song.title }}</td>
<tr>
{% endfor %}
</tbody>
</table>
In urls.py
path('songs/', views.songs, name='songs'),
If you're running source code from localhost, then type on your browser http://127.0.0.1:8000/songs/
Thank you ....