How can I display the count of related objects after each filter in list_filter in django admin?
class Application(TimeStampModel):
name = models.CharField(verbose_name='CI Name', max_length=100, unique=True)
description = models.TextField(blank=True, help_text="Business application")
class Server(TimeStampModel):
name = models.CharField(max_length=100, verbose_name='Server Name', unique=True)
company = models.CharField(max_length=3, choices=constants.COMPANIES.items())
online = models.BooleanField(default=True, blank=True, verbose_name='OnLine')
application_members = models.ManyToManyField('Application',through='Rolemembership',
through_fields = ('server', 'application'),
)
class Rolemembership(TimeStampModel):
server = models.ForeignKey(Server, on_delete = models.CASCADE)
application = models.ForeignKey(Application, on_delete = models.CASCADE)
name = models.CharField(verbose_name='Server Role', max_length=50, choices=constants.SERVER_ROLE.items())
roleversion = models.CharField(max_length=100, verbose_name='Version', blank=True)
Admin.py
#admin.register(Server)
class ServerAdmin(admin.ModelAdmin):
save_on_top = True
list_per_page = 30
list_max_show_all = 500
inlines = [ServerInLine]
list_filter = (
'region',
'rolemembership__name',
'online',
'company',
'location',
'updated_on',
)
i.e After each filter in list filter, I want to show the count of related objects.
Now it only shows the list of filter
i.e location filter list
Toronto
NY
Chicago
I want the filter to show the count like below:
Toronto(5)
NY(3)
Chicago(2)
And if the filter has 0 related objects, don't display the filter.
This is possible with a custom list filter by combining two ideas.
One: the lookups method lets you control the value used in the query string and the text displayed as filter text.
Two: you can inspect the data set when you build the list of filters. The docs at https://docs.djangoproject.com/en/1.11/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_filter shows examples for a start decade list filter (always shows «80s» and «90s») and a dynamic filter (shows «80s» if there are matching records, same for «90s»).
Also as a convenience, the ModelAdmin object is passed to the lookups
method, for example if you want to base the lookups on the available
data
This is a filter I wrote to filter data by language:
class BaseLanguageFilter(admin.SimpleListFilter):
title = _('language')
parameter_name = 'lang'
def lookups(self, request, model_admin):
# Inspect the existing data to return e.g. ('fr', 'français (11)')
# Note: the values and count are computed from the full data set,
# ignoring currently applied filters.
qs = model_admin.get_queryset(request)
for lang, name in settings.LANGUAGES:
count = qs.filter(language=lang).count()
if count:
yield (lang, f'{name} ({count})')
def queryset(self, request, queryset):
# Apply the filter selected, if any
lang = self.value()
if lang:
return queryset.filter(language=lang)
You can start from that and adapt it for your cities by replacing the part with settings.LANGUAGES with a queryset aggregation + values_list that will return the distinct values and counts for cities.
Éric's code got me 80% of what I needed. To address the comment he left in his code (about ignoring currently applied filters), I ended up using the following for my use case:
from django.db.models import Count
class CountAnnotatedFeedFilter(admin.SimpleListFilter):
title = 'feed'
parameter_name = 'feed'
def lookups(self, request, model_admin):
qs = model_admin.get_queryset(request).filter(**request.GET.dict())
for pk, name, count in qs.values_list('feed__feed_id', 'feed__feed_name').annotate(total=Count('feed')).order_by('-total'):
if count:
yield pk, f'{name} ({count})'
def queryset(self, request, queryset):
feed_id = self.value()
if feed_id:
return queryset.filter(feed_id=feed_id)
And then, in the admin model:
class FeedEntryAdmin(admin.ModelAdmin):
list_filter = (CountAnnotatedFeedFilter,)
Note: As Éric also mentioned, this can impact the speed of the admin panel quite heavily, as it may have to perform expensive queries.
I have a Employee domain class and properties name,age,salary,annualPackage.
When I call Employee.list(). All the properties will be persisted.
Now I want to apply numberformat for salary and annualPackage properties.I can achieve it by:
NumberFormat.getNumberInstance(Locale.US).format(Employee.salary.get(0))
But How to format all the values of salary and annualPackage inside the list.
This should do it
def formatter = java.text.NumberFormat.getNumberInstance(Locale.US)
def formattedValues = Employee.list().collect {
[
salary = formatter.format(it.salary)
annualPackage = formatter.format(it.annualPackage)
]
}
You can do this way
List<Employee> employees = Employee.list()
def formatter = java.text.NumberFormat.getNumberInstance(Locale.US)
def formatted = employees.collect { formatter.format(it.salary) }
Note: you should use getCurrencyInstance(Locale.US) instead of getNumberInstance(Locale.US)
Person domain class is as follows:
String name
String gender
boolean available
double salary
What i want to do is to query the database to find out all the Person's who are available and increase their salary by 100.
def person = new Person()
// now i need to get the count of available person
I think i have to use Person.executeQuery("THE QUERY"), but i don't know how to proceed.
I think you could do something like this:
Person.executeUpdate('update Person p set p.salary = p.salary+100 where p.available = :available', [available: true])
Or:
Person.executeUpdate('update Person p set p.salary = p.salary+100 where p.available = TRUE')
I hope that helps.
I am trying to have one variable that has a number value as well as a string value.
I am coding in Lua and I don't know how to do this. Is it possible?
Tables. They are like a filing cabinet where you can store as many values as you want and retrieve them given some kind of "key". In Lua, the key can be any type, but the most common key is going to be a numerical index or a string.
Given:
local age = 30 -- your number values
local name = 'Fred' -- your string value
There's a tons of different ways we can structure that in Lua:
local person = { age = 30, name = 'Fred' )
print(person.age, person.name)
local person = { 'Fred', 30 }
print(person[1], person[2])
print(unpack(person))
local person = { Fred = 30 }
print(person.Fred)
local person = { [30] = 'Fred' }
print(person[30])
So on and so forth.
So if i use..
coal = { name = "Coal", value = 80 }
I can then do this?
userInput = read()
if userInput == coal.name then
fuelUse = coal.value
end
I have there domain classes:
Person. (Person.ID, Name,Address)
Designation.(Designation.ID, Title, Band)
SalarySlip (Person.ID, Designation.ID, totalIncome, Tax etc etc.)
In the update method the person controller when I assign a person a designation from a list of designation values I want to insert a new record inside SalarySlip.
Something like:
def update = {
def SalarySlipInstance = new SalarySlip()
SalarySlipInstance.Person.ID = Params.ID //is this correct?
SalarySlipInstance.Designation.ID = ?? //since the value is coming from a list. How can I bind this field?
}
You need to load the Person and Designation objects first:
salarySlipInstance.Person = Person.get(params.person.id)
salarySlipInstance.Designation = Designation.get(params.designation.id)
If in your form you prefix the person and designation id's with person. and designation. it makes it easier to load.