Django how to display list users with some data in template - django

I want to display the list of users with some objects in 2 modelapps created.
these are the models.
first model:
class UserProfile(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
indirizzo = models.CharField(max_length=50)
citta = models.CharField(max_length=50)
paese = models.CharField(max_length=50)
ecap = models.CharField(max_length=4)
descrizione = models.CharField(max_length=100, default='')
image = models.ImageField(upload_to='profile_image', blank=True,null=True)
second model:
class Ore(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="ore",null=True,)
data = models.DateField(default=timezone.now)
oret = models.CharField(max_length=3,)
contrattiok = models.PositiveSmallIntegerField()
contrattiko = models.PositiveSmallIntegerField(default=0,)
nomecognome = models.CharField(max_length=100,blank=True)
my view:
def inizio(request):
users = User.objects.all()
return render (request, "base.html", {"users":users})
my template:
{% for users in users %}
<tbody>
<tr>
<td>
<img src="{{ users.userprofile.image.url }}"class="thumbnail">
<h4 class="small font-weight-bold">{{users}}</h4>
</td>
<td><h4 class="small font-weight-bold">{{users.last_name}}</h4></td>
<td class="text-center">
<h4 class="small font-weight-bold" class="btn btn-primary btn-circle">{{ users.ore.contrattiok }}</h4> <<<<<(does not work)
</td>
</tr>
{% endfor %}

I saw several problems in your templates.
1. It would be better to make different variable of users loop to increase readability code.
don't do this: {% for users in users %}
but instead: {% for user in users %}
so then you can use it with user instead of users inside loop like:
{{ user.last_name }}
2. your <tbody> inside forloop users, but theres no </tbody> right before the {% endfor %}.
But I suggest you to do not include <tbody> inside forloop.
Do this instead:
<tbody>
{% for user in users %}
<tr><td></td></tr>
{% endfor %}
</tbody>
since your foreign key is inside Ore model instead
(one to many relationship which means 1 user has many ores),
so you need to loop every ore on each user.
{% for user in users %}
{% for ore in user.ore.all %}
{{ ore.contrattiok }}
{% endfor %}
{% endfor %}
so the final result will be like this:
<tbody>
{% for user in users %}
<tr>
<td>
<img src="{{ user.userprofile.image.url }}" class="thumbnail">
<h4 class="small font-weight-bold">{{ user }}</h4>
</td>
<td><h4 class="small font-weight-bold">{{user.last_name}}</h4></td>
<td class="text-center">
{% for ore in user.ore.all %}
<h4 class="small font-weight-bold" class="btn btn-primary btn-circle">
{{ ore.contrattiok }}
</h4>
{% endfor %}
</td>
</tr>
{% endfor %}
</tbody>
EDITED
based on your comment, so you want to sum the total of contrattiok field?
if that so, you need to change your view using annotate
from django.db.models import Sum
users = User.objects.annotate(total_contrattiok=Sum('ore__contrattiok'))
then in your template:
{% for user in users %}
<td class="text-center">
<h4 class="small font-weight-bold" class="btn btn-primary btn-circle">
{{ user.total_contrattiok }}
</h4>
</td>
{% endfor %}

Related

How can i display count of each column in django

Display
I would like to count the number of students for each subjects but currently it only displays the number of students for one subject. it only counts the number of student for one subject but i would like to count the number of students in each subject
Added the models.py. Ps still new to django
views.py
class SubjectView(TemplateView):
template_name='subjects.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
username=self.request.user.id
#filter subject taught by lecturer
classdets=ClassDetail.objects.all().filter(teacher=username).values_list('subject_id')
print(classdets)
#filters all subjects from the class details
subj=Subject.objects.filter(id__in=classdets)
print(subj)
#counts number of students
subjID=Subject.objects.values('id')
num_student=ClassDetail.objects.filter(id__in=subjID).count
print(num_student)
context['subjects'] = subj
context['no_students'] = num_student
return context
template
{% extends "base.html" %}
{% load static %}
{% block title %}Subjects{% endblock title %}
{% block sidenavbar %}
{% include 'partials/sidenavbar.html' %}
{% endblock %}
{% block navbar %}
{% include 'partials/navbar.html' %}
{% endblock %}
{% block subject %}
<div class="container-fluid">
<div class="col">
<div class="card bg-transparent">
<!-- Card header -->
<div>
<div class="card-header bg-transparent border-0">
<h3 class="mb-0" style="text-transform: uppercase">Current Subjects</h3>
{% comment %} View Students {% endcomment %}
</div>
</div>
<!-- Translucent table -->
<div class="table-responsive">
<table class="table align-items-center table-flush" id="datatable-buttons">
<thead class="thead-light">
<tr>
<th>Subject Name</th>
<th>Subject Code</th>
<th>Number of Students</th>
{% comment %} <th>Generate Attendance Code</th> {% endcomment %}
</tr>
</thead>
{% if user.is_authenticated %}
{% for subject in subjects %}
<tbody class="list" style="text-transform: capitalize">
<tr>
<th scope="row">
<div class="media align-items-center">
<a href="#" class="avatar rounded-circle mr-3">
{% if subject.thumbnail %}
<img alt="Logo" src="{{subject.thumbnail.url}}" />
{% endif %}
</a>
<div class="media-body">
<span class="name mb-0 text-sm">{{subject}}</span>
</div>
</div>
</th>
<td class="budget">{{subject.code}}</td>
<td>
<div class="d-flex align-items-center">
<span class="completion mr-2">{{no_students}}</span>
</div>
</td>
<td>
{% comment %}
<div class="d-flex align-items-center">
<span class="completion mr-2">{{attendace_code}}</span>
</div>
{% endcomment %}
</td>
</tr>
</tbody>
{% endfor %}
{% endif %}
</table>
</div>
</div>
</div>
</div>
{% endblock %}
models
def get_thumbnail(instance, filename):
path = f"static/assets/img/custom/{filename}"
return path
class Subject(models.Model):
code=models.CharField(max_length=8,unique=True,default="")
name=models.CharField(max_length=100,unique=True)
thumbnail=models.ImageField(blank=True,null=True,upload_to=get_thumbnail)
def __str__(self):
return f'{self.name}'
class Meta:
unique_together = ('name', 'code')
class ClassDetail(models.Model):
teacher=models.ForeignKey(UserProfile,on_delete=models.PROTECT)
subject=models.ForeignKey(Subject, on_delete=models.PROTECT, default="")
student=models.ManyToManyField(UserProfile,related_name="student")
def __str__(self):
return f'{self.subject}'
class Meta:
unique_together = ('teacher', 'subject')
userprofile
class UserProfile(AbstractUser):
ROLE_LECTURER = 'lecturer'
ROLE_STUDENT = 'student'
ROLE_ADMIN = 'admin'
ROLE_CHOICES = (
(ROLE_LECTURER, _('Lecturer')),
(ROLE_STUDENT, _('Student')),
(ROLE_ADMIN, _('Admin')),
)
STATUS_ACTIVE = 'active'
STATUS_INACTIVE = 'inactive'
STATUS_SUSPENDED = 'suspended'
STATUS_EXPIRED = 'expired'
STATUS_CHOICES = (
(STATUS_ACTIVE, _('Active')),
(STATUS_INACTIVE, _('Inactive')),
(STATUS_SUSPENDED, _('Suspended')),
(STATUS_EXPIRED, _("Expired")),
)
username = models.CharField(max_length=11, unique=True, verbose_name="Relevant ID")
status = models.CharField(_('status'), max_length=50, choices=STATUS_CHOICES, default=STATUS_ACTIVE)
role = models.CharField(_('role'), max_length=50, choices=ROLE_CHOICES, default="")
def __str__(self):
return f'{self.username} ({self.first_name})'
USERNAME_FIELD = 'username'
num_student =subjID.classdetail_set.all().count()
print(num_student)

Why is my Class-based delete view not working?

My delete view is not working and the error message is:
Page not found (404) Request Method: GET.
I am trying to delete my uploaded file based on its primary key and so far, my url is able to link me correctly based on the pk.
This is my urls.py:
path('post/<int:post_id>/lesson_delete/<int:lesson_id>', LessonDeleteView.as_view(), name='lesson_delete'),
My views.py:
class LessonDeleteView(DeleteView):
model = Lesson
success_url = '../'
template_name = 'lesson_confirm_delete.html'
This is the html template that brings user to the delete view:
{% extends "store/base.html" %}
{% block content %}
<div id="main">
<table class="table mb-0">
<thead>
<tr>
<th>Title</th>
<th>Author</th>
<th>Download</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
{% for l in Lesson %}
<tr>
<td>
{% if l.file %}
{{ l.title }}
{% else %}
<h6>Not available</h6>
{% endif %}
</td>
<td>{{ l.post.author }}</td>
<td>{% if l.file %}
Download
{% else %}
<h6>Not available</h6>
{% endif %}
</td>
<td> <a class="btn btn-danger btn-sm mt-1 mb-1" href="{% url 'lesson_delete' lesson_id=l.id %}">Delete</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
This is my html template for DeleteView:
{% extends "store/base.html" %}
{% block content %}
<div class="content-section" id="main">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Delete Lesson</legend>
<h2>Are you sure you want to delete the post "{{object.title}}"?
</h2>
</fieldset>
<span style="display:inline;">
<button class="btn btn-outline-danger" type="submit">Yes, Delete!
</button>
<a class="btn btn-outline-secondary" href ="">Cancel</a>
</span>
</form>
</div>
{% endblock content %}
This is my Lesson Model:
class Lesson(models.Model):
title = models.CharField(max_length=100)
file = models.FileField(upload_to="lesson/pdf")
date_posted = models.DateTimeField(default=timezone.now)
post = models.ForeignKey(Post, on_delete=models.CASCADE, null=False, blank=False)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('lesson_upload', kwargs={'pk': self.pk})
Is you template called 'lesson_confirm_delete.html'?
Also, for your success url, I have feeling you don't have a path '../'. It should the specific path you want it to go to.
(Sorry, I can't comment yet.)

Using a different counter from different object_list than the one used in for_loop

I want to count the objects in my template, but since I am using pagination to divide them into pages, I want to use counter from different object_list than the one used in the for loop.
This is my template:
{% extends 'base.html' %}
{% block content %}
{% if user.is_superuser %}
<div class="row">
<div class="col-sm-4 offset-sm-4">
<form class="form-inline md-form form-sm" method="GET" action="">
<i class="fa fa-search" aria-hidden="true"></i>
<input class="form-control form-control-sm ml-3 w-75" type="text" placeholder="搜索货品 Znajdź część" name="q" value="{{ request.GET.q }}"/>
</form>
</div>
</div>
<br/>
<hr/>
<div class='row'>
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col">#</th>
<th scope="col">Image</th>
<th scope="col">Product name</th>
<th scope="col">Price (cost)</th>
<th scope="col">Price (PL)</th>
</tr>
</thead>
<tbody>
{% for product in objects %}
<tr>
<th scope="row">{{forloop.counter}}</th>
<td><img class="img img-fluid rounded" width="200" height="136" src="{{ product.photo.url }}"></td>
<td>{{product.product_name}}</td>
<td>{{product.price}}</td>
<td>{{product.price_pol}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="col-sm-4 offset-sm-4" align="center">
<div class="pagination">
<span class="step-links">
{% if objects.has_previous %}
« first
previous
{% endif %}
<span class="current">
Page {{ objects.number }} of {{ objects.paginator.num_pages }}.
</span>
{% if objects.has_next %}
next
last »
{% endif %}
</span>
</div>
</div>
{% endif %}
{% endblock content %}
My views.py:
Here I would like to use counter from object_list and not object
(Note the context in productview)
#login_required
def productview(request):
object_list = Product.objects.all().order_by('-date')
query = request.GET.get('q')
if query:
object_list = object_list.filter(
Q(product_name__icontains=query)|
Q(date__icontains=query)
).distinct()
paginator = Paginator(object_list, 5)
page = request.GET.get('page')
objects = paginator.get_page(page)
return render(request, 'products_list.html', {'objects': objects, 'object_list':object_list})
I wanted to use the nested loop, but it didn't work out. Is there another way that I don't know of? If I leave it like this every time I click nextpage the counter will start from "1". I would like the counter to continue when I click the next page...
You can enumerate you obect_list:
def productview(request):
object_list = Product.objects.all().order_by('-date')
query = request.GET.get('q')
if query:
object_list = object_list.filter(
Q(product_name__icontains=query)|
Q(date__icontains=query)
).distinct()
object_list =list(enumerate(object_list))
paginator = Paginator(object_list, 5)
page = request.GET.get('page')
objects = paginator.get_page(page)
return render(request, 'products_list.html', {'objects': objects, 'object_list':object_list})
Then the structure of the objects has changed: product.0 will contain the counter and product.1 will contain the model instance:
{% for product in objects %}
<tr>
<th scope="row">{{product.0}}</th>
<td><img class="img img-fluid rounded" width="200" height="136" src="{{ product.1.photo.url }}"></td>
<td>{{product.1.product_name}}</td>
<td>{{product.1.price}}</td>
<td>{{product.1.price_pol}}</td>
</tr>
{% endfor %}

Autocomplete through a selected external key (Django)

I have a query and I have 2 models, one called Detalleventa and Producto
class DetalleVenta(models.Model):
producto = models.ForeignKey(Producto,on_delete=models.CASCADE,verbose_name='Producto')
cantidad = models.IntegerField(verbose_name='Cantidad')
preciounit = models.DecimalField(decimal_places=2, max_digits=7, verbose_name='Precio unitario')
subtotal = models.DecimalField(decimal_places=2, max_digits=7, verbose_name='Subtotal')
venta = models.ForeignKey(Venta,on_delete=models.CASCADE, related_name='detalleventa', verbose_name='Venta')
def __str__(self):
return '{} - {}'.format(self.venta,self.producto)
class Producto(models.Model):
nombre = models.CharField(max_length=30,unique=True,verbose_name='Nombre de Producto:')
precio = models.DecimalField(decimal_places=2, max_digits=7, verbose_name='Precio de Producto:')
categoria = models.ForeignKey(Categoria,on_delete=models.CASCADE,verbose_name='Categoría:')
def __str__(self):
return self.nombre
And in my Detalle forms.py I have:
class DetalleForm(forms.ModelForm):
class Meta:
model = DetalleVenta
fields = [
'producto',
'cantidad',
'preciounit',
'subtotal',
]
labels = {
'producto':'Producto',
'cantidad':'Cantidad',
'preciounit':'Prec.Unit.',
'subtotal':'Subtotal',
}
widgets = {
'producto':forms.Select(attrs={'class':'form-control'}),
'cantidad':forms.NumberInput(attrs={'class':'form-control cantidad'}),
'preciounit':forms.NumberInput(attrs={'class':'form-control'}),
'subtotal':forms.NumberInput(attrs={'class':'form-control subtotal', 'readonly':True}),
}
DetalleFormSet = inlineformset_factory(Venta, DetalleVenta,
form=DetalleForm, extra=1)
As you can see in the details form, I have a priceunit field that refers to the price of the product that is in the product model and my question is: is there any way in my details template when selecting, for example, a product X ? ? (external key product) autocomplete its respective price in the input of preciounit?
This is my template:
{% extends 'base/base.html' %}
{% load static %}
{% block titulo%} Registrar venta {%endblock%}
{% block contenido %}
<div class="col-md-12">
<form method="post">{% csrf_token %}
<div class="col-md-4 form-group">
<label class="font-weight-bold" for="{{form.cliente.name}}">{{form.cliente.label}}</label>
{{form.cliente}}
</div>
<h4 class="text-left">Detalle de venta: </h4>
<div class="table-responsive-sm">
<table class="table" id="tablaDetalle">
{{ detalleformset.management_form }}
<thead class="thead-dark">
<th>Producto</th>
<th width="100px">Cantidad</th>
<th width="115px">Prec.Unit.</th>
<th width="115px">Subtotal</th>
<th>Acción</th>
</thead>
<tbody>
{% for form in detalleformset.forms %}
<tr class="formset_row">
{% for field in form.visible_fields %}
<td>
{# Include the hidden fields in the form #}
{% if forloop.first %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
{{ field.errors.as_ul }}
{{ field }}
</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="row justify-content-md-end">
<div class="col-md-2">
<label class="font-weight-bold" for="{{form.total.name}}">{{form.total.label}}</label>
{{form.total}}
</div>
</div>
<div class="form-group">
<label class="font-weight-bold" for="{{form.descripcion.name}}">{{form.descripcion.label}}</label>
{{form.descripcion}}
</div>
<div class="col-md-4 offset-md-4">
<button class="btn btn-block btn-lg btn-primary" type="submit"><span><i class="fa fa-shopping-cart"></i>
</span>Registrar venta</button>
</div>
</form>
</div>
{% endblock %}
As you know, it's for a small sales system and I have to get the price of the product. If there is a way to be able to do what has been proposed? or at least a clue to discover how to do it?

Django template queryset.example_set.all() showing different primary key

{% for n in medrec %}
<tr>
<td>{{ n.patient.pk }}</td>
<td>{{ n.patient.name }}</td>
<td>
<div class="ui grid">
<form class="ui form" id="mform{{ n.id }}" action="/mbill/" method="post">
{% csrf_token %}
<input value="{{ n.pk }}" type="hidden" name="pk">
{% for m in n.med_set.all %}
<div class="row">
<div class="eight wide column">{{ m.medicine }}</div>
<div class="eight wide column">
<div class="field"><input name="{{ m.medicine.id }}" type="text"></div>
<h5>{{ m.medicine.quantity }} left</h5>
</div>
</div>
{% endfor %}
</form>
</div>
</td>
<td class="right aligned">
<button type="submit" class="ui button green" form="mform{{ n.id }}" id="mbill">bill</button>
</td>
</tr>
{% endfor %}
I am trying to access pk of foreign keys of medrec or n. but instead of real pk it show 1,2,3... every time
the n.medicine.id gives 1,2,3... instead of the real 3,4,5 is there a work around for this?
class Medicine(models.Model):
medicalrec = models.ForeignKey(MedicalRec,related_name='med_set')
medicine = models.ForeignKey(Stock,related_name='stock_set')
stockpk = models.IntegerField()
class MedicalRec(models.Model):
patient = models.ForeignKey(Patient)
date = models.DateField()
disease = models.TextField()
treatment = models.TextField()
billed = models.BooleanField()