My Views.py code
class ListaFuncionariosView(ListView):
model = Funcionarios
template_name = '../templates/funcionarios/lista_funcionarios.html'
paginate_by = 10
ordering = ['FuncionarioCartao']
queryset = Funcionarios.objects.filter(EmpresaCodigo=1)
funcionarios_number = Funcionarios.objects.aggregate(Count('FuncionarioCartao'))
My HTML
<h1>Good Morning</h1>
Exists: {{funcionarios_number}}
<br>
{{funcionarios}}
I would like to show the total number of registered employees in my db table (in the HTML file below), but I don't know how to put variables in class based views, in this case ListView. I'm using 4.0 Django
I tried put: funcionarios_number = Funcionarios.objects.aggregate(Count('FuncionarioCartao')) in bellow of my class, but this is not showed in my html.
By aggregating at the class-level, the query will run when you start the server, and the count will thus always remain that exact number.
You can define this in a function:
class ListaFuncionariosView(ListView):
model = Funcionarios
template_name = '../templates/funcionarios/lista_funcionarios.html'
paginate_by = 10
ordering = ['FuncionarioCartao']
queryset = Funcionarios.objects.filter(EmpresaCodigo=1)
def funcionarios_number(self):
return Funcionarios.objects.aggregate(total=Count('FuncionarioCartao'))[
'total'
]
and then access the function in the view in the template:
{{ view.functionarios_number }}
Related
This is my serializer.
class MixSerializer(serializers.ModelSerializer):
pub_date = serializers.DateTimeField(format="%m/%d/%Y,%I:%M:%S %p")
new_order = #I want to get the number order
class Meta:
model = Mix
fields = ('id','pub_date','detail','user','u_key')
And I narrowing-down the rows like this below.
def get_queryset(self):
queryset = Mix.objects.all()
u_key = self.request.query_params.get('u_key')
if u_key is not None:
queryset = queryset.filter(u_key=u_key)
return queryset
For example, it returns the 30 items from 100 items.
so id should be (1,4,5,6,9,11,13...) like this,
However I want to get the number new_order (1,2,3,4,5,6,....)
I guess I should do some trick in Serializer?
or any other way ?
Any help appreciated.
Well ID is the actual ID in the database, which you don't want to change or override in your queryset (or elsewhere such as your template) because then you would be referring to a different model object, which will cause you problems.
If you want to use ID as some sort of ranking then you have some options, referencing my answer here
The easiest way is to use the forloop.counter in a template or enumerate in a view:
# template
{% for object in objects %}
# rank is {{ forloop0.counter }}
{% endfor %}
# views
for index, value in enumerate(queryset):
# order is the index variable
...
If you want to explicitly add the rank to the queryset then you can use annotation:
from django.db.models import Window, F
from django.db.models.functions import DenseRank
queryset = Mix.objects.annotate(
ranking=Window(
expression=DenseRank(),
order_by=[
F('id').desc(),
]))
If you want to get Order Table data, you have to create an Order Serializer and link to this MixSerilizer, Like this,
class OrderSerializer(serializers.ModelSerializer):
class Meta:
model = Order
fields = ('id',)
class MixSerializer(serializers.ModelSerializer):
pub_date = serializers.DateTimeField(format="%m/%d/%Y,%I:%M:%S %p")
new_order = OrderSerializer()
class Meta:
model = Mix
fields = ('id','pub_date','detail','user','u_key','new_order')
models.py
class Mix(models.Model):
----
----
order = models.ForeignKey(Order, related_name=new_order, on_delete=models.CASCADE)
If want to get parent table data into a child table you have to pass "related_name" attribute in a models fields. and also that name in a child table sterilizer.
I'm working in django and my objective is to output to a template a table consisting of all my customers and a corresponding amount equal to the total amount they have spent.
I have the classes/models Customers and Transactions with a OneToMany relationship. Every time a customer makes a purchase, the transaction is recorded as is the amount they spent (tx_amount). I have the following set a code that works but I believe is not optimal since its running in O(x * y) time, i.e., running a full loop over Transactions for every customer.
Q1: What is the optimal way for accomplishing this task?
When I originally tried to get my template to work, instead of using local_customer, I was using setattr(customer[x],"value",tx_amount) which worked in the django shell but did not work in the template. My workaround was to create a local class which I would use to population my context variable.
Q2: When combining data models to output in a template, is it necessary to use some sort of local class like my local_customer implementation below or is there a better way?
Pseudo-code below:
models.py:
class Customers(models.Model):
name = models.CharField(max_length=70)
def __str__(self):
return self.name
class Transactions(models.Model):
customers = models.ForeignKey(Customers, on_delete=models.CASCADE)
tx_amount = models.DecimalField(max_digits=9, decimal_places=2
views.py:
class Local_Customer:
name = ""
total_spent = 0
def __str__(self, name):
self.name = name
def customer_view(request):
customer = Customers.objects.all()
customer_context = [] # list of objects we'll pass to render
for x in range(len(customer)):
local_customer = Local_Customer(customer[x].name)
customer_txs = Transactions.objects.filter(customer__name=customer[x])
for y in customer_txs:
local_customer.total_spent += y.tx_amount
customer_context.append(local_customer)
context = {'customers' : customer_context}
html_template = loader.get_template( load_template )
return HttpResponse(html_template.render(context, request))
template.html:
{% for customer in customers %}
{{customer.name}}
{{customer.total_spent}}
{% endfor %}
You can .annotate(…) [Django-doc] to do this at the database side:
from django.db.models import Sum
from django.shortcuts import render
def customer_view(request):
customers = Customers.objects.annotate(
total_spent=Sum('transactions__tx_amount')
)
context = {'customers' : customers}
return render(request, load_template, context)
This will thus generate a query that looks like:
SELECT customers.*, SUM(transactions.tx_amount) AS total_spent
FROM customers
LEFT OUTER JOIN transactions ON transactions.customers_id = customers.id
and thus fetches all data in a single query.
If there are no transactions, total_spent will be None (NULL), not 0, you can use Coalesce [Django-doc] to use zero instead:
from django.db.models import Sum, Value
from django.db.models.functions import Coalesce
from django.shortcuts import render
def customer_view(request):
customers = Customers.objects.annotate(
total_spent=Coalesce(Sum('transactions__tx_amount'), Value(0))
)
context = {'customers' : customers}
return render(request, load_template, context)
I'm making a query set with django to list some courses. The problem is when I make the query in the django shell, it returns something like this: <QuerySet [<Course: Course object (1)>,....]>
How can I make it to obtain the table information?
PSD: I make a query set with the users table exactly as I described and I get the expected result. But it can't show the result in the template. So if you can help... Thanks for the help in advance.
class ListCursos( TemplateView):
model1 = User
model2 = Course
template_name = 'plantillas/miscursos.html'
def get_context_data(self, *args, **kwargs):
context = super(ListCursos, self).get_context_data(**kwargs)
context['usuarios'] = User.objects.all()
context['cursos'] = Course.objects.all()
return context
The values of the columns for each instance of a model are as stored as instances variables. You have not provided the definition of one of your models, so I'll just take this for an example.
class Course(models.Model): # example model
name = models.CharField(max_length=10)
students = models.IntegerField()
When you have a queryset of Course models you can access them by index
>>> all_courses = Course.objects.all()
<QuerySet [<Course: Course object (1)>]>
>>> first_course = all_courses[0]
and to acess the values of the selected Course model instance you just type the names for the columns that you have in the class definition. if for example you have the Course model with name history and 10 students then
>>> first_course.name # just type the name of the column
'history'
>>> first_course.students
10
So to access them in a django template, considering that you are passing in the context the Course.objects.all() with a key of "cursos". (like you are doing)
{% for course in cursos %}
<div>{{course.name}}</div>
<div>{{course.students}}</div>
{% endfor %}
I have a listview in my Django's project like:
class KaoiroView(ListView):
template_name = 'main/show-kaoiro.html'
queryset = Kaoiro.objects.all()
context_object_name = 'kaoiro'
paginate_by = 10
where Kaoiro has one column called
checkTime = models.BigIntegerField()
in models.py.
this checkTime is an unixtime like one big number.
I would like to convert this time when user get above page from my views.py, but because I'm using a listview I don't know how to access this data
you can create a new property in your model class such as :
this property is called derived property you can use any formula or code here to calculate new value.
class kaoiro(models.Model):
...
...
checkTime = models.BigIntegerField()
#property
def normal_time(self):
ct = self.checkTime
## do something with ct
return ct
you can use normal_time as any other property of your class.
In a django app I've created different models and everything looks okay until I try using data from two different models inside the same table.
To sum it up: in the homepage, I need to create a table that contains data from both the models, ordered by date.
The two models I need to display are the following.
models.py
class Document(models.Model):
number = models.CharField(max_length=10)
description = models.CharField(max_length=50)
assigned = models.BooleanField
validity_date = models.DateField
is_issued = models.BooleanField
class Program(models.Model):
name = models.CharField(max_length=25)
description = models.CharField(max_length=100)
validity_date = models.DateField
Then, I tried to create a view that would allow me to work with different models.
This is my view.py:
class BaseView(generic.ListView):
template_name = 'base/base_list.html'
context_object_name = 'base_list'
def get_queryset(self):
queryset = Document.objects.order_by('due_date')
return queryset
def get_context_data(self, **kwargs):
context = super(BaseView, self).get_context_data(**kwargs)
context['Programs'] = Program.objects.all()
context['Employees'] = Employee.objects.all()
return context
Now how can I create inside the template a table that shows both the models at once, ordering each entry by validity date (no matter if the entry belongs to Program or to Document)?
Thank you in advance!
You need to first query both the models, chain them together (Concatenate them) and then order by their shared attribute, that is the validity_date. You may do something like:
from itertools import chain
documents = Documents.objects.all()
programs = Program.objects.all()
final_combined_list = sorted(chain(documents,programs),key=lambda instance: instance.validity_date)
You can now simply pass final_combine_list to the template and render it to display it in the manner you want.
def get_context_data(self, **kwargs):
context = super(BaseView, self).get_context_data(**kwargs)
context['object_list'] = sorted(
itertools.chain(Document.objects.all(), Program.objects.all()),
key=lambda x: x.validity_date
)
return context