aco
aco

Reputation: 739

Filtered list box based on another field in Django admin page

I am working on a Django website that displays information about securities on stock markets. It has a model something like this:

class Market(models.Model):
    name = models.CharField(max_length=255)

class Security(models.Model):
    name = models.CharField(max_length=255)
    market = models.ForeignKey(Market)

class SecurityGroup(models.Model):
    name = models.CharField(max_length=255)
    market = models.ForeignKey(Market)
    securities = models.ManyToManyField(Security)

The problem is that we have about 100 markets in our database, each one of which can contain 500+ securities. When you create a new SecurityGroup instance in the Django admin panel, it takes a very long time to display the list box as it can contain tens of thousands of items. What I'd like to do is something like this when a new SecurityGroup is created:

  1. User enters group name and chooses market
  2. Securities list box is filtered to only show securities from the selected market

Is this possible with Django?

Upvotes: 0

Views: 690

Answers (1)

vadimchin
vadimchin

Reputation: 1497

something like this

class AdminSecurityGroup(admin.ModelAdmin):        
    object = None
    def get_object(self, request, object_id):
       self.object = super(AdminSecurityGroup, self).get_object(request, object_id)
       return self.object

    def formfield_for_manytomany(self, db_field, request, **kwargs):
        if db_field.name.lower() == 'securities':
           if self.object and self.object.market:
              kwargs['queryset'] = Security.objects.filter(market=self.object.market)
           else:
              kwargs['queryset'] = EmptyQuerySet()
        return super(AdminSecurityGroup, self).formfield_for_manytomany(db_field, request, **kwargs)

also you need change

securities = models.ManyToManyField(Security, blank=True)

and save model in 2 steps

Upvotes: 2

Related Questions