0

I have the following models in Django that have a structure as follows:

class Office_Accounts(models.Model):
    accountid                       =   models.EmailField(max_length=200, unique=True)
    validtill                       =   models.DateField(default=datetime.now)
    limit                           =   models.CharField(max_length=2)

class Device(models.Model):
    device_type         = models.ForeignKey(DeviceType,to_field='device_type')
    serial_number       = models.CharField(max_length=200,unique=True)
    in_use_by           = models.ForeignKey(User,to_field='username')
    brand               = models.CharField(max_length=200,default="-", null=False)
    model               = models.CharField(max_length=200,default="-", null=False)
    type_number         = models.CharField(max_length=200,blank=True,null=True, default = None)
    mac_address         = models.CharField(max_length=200,blank=True,null=True, default = None)
    invoice             = models.FileField(upload_to='Device_Invoice', null=True, blank = True)
    msofficeaccount     = models.ForeignKey(Office_Accounts, to_field="accountid")

    class Meta:
        verbose_name_plural = "Devices"

    def full_name(self):
        return self.device_type + self.serial_number + self.brand

I will display both of the models in admin.py. Now, I want to display the count of each accountid present in the field "msofficeaccount" (present in Device Models) in my admin page of Office_Accounts model. For an example if xyz@abc.com appears in 10 rows of msofficeaccount field then, the count should be displayed as 10 in Office_Accounts admin page. Can anyone please guide me how should I approach this problem to solve it?

A Shukla
  • 13
  • 2

1 Answers1

0

You could add a method to your admin class that returns the count of related devices for each office_account, but that would be very inefficient. Instead you can override get_queryset to annotate the count from a database aggregation function:

from django.db.models import Count

class Office_AccountsAdmin(admin.ModelAdmin):
    list_display = (..., 'device_count')
    ...
    def get_queryset(self, request):
        qs = super().get_queryset(request)
        return qs.annotate(device_count=Count('device'))

(On a minor note, Python style is always to use CamelCase for class names, and Django style is to use singular model names, so your model should really be called OfficeAccount.)

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • Thank you for the reply. Let me check it out and reply back to you asap. – A Shukla Oct 12 '18 at 07:49
  • I am using python 2, in that case I will need to pass an argument with super() right? In this case what would be the argument? – A Shukla Oct 12 '18 at 08:06
  • The argument is always (current class, self) so `(Office_AccountsAdmin, self)`. But really you should upgrade, recent versions of Django aren't even compatible with Python 2. – Daniel Roseman Oct 12 '18 at 08:07
  • But the code that you provided to me will return the count from the present class right? whereas, I wanted the count from a different class that uses a particular field of Office_Accounts as a foreign key. In this case how will I be able to do it? – A Shukla Oct 12 '18 at 08:13
  • I don't understand your question. The code will add to each row of Office_Accounts a field containing the number of Devices that are related to it. Is that not what you want? – Daniel Roseman Oct 12 '18 at 08:34