Real time counter in admin you can implement with one small function
class TransactionAdmin(admin.ModelAdmin):
search_fields = ('name', 'explanation', )
list_filter = ('transaction_type', 'paymentmethod', 'accounting_period__full_name', 'transaction_date', DocsCountFilter)
list_display = ('name', 'explanation', 'transaction_date', 'docs_count', 'docs_count_current')
inlines = [
DocumentInline,
]
def docs_count_current(self, obj: Transaction) -> str:
return str(Document.objects.filter(transaction=obj).count())
But if you need something more than display, you have to filter with this count in admin then you could implement List Filter
class DocsCountFilter(admin.SimpleListFilter):
title = 'Docs count'
parameter_name = 'docs_count'
def lookups(self, request, model_admin):
"""
Returns a list of tuples. The first element in each
tuple is the coded value for the option that will
appear in the URL query. The second element is the
human-readable name for the option that will appear
in the right sidebar.
"""
return (
('0', 'No Invoics'),
('1', 'More then null'),
)
def queryset(self, request, queryset):
"""
Returns the filtered queryset based on the value
provided in the query string and retrievable via
`self.value()`.
"""
if self.value() == '0':
return queryset.filter(docs_count=0)
if self.value() == '1':
return queryset.filter(docs_count__gt=0)
So in this way you can filter transactions if a doc is filled in or not.
Then you are sure that you did not miss any transactions.
When you save one object or delete it. You have to update your counter in related model.
So, use Django signals for this action.
@receiver(models.signals.post_save, sender=Document)
def auto_update_docs_count_on_save(sender, instance, **kwargs):
instance.transaction.docs_count = Document.objects.filter(transaction=instance.transaction).count()
instance.transaction.save()
@receiver(models.signals.post_delete, sender=Document)
def auto_delete_file_on_delete(sender, instance, **kwargs):
"""
Deletes file from filesystem
when corresponding `Document` object is deleted.
"""
if instance.invoice:
if os.path.isfile(instance.invoice.path):
os.remove(instance.invoice.path)
instance.transaction.docs_count = Document.objects.filter(transaction=instance.transaction).count()
instance.transaction.save()
This post is related on topic about. Django models - how to filter number of ForeignKey objects
Comments
Post a Comment