Django admin – Limit the choices in dropdown

Question:

I am starting to use Django and I have an issue trying to filter data based on user information. Let me explain how my app works. A User in my app belongs to a company. So I created a table called Company to capture company info. Then I created another table called UserCompany. Basically, it stores the Id from the Django User and the Id from my company table. Now, I want to filter data so that the user will see results filtered in the Django Admin based on their company id. He/She can only see data based on their company Id. I was able to figure this user out using get_queryset in admin.py. My only issue now is, the dropdown list that shows in admin as a result of foreign keys isn’t being filtered. I did some research and found out about limit_choices_to. I can set that statically like this:

class Cleaner(models.Model):
    company = models.ForeignKey('Company',limit_choices_to = {'companyname' = 'Test'}

The dropdown list in the admin section only shows the company Test. How can I do this dynamically? Do I do it in the model or do I do it in admin.py? Please help!

Asked By: user4432964

||

Answers:

It’s time to setup CustomAdmin for your models now. You will have to override formfield_for_foreignkey method of ModelAdmin

class CleanerAdmin(admin.ModelAdmin):
    def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
         if db_field.name == "company":
                 kwargs["queryset"] = Company.objects.filter(name='Test')
         return super(MyModelAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

admin.site.register(Cleaner, CleanerAdmin)

If there are session specific filter for which you need reference to logged in user object you also have reference to request object. You can write any logic here.

Answered By: Bipul Jain
@admin.register(Cleaner)
class CleanerAdmin(admin.ModelAdmin):
    def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
         if db_field.name == "company":
                 kwargs["queryset"] = db_field.related_model.objects.filter(name='Test')
         return super(CleanerAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
Answered By: Rezaul Karim