curlyreggie
curlyreggie

Reputation: 1530

Restrictive selection in django-admin panel

I have 3 simple models in my Django project as below:

class Customer(models.Model):
      name = models.CharField(max_length=250)

class Location(models.Model):
      name = models.CharField(max_length=500)
      customer = models.ForeignKey(Customer)

class CustomerLocation(models.Model):
      name = models.CharField(max_length=250)
      customer = models.ForeignKey(Customer)
      location = models.ForeignKey(Location)

Now, I want to display the list of location(s) linked to a Customer in CustomerLocation in Admin panel.

For e.g.,

Customer = C1, Location for C1 = L1, L2.
Customer = C2, Location for C2 = L3.

If I select C1 as my Customer, I should be able choose only L1, L2 in Location. Else, it should be empty.

How can I achieve this restriction in Django-Admin?

PS: I want to achieve this via models.Admin only.

Upvotes: 1

Views: 126

Answers (1)

Anatoly Scherbakov
Anatoly Scherbakov

Reputation: 1752

There is a pluggable django app for that: https://github.com/digi604/django-smart-selects

You just add a field:

location = ChainedForeignKey(
    'Location',
    chained_field='customer',
    chained_model_field='customer',
    auto_choose=True,
    null=True,
    blank=True,
)

(Not tested, but should work.)

And in Django admin, if you change Customer, Locations list changes accordingly.


UPD. Hm, it appears that I didn't understand your question properly.

  1. What do you need Customer field in your Location model for? As far as I can see, CustomerLocation is responsible for linking these two models with one another, and every Customer may be thus linked to multiple Locations. You can achieve this with a ManyToManyField more easily, by the way.

  2. Why do you need to display customers and locations at CustomerLocation? You probably can use Django filters for that. For example:

    class CustomerLocationAdmin(admin.ModelAdmin):
        list_display = ('customer', 'location')
        list_filter = ('location', 'customer')
    
    admin.register(CustomerLocation, CustomerLocationAdmin)
    

Then, you get:

  1. A list of customers and locations
  2. Two dropdowns for customer and location. You select particular customer or a particular location to get necessary data.

Will this solution work for you?

Upvotes: 1

Related Questions