Django ,How to show image on the board in templates? - django

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.

Related

Django templates - how to run a method on a variable?

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

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

I need help creating a custom counter for items in my SQLite database

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>

How to display ForeignKey object in ListView - Django

I have read up on this but I can't find something which solves my issue.
I am trying to display a table with a list of products with thumbnails.
The thumbnail field in the table returns no url, but returns a broken image link only for the products which own a thumbnail.
This list of products uses a ListView, and I can display the thumbnail fine in the detail view of the product (a DetailView) which uses the same template code
What do I need to do to display the thumbnail for each product in the ListView... ie. how must I change my queryset to pass the thumbnail into the template along with the product?
View
class ProductView(generic.ListView):
template_name = 'product/product.html'
context_object_name = 'product_list'
def get_queryset(self):
return Product.objects.all()
Template
{% for product in product_list %}
<tr>
<td>{{ product.title }}</td>
<td> {% if product.thumbnails.all %}
<img src="{{ product.thumbnail.url }}" alt="...">
{% endif %}
</td>
<td>{{ product.category }}</td>
<td>{{ product.subcategory }}</td>
<td>{{ product.status }}</td>
<td>{{ product.date_added }}</td>
{% endfor %}
Model
class ProductThumbnail(models.Model):
product = models.ForeignKey(Product, default=None, related_name='thumbnails')
thumbnail = models.ImageField(upload_to='thumbnails/',
verbose_name='thumbnail', blank=True,)
Please let me know if any more information is needed.
{% if product.thumbnails.all %} should be {% if product.thumbnail %}
{% if product.thumbnails.all %} would only make sense if product.thumbnails was a reverse relation
EDIT: I misread the question
You need to loop through the thumbnails {% for thumbnail in product.thumbnails.all %}
If you have only one thumbnail per Product, you should add the field
thumbnail = models.ImageField(upload_to='thumbnails/',
verbose_name='thumbnail', blank=True)
directly to the model Product and ditch the ProductThumbnail model. The way you designed your DB makes possible to have more thumbnails for each product (one-to-many relationship), but this makes your code needlessly complex.
If thumbnail was a field of the Product model, you could do simply:
{% if product.thumbnail %}
<img src="{{ product.thumbnail.url }}" alt="...">
{% endif %}

accessing foreignKey inside the template

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 ....